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

Reply via email to