Changeset: 369cbb2cf7a6 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=369cbb2cf7a6
Modified Files:
java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
java/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
java/tests/Test_PSgeneratedkeys.java
Branch: default
Log Message:
Make sure every ResultSet object (including objects of subclasses of
MonetResultSet)
always has a valid (non-null) Statement reference (as returned by
getStatement()).
This is required by JDBC API, JDBC programs depend on this behavior.
It also simplifies internal code as we no longer have to check if
getStatement() returns null.
Extended test: Test_PSgeneratedkeys.java with keys.getStatement() == null test.
diffs (233 lines):
diff --git a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
--- a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -112,6 +112,12 @@ public class MonetResultSet extends Mone
MonetConnection.ResultSetResponse header)
throws SQLException
{
+ if (statement == null) {
+ throw new IllegalArgumentException("Statement may not
be null!");
+ }
+ if (header == null) {
+ throw new IllegalArgumentException("ResultSetResponse
may not be null!");
+ }
this.statement = statement;
this.header = header;
this.type = header.getRSType();
@@ -136,6 +142,7 @@ public class MonetResultSet extends Mone
* Constructor used by MonetVirtualResultSet.
* DO NOT USE THIS CONSTRUCTOR IF YOU ARE NOT EXTENDING THIS OBJECT!
*
+ * @param statement the statement which created this ResultSet
* @param columns the column names
* @param types the column types
* @param results the number of rows in the ResultSet
@@ -143,11 +150,15 @@ public class MonetResultSet extends Mone
* @throws SQLException is a protocol error occurs
*/
MonetResultSet(
+ Statement statement,
String[] columns,
String[] types,
int results
) throws IllegalArgumentException
{
+ if (statement == null) {
+ throw new IllegalArgumentException("Statement may not
be null!");
+ }
if (columns == null || types == null) {
throw new IllegalArgumentException("One of the given
arguments is null!");
}
@@ -158,16 +169,15 @@ public class MonetResultSet extends Mone
throw new IllegalArgumentException("Negative rowcount
not allowed!");
}
+ this.statement = statement;
this.header = null;
- this.statement = null; // no parent, required for specs
+ this.fetchSize = 0;
this.columns = columns;
this.types = types;
this.tupleCount = results;
this.tlp = new TupleLineParser(columns.length);
-
- this.fetchSize = 0;
}
//== methods of interface ResultSet
@@ -992,11 +1002,7 @@ public class MonetResultSet extends Mone
*/
@Override
public int getHoldability() throws SQLException {
- // prevent NullPointerException when statement is null (i.c.
MonetVirtualResultSet)
- if (this.getStatement() != null) {
- return getStatement().getConnection().getHoldability();
- }
- return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+ return getStatement().getConnection().getHoldability();
}
/**
@@ -1251,11 +1257,8 @@ public class MonetResultSet extends Mone
String colName =
getColumnName(column);
if (colName != null &&
!"".equals(colName)) {
if (conn == null) {
- // prevent
NullPointerException when statement is null (i.c. MonetVirtualResultSet)
- if
(getStatement() != null) {
- //
first time, get a Connection object and cache it for all next columns
- conn =
getStatement().getConnection();
- }
+ // first time,
get a Connection object and cache it for all next columns
+ conn =
getStatement().getConnection();
}
if (conn != null &&
dbmd == null) {
// first time,
get a MetaData object and cache it for all next columns
@@ -1653,11 +1656,8 @@ public class MonetResultSet extends Mone
final String MonetDBtype =
getColumnTypeName(column);
Class<?> type = null;
if (conn == null) {
- // prevent NullPointerException when
statement is null (i.c. MonetVirtualResultSet)
- if (getStatement() != null) {
- // first time, get a Connection
object and cache it for all next columns
- conn =
getStatement().getConnection();
- }
+ // first time, get a Connection object
and cache it for all next columns
+ conn = getStatement().getConnection();
}
if (conn != null) {
Map<String,Class<?>> map =
conn.getTypeMap();
@@ -1897,11 +1897,6 @@ public class MonetResultSet extends Mone
default:
// When we get here the column type is a
non-standard JDBC SQL type, possibly a User Defined Type.
// Just call getObject(int, Map) for those rare
cases.
-
- /* note: statement will be null for a
MonetVirtualResultSet, such as the ones that hold generated keys */
- if (this.getStatement() == null) { //
prevent NPE
- return val;
- }
return getObject(columnIndex,
this.getStatement().getConnection().getTypeMap());
}
}
diff --git a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
--- a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
+++ b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java
@@ -718,7 +718,7 @@ public class MonetStatement extends Mone
}
try {
- return new MonetVirtualResultSet(columns, types,
results);
+ return new MonetVirtualResultSet(this, columns, types,
results);
} catch (IllegalArgumentException e) {
throw new SQLException("Internal driver error: " +
e.getMessage(), "M0M03");
}
@@ -1212,7 +1212,8 @@ public class MonetStatement extends Mone
* Special checks are programmed to prevent NullPointerExceptions, see above.
*
* As of Jun2016 this class is only used by MonetStatement.getGeneratedKeys()
- * and to resolve a javac -Xlint warning, moved to this file.
+ * Note: to resolve a javac -Xlint warning, this class definition is moved to
this file.
+ *
* TODO: try to eliminate the need for this class completely.
*/
class MonetVirtualResultSet extends MonetResultSet {
@@ -1220,11 +1221,12 @@ class MonetVirtualResultSet extends Mone
private boolean closed;
MonetVirtualResultSet(
+ Statement statement,
String[] columns,
String[] types,
String[][] results
) throws IllegalArgumentException {
- super(columns, types, results.length);
+ super(statement, columns, types, results.length);
this.results = results;
closed = false;
@@ -1281,16 +1283,4 @@ class MonetVirtualResultSet extends Mone
// types and columns are MonetResultSets private parts
}
}
-
- /**
- * Retrieves the fetch size for this ResultSet object, which will be
- * zero, since it's a virtual set.
- *
- * @return the current fetch size for this ResultSet object
- * @throws SQLException if a database access error occurs
- */
- @Override
- public int getFetchSize() throws SQLException {
- return 0;
- }
}
diff --git a/java/tests/Test_PSgeneratedkeys.java
b/java/tests/Test_PSgeneratedkeys.java
--- a/java/tests/Test_PSgeneratedkeys.java
+++ b/java/tests/Test_PSgeneratedkeys.java
@@ -12,22 +12,18 @@ public class Test_PSgeneratedkeys {
public static void main(String[] args) throws Exception {
Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");
Connection con = DriverManager.getConnection(args[0]);
- Statement stmt = con.createStatement();
- PreparedStatement pstmt;
- //ResultSet rs = null;
- //DatabaseMetaData dbmd = con.getMetaData();
-
con.setAutoCommit(false);
// >> false: auto commit was just switched off
System.out.println("0. false\t" + con.getAutoCommit());
try {
+ Statement stmt = con.createStatement();
stmt.executeUpdate(
-"CREATE TABLE psgenkey (" +
-" id serial," +
-" val varchar(20)" +
-")"
-);
+ "CREATE TABLE psgenkey (" +
+ " id serial," +
+ " val varchar(20)" +
+ ")");
+ stmt.close();
} catch (SQLException e) {
System.out.println(e);
System.out.println("Creation of test table failed! :(");
@@ -36,14 +32,12 @@ public class Test_PSgeneratedkeys {
}
try {
- pstmt = con.prepareStatement(
-"INSERT INTO psgenkey (val) VALUES ('this is a test')",
-Statement.RETURN_GENERATED_KEYS
-);
+ PreparedStatement pstmt = con.prepareStatement(
+ "INSERT INTO psgenkey (val) VALUES ('this is a
test')",
+ Statement.RETURN_GENERATED_KEYS);
+
System.out.print("1. inserting a record...");
-
pstmt.executeUpdate();
-
System.out.println("success :)");
// now get the generated keys
@@ -56,6 +50,16 @@ Statement.RETURN_GENERATED_KEYS
}
System.out.println("generated key index: " +
keys.getInt(1));
+ while (keys.next()) {
+ System.out.println("generated key index: " +
keys.getInt(1));
+ }
+
+ if (keys.getStatement() == null) {
+ System.out.println("ResultSet.getStatement()
should never return null!");
+ }
+
+ keys.close();
+ pstmt.close();
} catch (SQLException e) {
System.out.println("FAILED :( "+ e.getMessage());
System.out.println("ABORTING TEST!!!");
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list