Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 31431 invoked from network); 16 May 2007 13:05:07 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 16 May 2007 13:05:07 -0000 Received: (qmail 73666 invoked by uid 500); 16 May 2007 13:05:13 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 73642 invoked by uid 500); 16 May 2007 13:05:13 -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 73631 invoked by uid 99); 16 May 2007 13:05:13 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 May 2007 06:05:13 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 May 2007 06:05:05 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 0C7FC1A9838; Wed, 16 May 2007 06:04:45 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r538572 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/store/access/ engine/org/apache/derby/impl/sql/execute/ engine/org/apache/derby/impl/store/access/ engine/org/apache/derby/impl/store/access/btree/ engine/org/apache/derby... Date: Wed, 16 May 2007 13:04:44 -0000 To: derby-commits@db.apache.org From: dag@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070516130445.0C7FC1A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dag Date: Wed May 16 06:04:43 2007 New Revision: 538572 URL: http://svn.apache.org/viewvc?view=rev&rev=538572 Log: DERBY-2462 Committed DERBY-2462-4, which fixes this issue and improves the test. Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/DiskHashtable.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/ScanController.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/HashScanResultSet.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/BackingStoreHashTableFromScan.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeScan.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericScanController.java db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/NoOpTransaction.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SpillHash.out db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SpillHash.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_QualifierTest.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/DiskHashtable.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/DiskHashtable.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/DiskHashtable.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/DiskHashtable.java Wed May 16 06:04:43 2007 @@ -24,6 +24,7 @@ import java.util.NoSuchElementException; import java.util.Properties; import java.util.Vector; +import org.apache.derby.shared.common.reference.SQLState; import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.types.DataValueDescriptor; import org.apache.derby.iapi.types.SQLInteger; @@ -63,6 +64,7 @@ private final DataValueDescriptor[] scanKey = { new SQLInteger()}; private int size; private boolean keepStatistics; + private final boolean keepAfterCommit; /** * Creates a new DiskHashtable instance. @@ -88,6 +90,7 @@ this.tc = tc; this.key_column_numbers = key_column_numbers; this.remove_duplicates = remove_duplicates; + this.keepAfterCommit = keepAfterCommit; LanguageConnectionContext lcc = (LanguageConnectionContext) ContextService.getContextOrNull( LanguageConnectionContext.CONTEXT_ID); @@ -387,13 +390,14 @@ { private ScanController scan; private boolean hasMore; + private RowLocation rowloc; ElementEnum() { try { scan = tc.openScan( rowConglomerateId, - false, // do not hold + keepAfterCommit, 0, // read only TransactionController.MODE_TABLE, TransactionController.ISOLATION_NOLOCK, @@ -408,6 +412,9 @@ { scan.close(); scan = null; + } else if (keepAfterCommit) { + rowloc = rowConglomerate.newRowLocationTemplate(); + scan.fetchLocation(rowloc); } } catch( StandardException se) @@ -436,13 +443,27 @@ throw new NoSuchElementException(); try { - scan.fetch( row); + if (scan.isHeldAfterCommit()) { + // automatically reopens scan: + if (!scan.positionAtRowLocation(rowloc)) { + // Will not happen unless compress of this table + // has invalidated the row location. Possible? + throw StandardException. + newException(SQLState.NO_CURRENT_ROW); + } + } + + scan.fetch(row); + Object retValue = BackingStoreHashtable.shallowCloneRow( row); hasMore = scan.next(); + if( ! hasMore) { scan.close(); scan = null; + } else if (keepAfterCommit) { + scan.fetchLocation(rowloc); } return retValue; Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/ScanController.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/ScanController.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/ScanController.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/ScanController.java Wed May 16 06:04:43 2007 @@ -167,6 +167,18 @@ boolean doesCurrentPositionQualify() throws StandardException; + + /** + * Return true is the scan has been closed after a commit, but was + * opened with holdability and can be reopened using + * positionAtRowLocation. + * + * @exception StandardException Standard exception policy. + * + * @see ScanController#positionAtRowLocation + */ + boolean isHeldAfterCommit() throws StandardException; + /** Fetch the (partial) row at the current position of the Scan. The value in the destRow storable row is replaced Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/access/TransactionController.java Wed May 16 06:04:43 2007 @@ -901,6 +901,8 @@ * BackingStoreHashtable.getRuntimeStats(). * @param skipNullKeyColumns Whether or not to skip rows with 1 or more null key columns * + * @param keepAfterCommit If true then the hash table is kept after a + * commit * @see BackingStoreHashtable * @see TransactionController#openScan * @@ -925,7 +927,8 @@ int initialCapacity, float loadFactor, boolean collect_runtimestats, - boolean skipNullKeyColumns) + boolean skipNullKeyColumns, + boolean keepAfterCommit) throws StandardException; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/HashScanResultSet.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/HashScanResultSet.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/HashScanResultSet.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/HashScanResultSet.java Wed May 16 06:04:43 2007 @@ -104,6 +104,7 @@ public int[] keyColumns; private boolean sameStartStopPosition; private boolean skipNullKeyColumns; + private boolean keepAfterCommit; protected BackingStoreHashtable hashtable; protected boolean eliminateDuplicates; // set to true in DistinctScanResultSet @@ -187,6 +188,7 @@ this.isConstraint = isConstraint; this.forUpdate = forUpdate; this.skipNullKeyColumns = skipNullKeyColumns; + this.keepAfterCommit = activation.getResultSetHoldability(); /* Retrieve the hash key columns */ FormatableArrayHolder fah = (FormatableArrayHolder) @@ -296,7 +298,8 @@ initialCapacity, // in memory Hashtable initial capacity loadFactor, // in memory Hashtable load factor runTimeStatisticsOn, - skipNullKeyColumns); + skipNullKeyColumns, + keepAfterCommit); if (runTimeStatisticsOn) Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/BackingStoreHashTableFromScan.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/BackingStoreHashTableFromScan.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/BackingStoreHashTableFromScan.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/BackingStoreHashTableFromScan.java Wed May 16 06:04:43 2007 @@ -83,7 +83,8 @@ int initialCapacity, float loadFactor, boolean collect_runtimestats, - boolean skipNullKeyColumns) + boolean skipNullKeyColumns, + boolean keepAfterCommit) throws StandardException { @@ -97,7 +98,7 @@ initialCapacity, loadFactor, skipNullKeyColumns, - false /* Do not keep the hash table after a commit. */); + keepAfterCommit); open_scan = (ScanManager) tc.openScan( Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/RAMTransaction.java Wed May 16 06:04:43 2007 @@ -1367,7 +1367,8 @@ int initialCapacity, float loadFactor, boolean collect_runtimestats, - boolean skipNullKeyColumns) + boolean skipNullKeyColumns, + boolean keepAfterCommit) throws StandardException { return ( @@ -1391,7 +1392,8 @@ initialCapacity, loadFactor, collect_runtimestats, - skipNullKeyColumns)); + skipNullKeyColumns, + keepAfterCommit)); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeScan.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeScan.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeScan.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeScan.java Wed May 16 06:04:43 2007 @@ -1590,6 +1590,15 @@ } /** + * @see org.apache.derby.iapi.store.access.ScanController#isHeldAfterCommit + */ + public boolean isHeldAfterCommit() throws StandardException + { + return (scan_state == SCAN_HOLD_INIT || + scan_state == SCAN_HOLD_INPROGRESS); + } + + /** Fetch the row at the current position of the Scan. @see ScanController#fetch Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericScanController.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericScanController.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericScanController.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/conglomerate/GenericScanController.java Wed May 16 06:04:43 2007 @@ -65,8 +65,9 @@ extended to provide more information if necessary. -scan_state - a scan has 3 possible states: - SCAN_INIT, SCAN_INPROGRESS, SCAN_DONE +scan_state - a scan has 5 possible states: + SCAN_INIT, SCAN_INPROGRESS, SCAN_DONE, SCAN_HOLD_INIT, and + SCAN_HOLD_INPROGRESS positionAtInitScan() - This routine is called to move the scan to the SCAN_INIT state. @@ -1453,6 +1454,17 @@ { fetch(row, false); } + + /** + * @see org.apache.derby.iapi.store.access.ScanController#isHeldAfterCommit + */ + public boolean isHeldAfterCommit() throws StandardException + { + return (scan_state == SCAN_HOLD_INIT || + scan_state == SCAN_HOLD_INPROGRESS); + } + + /** Fetch the row at the current position of the Scan. Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/Scan.java Wed May 16 06:04:43 2007 @@ -386,4 +386,14 @@ return(prop); } + + /** + * @see org.apache.derby.iapi.store.access.ScanController#isHeldAfterCommit + */ + public boolean isHeldAfterCommit() throws StandardException + { + throw StandardException.newException( + SQLState.SORT_IMPROPER_SCAN_METHOD); + } + } Modified: db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/NoOpTransaction.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/NoOpTransaction.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/NoOpTransaction.java (original) +++ db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/NoOpTransaction.java Wed May 16 06:04:43 2007 @@ -152,7 +152,8 @@ int stopSearchOperator, long max_rowcnt, int[] key_column_numbers, boolean remove_duplicates, long estimated_rowcnt, long max_inmemory_rowcnt, int initialCapacity, float loadFactor, - boolean collect_runtimestats, boolean skipNullKeyColumns) + boolean collect_runtimestats, boolean skipNullKeyColumns, + boolean keepAfterCommit) throws StandardException { // TODO Auto-generated method stub return null; Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SpillHash.out URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SpillHash.out?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SpillHash.out (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SpillHash.out Wed May 16 06:04:43 2007 @@ -1,8 +1,20 @@ -Running join -Running distinct -Running scroll insensitive cursor +Running join, holdability=false positive +Running join, holdability=false negative +Running join, holdability=true positive +Running distinct, holdability=false positive +Running distinct, holdability=false negative +Running distinct, holdability=true positive +Running scroll insensitive cursor, holdability=false positive +Running scroll insensitive cursor, holdability=false negative +Running scroll insensitive cursor, holdability=true positive Growing database. -Running join -Running distinct -Running scroll insensitive cursor +Running join, holdability=false positive +Running join, holdability=false negative +Running join, holdability=true positive +Running distinct, holdability=false positive +Running distinct, holdability=false negative +Running distinct, holdability=true positive +Running scroll insensitive cursor, holdability=false positive +Running scroll insensitive cursor, holdability=false negative +Running scroll insensitive cursor, holdability=true positive PASSED. Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SpillHash.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SpillHash.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SpillHash.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SpillHash.java Wed May 16 06:04:43 2007 @@ -1,6 +1,6 @@ /* - Derby - Class org.apache.derbyTesting.functionTests.tests.lang.bug4356 + Derby - Class org.apache.derbyTesting.functionTests.tests.lang.SpillHash Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -33,6 +33,7 @@ import org.apache.derby.tools.ij; import org.apache.derby.tools.JDBCDisplayUtil; +import org.apache.derbyTesting.functionTests.util.SQLStateConstants; /** * Test BackingStoreHashtable spilling to disk. @@ -41,8 +42,6 @@ */ public class SpillHash { - private static PreparedStatement joinStmt; - private static PreparedStatement distinctStmt; private static final int LOTS_OF_ROWS = 10000; private static int errorCount = 0; @@ -62,11 +61,6 @@ PreparedStatement insB = conn.prepareStatement( "insert into tb(cb1,cb2) values(?,?)"); insertDups( insA, insB, initDupVals); - joinStmt = - conn.prepareStatement( "select ta.ca1, ta.ca2, tb.cb2 from ta, tb where ca1 = cb1"); - distinctStmt = - conn.prepareStatement( "select distinct ca1 from ta"); - runStatements( conn, 0, new String[][][] {initDupVals}); System.out.println( "Growing database."); @@ -102,12 +96,10 @@ if( errorCount == 0) { System.out.println( "PASSED."); - System.exit(0); } else { System.out.println( "FAILED: " + errorCount + ((errorCount == 1) ? " error" : " errors")); - System.exit(1); } } // end of main @@ -171,20 +163,49 @@ return "B" + col1Val; } + static final boolean NEGATIVE_TEST = false; + static final boolean POSITIVE_TEST = true; + private static void runStatements( Connection conn, int maxColValue, String[][][] dupVals) throws SQLException { - runJoin( conn, maxColValue, dupVals); - runDistinct( conn, maxColValue, dupVals); - runCursor( conn, maxColValue, dupVals); + // run variants with holdability false and true (last arg) + runJoin( conn, maxColValue, dupVals, false, POSITIVE_TEST); + runJoin( conn, maxColValue, dupVals, false, NEGATIVE_TEST); + runJoin( conn, maxColValue, dupVals, true, POSITIVE_TEST); + + runDistinct( conn, maxColValue, dupVals, false, POSITIVE_TEST); + runDistinct( conn, maxColValue, dupVals, false, NEGATIVE_TEST); + runDistinct( conn, maxColValue, dupVals, true, POSITIVE_TEST); + + runCursor( conn, maxColValue, dupVals, false, POSITIVE_TEST); + runCursor( conn, maxColValue, dupVals, false, NEGATIVE_TEST); + runCursor( conn, maxColValue, dupVals, true, POSITIVE_TEST); } - private static void runJoin( Connection conn, int maxColValue, String[][][] dupVals) + private static void runJoin( Connection conn, + int maxColValue, + String[][][] dupVals, + boolean holdOverCommit, + boolean positiveTest) throws SQLException { - System.out.println( "Running join"); + System.out.println( "Running join, holdability=" + holdOverCommit + + " " + (positiveTest ? "positive" : "negative")); int expectedRowCount = maxColValue; // plus expected duplicates, to be counted below - ResultSet rs = joinStmt.executeQuery(); + + Statement stmt; + if( holdOverCommit) { + stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY, + ResultSet.HOLD_CURSORS_OVER_COMMIT); + } else { + stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY, + ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + ResultSet rs = stmt.executeQuery( + "select ta.ca1, ta.ca2, tb.cb2 from ta, tb where ca1 = cb1"); BitSet joinRowFound = new BitSet( maxColValue); int dupKeyCount = 0; for( int i = 0; i < dupVals.length; i++) @@ -255,6 +276,35 @@ } dupsFound[dupKeyIdx].set( idx); } + + if (holdOverCommit) { + // Commit inside an open result set to test + // rs' holdability, next() will reopen it if all is well. + rs.getStatement().getConnection().commit(); + holdOverCommit = false; // hack: do this only once + } else if (!positiveTest) { + // Negative test, check if we get the expected error. + rs.getStatement().getConnection().commit(); + + try { + rs.next(); + } catch (SQLException e) { + if (!e.getSQLState(). + equals(SQLStateConstants.RESULT_SET_IS_CLOSED)) { + System.out.println("Running join, holdability=false " + + "negative test: Failed " + + e.getSQLState()); + rs.close(); + } + stmt.close(); + return; + } + System.out.println("Running join, holdability=false " + + "negative test: Failed: rs not closed"); + rs.close(); + stmt.close(); + return; + } }; if( count != expectedRowCount) { @@ -262,6 +312,7 @@ errorCount++; } rs.close(); + stmt.close(); } // end of runJoin private static int findDupVal( ResultSet rs, int col, char prefix, int keyIdx, String[][][] dupVals) @@ -296,17 +347,36 @@ return str.trim(); } - private static void runDistinct( Connection conn, int maxColValue, String[][][] dupVals) + private static void runDistinct( Connection conn, + int maxColValue, + String[][][] dupVals, + boolean holdOverCommit, + boolean positiveTest) throws SQLException { - System.out.println( "Running distinct"); - ResultSet rs = distinctStmt.executeQuery(); - checkAllCa1( rs, false, false, maxColValue, dupVals, "DISTINCT"); + System.out.println( "Running distinct, holdability=" + holdOverCommit + + " " + (positiveTest ? "positive" : "negative")); + Statement stmt; + if( holdOverCommit) { + stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY, + ResultSet.HOLD_CURSORS_OVER_COMMIT); + } else { + stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY, + ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + ResultSet rs = stmt.executeQuery("select distinct ca1 from ta"); + checkAllCa1( rs, false, holdOverCommit, positiveTest, + maxColValue, dupVals, "DISTINCT"); + rs.close(); + stmt.close(); } private static void checkAllCa1( ResultSet rs, boolean expectDups, boolean holdOverCommit, + boolean positiveTest, int maxColValue, String[][][] dupVals, String label) @@ -391,10 +461,36 @@ found.set( col1Val); count++; } - if( holdOverCommit) - { + + if( holdOverCommit) { + // Commit inside an open result set to test + // rs' holdability, next() will reopen it if all is well. rs.getStatement().getConnection().commit(); holdOverCommit = false; + } else if (!positiveTest) { + // Negative test, check if we get the expected error. + rs.getStatement().getConnection().commit(); + + String runningWhat = + (expectDups ? + "Running scroll insensitive cursor, " + + "holdability=false" : + "Running distinct, holdability=false"); + + try { + rs.next(); + } catch (SQLException e) { + if (!e.getSQLState().equals + (SQLStateConstants.RESULT_SET_IS_CLOSED)) { + System.out.println(runningWhat + + " negative test: Failed " + + e.getSQLState()); + } + return; + } + System.out.println(runningWhat + + " negative test: Failed: rs not closed"); + return; } } if( count != maxColValue) @@ -418,12 +514,16 @@ } } // End of checkAllCa1 - private static void runCursor( Connection conn, int maxColValue, String[][][] dupVals) + private static void runCursor( Connection conn, + int maxColValue, + String[][][] dupVals, + boolean holdOverCommit, + boolean positiveTest) throws SQLException { - System.out.println( "Running scroll insensitive cursor"); - DatabaseMetaData dmd = conn.getMetaData(); - boolean holdOverCommit = dmd.supportsOpenCursorsAcrossCommit(); + System.out.println( "Running scroll insensitive cursor, holdability=" + + holdOverCommit + + " " + (positiveTest ? "positive" : "negative")); Statement stmt; if( holdOverCommit) stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, @@ -431,8 +531,10 @@ ResultSet.HOLD_CURSORS_OVER_COMMIT); else stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_READ_ONLY); + ResultSet.CONCUR_READ_ONLY, + ResultSet.CLOSE_CURSORS_AT_COMMIT); ResultSet rs = stmt.executeQuery( "SELECT ca1 FROM ta"); - checkAllCa1( rs, true, holdOverCommit, maxColValue, dupVals, "scroll insensitive cursor"); + checkAllCa1( rs, true, holdOverCommit, positiveTest, + maxColValue, dupVals, "scroll insensitive cursor"); } } Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_QualifierTest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_QualifierTest.java?view=diff&rev=538572&r1=538571&r2=538572 ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_QualifierTest.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_QualifierTest.java Wed May 16 06:04:43 2007 @@ -1015,8 +1015,9 @@ -1, // put it all into memory -1, // use default initial capacity -1, // use default load factor - false, // don't maintain runtime statistics - false); // don't skip null key columns + false, // don't maintain runtime statistics + false, // don't skip null key columns + false); // don't keep after commit // make sure the expected result set is the same as the actual result // set. @@ -1104,8 +1105,8 @@ -1, // use default initial capacity -1, // use default load factor false, // don't maintain runtime statistics - false); // don't skip null key columns - + false, // don't skip null key columns + false); // don't keep after commit Object removed_obj; for (numrows = 0; numrows < expect_numrows; numrows++)