You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by kr...@apache.org on 2011/05/30 14:08:34 UTC

svn commit: r1129138 - in /db/derby/code/branches/10.8: ./ java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java

Author: kristwaa
Date: Mon May 30 12:08:34 2011
New Revision: 1129138

URL: http://svn.apache.org/viewvc?rev=1129138&view=rev
Log:
DERBY-4843: Consult isPoolable hint before caching prepared statement

Merged test addition from trunk (r1129136).

Modified:
    db/derby/code/branches/10.8/   (props changed)
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java

Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon May 30 12:08:34 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7:1061570,1061578,1082235
-/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1102826,1103681,1103718,1127825
+/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1102826,1103681,1103718,1127825,1129136

Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java?rev=1129138&r1=1129137&r2=1129138&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java Mon May 30 12:08:34 2011
@@ -24,14 +24,13 @@ package org.apache.derbyTesting.function
 import junit.framework.*;
 
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
-import org.apache.derbyTesting.junit.BaseJDBCTestSetup;
 import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.junit.JDBC;
 import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetStream;
 import org.apache.derbyTesting.junit.TestConfiguration;
 
 import java.io.*;
 import java.sql.*;
-import javax.sql.*;
 
 import org.apache.derby.iapi.services.io.DerbyIOException;
 import org.apache.derby.impl.jdbc.EmbedSQLException;
@@ -172,6 +171,10 @@ public class PreparedStatementTest exten
         suite.addTest(TestConfiguration.clientServerDecorator(
             baseSuite("PreparedStatementTest:client")));
 
+        // Tests for the client side JDBC statement cache.
+        suite.addTest(TestConfiguration.clientServerDecorator(
+                statementCachingSuite()));
+
         suite.addTest(
                 TestConfiguration.clientServerDecorator(
                 TestConfiguration.connectionXADecorator(
@@ -197,6 +200,28 @@ public class PreparedStatementTest exten
             };
     }
     
+    /**
+     * Returns a suite for tests that need JDBC statement caching to be enabled.
+     */
+    private static Test statementCachingSuite() {
+        TestSuite suite = new TestSuite("JDBC statement caching suite");
+        suite.addTest(new PreparedStatementTest("cpTestIsPoolableHintFalse"));
+        suite.addTest(new PreparedStatementTest("cpTestIsPoolableHintTrue"));
+        return TestConfiguration.connectionCPDecorator(
+            new CleanDatabaseTestSetup(suite) {
+
+            protected void decorateSQL(Statement stmt)
+                    throws SQLException {
+                stmt.execute("create table " + BLOBTBL +
+                        " (sno int, dBlob BLOB(1M))");
+                stmt.execute("create table " + CLOBTBL +
+                        " (sno int, dClob CLOB(1M))");
+                stmt.execute("create table " + LONGVARCHAR  +
+                        " (sno int, dLongVarchar LONG VARCHAR)");
+                 }
+            });
+    }
+
     //--------------------------------------------------------------------------
     //BEGIN THE TEST OF THE METHODS THAT THROW AN UNIMPLEMENTED EXCEPTION IN
     //THIS CLASS
@@ -603,13 +628,79 @@ public class PreparedStatementTest exten
      * @throws SQLException
      *
      */
-    
-    public void testIsPoolable() throws SQLException {
+    public void testIsPoolableDefault() throws SQLException {
         // By default a prepared statement is poolable
         assertTrue("Expected a poolable statement", ps.isPoolable());
     }
 
     /**
+     * Tests that the {@code isPoolable}-hint works by exploiting the fact that
+     * the client cannot prepare a statement referring to a deleted table
+     * (unless the statement is already in the statement cache).
+     *
+     * @throws SQLException if something goes wrong...
+     */
+    public void cpTestIsPoolableHintFalse()
+            throws SQLException {
+        getConnection().setAutoCommit(false);
+        // Create a table, insert a row, then create a statement selecting it.
+        Statement stmt = createStatement();
+        stmt.executeUpdate("create table testispoolablehint (id int)");
+        stmt.executeUpdate("insert into testispoolablehint values 1");
+        PreparedStatement ps = prepareStatement(
+                "select * from testispoolablehint");
+        ps.setPoolable(false);
+        JDBC.assertSingleValueResultSet(ps.executeQuery(), "1");
+        // Close statement, which should be discarded.
+        ps.close();
+        // Now delete the table.
+        stmt.executeUpdate("drop table testispoolablehint");
+        stmt.close();
+        // Since there is no cached statement, we'll get exception here.
+        try {
+            ps = prepareStatement("select * from testispoolablehint");
+            fail("Prepared statement not valid, referring non-existing table");
+        } catch (SQLException sqle) {
+            assertSQLState("42X05", sqle);
+        }
+    }
+
+    /**
+     * Tests that the {@code isPoolable}-hint works by exploiting the fact that
+     * the client can prepare a statement referring to a deleted table if JDBC
+     * statement caching is enabled and the statement is already in the cache.
+     *
+     * @throws SQLException if something goes wrong...
+     */
+    public void cpTestIsPoolableHintTrue()
+            throws SQLException {
+        getConnection().setAutoCommit(false);
+        // Create a table, insert a row, then create a statement selecting it.
+        Statement stmt = createStatement();
+        stmt.executeUpdate("create table testispoolablehint (id int)");
+        stmt.executeUpdate("insert into testispoolablehint values 1");
+        PreparedStatement ps = prepareStatement(
+                "select * from testispoolablehint");
+        ps.setPoolable(true);
+        JDBC.assertSingleValueResultSet(ps.executeQuery(), "1");
+        // Put the statement into the cache.
+        ps.close();
+        // Now delete the table and fetch the cached prepared statement.
+        stmt.executeUpdate("drop table testispoolablehint");
+        stmt.close();
+        ps = prepareStatement("select * from testispoolablehint");
+        // If we get this far, there is a big change we have fetched an
+        // invalid statement from the cache, but we won't get the exception
+        // until we try to execute it.
+        try {
+            ps.executeQuery();
+            fail("Prepared statement not valid, referring non-existing table");
+        } catch (SQLException sqle) {
+            assertSQLState("42X05", sqle);
+        }
+    }
+
+    /**
      *
      * Tests the PreparedStatement interface method isPoolable on closed
      * PreparedStatement