Skip to content

Commit

Permalink
[CONJ-809] resultset metadata implementation correction for isReadOnl…
Browse files Browse the repository at this point in the history
…y/isWritable/isDefinitelyWritable
  • Loading branch information
rusher committed Jul 22, 2020
1 parent 426d829 commit ca79fb3
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 134 deletions.
19 changes: 7 additions & 12 deletions src/main/java/org/mariadb/jdbc/MariaDbResultSetMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,19 @@ public class MariaDbResultSetMetaData implements ResultSetMetaData {
private final ColumnDefinition[] fieldPackets;
private final Options options;
private final boolean forceAlias;
private final boolean updatable;

/**
* Constructor.
*
* @param fieldPackets column informations
* @param options connection options
* @param forceAlias force table and column name alias as original data
* @param updatable is column updatable
*/
public MariaDbResultSetMetaData(
final ColumnDefinition[] fieldPackets,
final Options options,
final boolean forceAlias,
final boolean updatable) {
final ColumnDefinition[] fieldPackets, final Options options, final boolean forceAlias) {
this.fieldPackets = fieldPackets;
this.options = options;
this.forceAlias = forceAlias;
this.updatable = updatable;
}

/**
Expand Down Expand Up @@ -312,10 +306,9 @@ public String getColumnTypeName(final int column) throws SQLException {
* @throws SQLException if a database access error occurs or in case of wrong index
*/
public boolean isReadOnly(final int column) throws SQLException {
if (column >= 1 && column <= fieldPackets.length) {
return !updatable;
}
throw ExceptionFactory.INSTANCE.create(String.format("no column with index %s", column));
ColumnDefinition ci = getColumnInformation(column);
return (ci.getOriginalTable() == null || ci.getOriginalTable().isEmpty())
&& (ci.getOriginalName() == null || ci.getOriginalName().isEmpty());
}

/**
Expand Down Expand Up @@ -362,7 +355,9 @@ private ColumnDefinition getColumnInformation(int column) throws SQLException {
if (column >= 1 && column <= fieldPackets.length) {
return fieldPackets[column - 1];
}
throw ExceptionFactory.INSTANCE.create("No such column");
throw ExceptionFactory.INSTANCE.create(
String.format(
"wrong column index %s. must be in [1, %s] range", column, fieldPackets.length));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private void setMetaFromResult() {
parameterCount = serverPrepareResult.getParameters().length;
metadata =
new MariaDbResultSetMetaData(
serverPrepareResult.getColumns(), protocol.getUrlParser().getOptions(), false, false);
serverPrepareResult.getColumns(), protocol.getUrlParser().getOptions(), false);
parameterMetaData = new MariaDbParameterMetaData(serverPrepareResult.getParameters());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ public String getCursorName() throws SQLException {

/** {inheritDoc}. */
public ResultSetMetaData getMetaData() {
return new MariaDbResultSetMetaData(columnsInformation, options, forceAlias, false);
return new MariaDbResultSetMetaData(columnsInformation, options, forceAlias);
}

/** {inheritDoc}. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,6 @@ private void checkIfUpdatable(Results results) throws SQLException {
}
}

@Override
public ResultSetMetaData getMetaData() {
return new MariaDbResultSetMetaData(columnsInformation, options, false, canBeUpdate);
}

private UpdatableColumnDefinition[] getUpdatableColumns() {
return (UpdatableColumnDefinition[]) columnsInformation;
}
Expand Down
41 changes: 23 additions & 18 deletions src/test/java/org/mariadb/jdbc/ResultSetMetaDataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,41 +70,46 @@ public void metaDataTest() throws SQLException {
assertEquals("unikey_col", rsmd.getColumnName(3));
assertEquals(Types.CHAR, rsmd.getColumnType(4));
assertEquals(Types.SMALLINT, rsmd.getColumnType(5));
assertTrue(rsmd.isReadOnly(1));
assertTrue(rsmd.isReadOnly(2));
assertTrue(rsmd.isReadOnly(3));
assertTrue(rsmd.isReadOnly(4));
assertTrue(rsmd.isReadOnly(5));
assertFalse(rsmd.isWritable(1));
assertFalse(rsmd.isWritable(2));
assertFalse(rsmd.isWritable(3));
assertFalse(rsmd.isWritable(4));
assertFalse(rsmd.isWritable(5));
assertFalse(rsmd.isDefinitelyWritable(1));
assertFalse(rsmd.isDefinitelyWritable(2));
assertFalse(rsmd.isDefinitelyWritable(3));
assertFalse(rsmd.isDefinitelyWritable(4));
assertFalse(rsmd.isDefinitelyWritable(5));
assertFalse(rsmd.isReadOnly(1));
assertFalse(rsmd.isReadOnly(2));
assertFalse(rsmd.isReadOnly(3));
assertFalse(rsmd.isReadOnly(4));
assertFalse(rsmd.isReadOnly(5));
assertTrue(rsmd.isWritable(1));
assertTrue(rsmd.isWritable(2));
assertTrue(rsmd.isWritable(3));
assertTrue(rsmd.isWritable(4));
assertTrue(rsmd.isWritable(5));
assertTrue(rsmd.isDefinitelyWritable(1));
assertTrue(rsmd.isDefinitelyWritable(2));
assertTrue(rsmd.isDefinitelyWritable(3));
assertTrue(rsmd.isDefinitelyWritable(4));
assertTrue(rsmd.isDefinitelyWritable(5));

try {
rsmd.isReadOnly(6);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 6"));
assertTrue(sqle.getMessage().contains("wrong column index 6. must be in [1, 5] range"));
}
try {
rsmd.isWritable(6);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 6"));
assertTrue(sqle.getMessage().contains("wrong column index 6. must be in [1, 5] range"));
}
try {
rsmd.isDefinitelyWritable(6);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 6"));
assertTrue(sqle.getMessage().contains("wrong column index 6. must be in [1, 5] range"));
}

rs = stmt.executeQuery("select count(char_col) from test_rsmd");
assertTrue(rs.next());
rsmd = rs.getMetaData();
assertTrue(rsmd.isReadOnly(1));

DatabaseMetaData md = sharedConnection.getMetaData();
ResultSet cols = md.getColumns(null, null, "test\\_rsmd", null);
cols.next();
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/mariadb/jdbc/ResultSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ public void columnNamesMappingError() throws SQLException {
Statement stmt = sharedConnection.createStatement();
stmt.executeUpdate("INSERT INTO columnNamesMappingError VALUES (4)");
try (PreparedStatement preparedStatement =
sharedConnection.prepareStatement(
sharedConnection.prepareStatement(
"SELECT * FROM " + "columnNamesMappingError",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE)) {
Expand Down
107 changes: 11 additions & 96 deletions src/test/java/org/mariadb/jdbc/UpdateResultSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public void testMultipleDatabase() throws Exception {
}

@Test
public void testUpdateWithoutPrimary() throws Exception {
public void testMeta() throws Exception {
createTable(
"UpdateWithoutPrimary",
"`id` INT NOT NULL AUTO_INCREMENT,"
Expand Down Expand Up @@ -265,126 +265,41 @@ public void testUpdateWithoutPrimary() throws Exception {
"ResultSet cannot be updated. "
+ "Primary key field `id` is not in result-set"));
}
ResultSetMetaData rsmd = rs.getMetaData();
assertTrue(rsmd.isReadOnly(1));
assertTrue(rsmd.isReadOnly(2));
assertFalse(rsmd.isWritable(1));
assertFalse(rsmd.isWritable(2));
assertFalse(rsmd.isDefinitelyWritable(1));
assertFalse(rsmd.isDefinitelyWritable(2));

try {
rsmd.isReadOnly(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 3"));
}
try {
rsmd.isWritable(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 3"));
}
try {
rsmd.isDefinitelyWritable(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 3"));
}
}
int[] autoInc = setAutoInc();
ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM UpdateWithoutPrimary");
assertTrue(rs.next());
assertEquals(autoInc[1] + autoInc[0], rs.getInt(1));
assertEquals("1-1", rs.getString(2));
assertEquals("1-2", rs.getString(3));

assertFalse(rs.next());
}

@Test
public void testUpdateWithPrimary() throws Exception {
createTable(
"testUpdateWithPrimary",
"`id` INT NOT NULL AUTO_INCREMENT,"
+ "`t1` VARCHAR(50) NOT NULL,"
+ "`t2` VARCHAR(50) NULL default 'default-value',"
+ "PRIMARY KEY (`id`)",
"DEFAULT CHARSET=utf8");

Statement stmt = sharedConnection.createStatement();
stmt.executeQuery(
"INSERT INTO testUpdateWithPrimary(t1,t2) values ('1-1','1-2'),('2-1','2-2')");

String utf8escapeQuote = "你好 '' \" \\";

try (PreparedStatement preparedStatement =
sharedConnection.prepareStatement(
"SELECT id, t1, t2 FROM testUpdateWithPrimary",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE)) {
ResultSet rs = preparedStatement.executeQuery();

rs.moveToInsertRow();
rs.updateInt(1, -1);
rs.updateString(2, "0-1");
rs.updateString(3, "0-2");
rs.insertRow();

assertTrue(rs.next());
assertTrue(rs.next());
rs.updateString(2, utf8escapeQuote);
rs.updateRow();

ResultSetMetaData rsmd = rs.getMetaData();
assertFalse(rsmd.isReadOnly(1));
assertFalse(rsmd.isReadOnly(2));
assertFalse(rsmd.isReadOnly(3));
assertTrue(rsmd.isWritable(1));
assertTrue(rsmd.isWritable(2));
assertTrue(rsmd.isWritable(3));
assertTrue(rsmd.isDefinitelyWritable(1));
assertTrue(rsmd.isDefinitelyWritable(2));
assertTrue(rsmd.isDefinitelyWritable(3));

try {
rsmd.isReadOnly(4);
rsmd.isReadOnly(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 4"));
System.out.println(sqle.getMessage());
assertTrue(sqle.getMessage().contains("wrong column index 3. must be in [1, 2] range"));
}
try {
rsmd.isWritable(4);
rsmd.isWritable(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 4"));
assertTrue(sqle.getMessage().contains("wrong column index 3. must be in [1, 2] range"));
}
try {
rsmd.isDefinitelyWritable(4);
rsmd.isDefinitelyWritable(3);
fail("must have throw exception");
} catch (SQLException sqle) {
assertTrue(sqle.getMessage().contains("no column with index 4"));
assertTrue(sqle.getMessage().contains("wrong column index 3. must be in [1, 2] range"));
}
}

final int[] autoInc = setAutoInc();

ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM testUpdateWithPrimary");
assertTrue(rs.next());
assertEquals(-1, rs.getInt(1));
assertEquals("0-1", rs.getString(2));
assertEquals("0-2", rs.getString(3));

int[] autoInc = setAutoInc();
ResultSet rs = stmt.executeQuery("SELECT id, t1, t2 FROM UpdateWithoutPrimary");
assertTrue(rs.next());
assertEquals(autoInc[0] + autoInc[1], rs.getInt(1));
assertEquals(autoInc[1] + autoInc[0], rs.getInt(1));
assertEquals("1-1", rs.getString(2));
assertEquals("1-2", rs.getString(3));

assertTrue(rs.next());
assertEquals(2 * autoInc[0] + autoInc[1], rs.getInt(1));
assertEquals(utf8escapeQuote, rs.getString(2));
assertEquals("2-2", rs.getString(3));

assertFalse(rs.next());
}

Expand Down

0 comments on commit ca79fb3

Please sign in to comment.