Author: kristwaa
Date: Mon May 30 12:15:48 2011
New Revision: 1129140
URL: http://svn.apache.org/viewvc?rev=1129140&view=rev
Log:
DERBY-4843: Consult isPoolable hint before caching prepared statement
Merged test addition from trunk (r1129136).
Modified:
db/derby/code/branches/10.7/ (props changed)
db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java
Propchange: db/derby/code/branches/10.7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon May 30 12:15:48 2011
@@ -1 +1 @@
-/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169,1059888,1060480,1062096,1063809,1065061,1066290,1067250,1067357,1069661,1071463,1071886,1076387,1078461,1078693,1081455,1085078,1091000,1097247,1103681,1103718
+/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169,1059888,1060480,1062096,1063809,1065061,1066290,1067250,1067357,1069661,1071463,1071886,1076387,1078461,1078693,1081455,1085078,1091000,1097247,1103681,1103718,1129136
Modified: db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java?rev=1129140&r1=1129139&r2=1129140&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java
(original)
+++ db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java
Mon May 30 12:15:48 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
|