Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B72F66D48 for ; Mon, 30 May 2011 12:08:56 +0000 (UTC) Received: (qmail 1159 invoked by uid 500); 30 May 2011 12:08:56 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 1140 invoked by uid 500); 30 May 2011 12:08:56 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 1133 invoked by uid 99); 30 May 2011 12:08:56 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 May 2011 12:08:56 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 May 2011 12:08:55 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id F016F2388897; Mon, 30 May 2011 12:08:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1129138 - in /db/derby/code/branches/10.8: ./ java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest.java Date: Mon, 30 May 2011 12:08:34 -0000 To: derby-commits@db.apache.org From: kristwaa@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110530120834.F016F2388897@eris.apache.org> 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