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 ka...@apache.org on 2007/05/11 10:37:04 UTC

svn commit: r537128 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/

Author: kahatlen
Date: Fri May 11 01:37:02 2007
New Revision: 537128

URL: http://svn.apache.org/viewvc?view=rev&rev=537128
Log:
DERBY-2597: Language result sets should not reuse current isolation
level across executions

1) Move the static method UpdateResultSet.decodeLockMode() into
DMLWriteResultSet and make it non-static. This makes it possible to
add debug code that checks that it is only called when the
{Update,Delete,Insert}ResultSet has been opened (to prevent calls at
ResultSet construction time).

2) Move UpdateResultSet's call to decodeLockMode() from the
constructor to open().

3) Make the NoRowsResultSetImpl class hierarchy maintain an isOpen
variable that is set to true on open and to false on
close. Previously, an isClosed variable was used, which was false
until the first call to close(), after which it would be true forever
even after the RS was reopened. This change was necessary to be able
to assert that the result set had been opened in decodeLockMode().

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLVTIResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeleteResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MiscResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java Fri May 11 01:37:02 2007
@@ -64,6 +64,7 @@
 	*/
 	public void open() throws StandardException
 	{
+		setup();
 		methodCall.invoke(activation);
 		close();
     }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLVTIResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLVTIResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLVTIResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLVTIResultSet.java Fri May 11 01:37:02 2007
@@ -86,6 +86,7 @@
 	*/
 	public void open() throws StandardException
 	{
+		setup();
 		// Remember if this is the 1st execution
 		firstExecute = (numOpens == 0);
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java Fri May 11 01:37:02 2007
@@ -26,6 +26,7 @@
 import org.apache.derby.iapi.services.io.StreamStorable;
 import org.apache.derby.iapi.sql.execute.ExecRow;
 import org.apache.derby.iapi.sql.execute.ConstantAction;
+import org.apache.derby.iapi.sql.execute.ExecutionContext;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
@@ -36,6 +37,7 @@
 
 import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.services.io.FormatableBitSet;
+import org.apache.derby.iapi.services.sanity.SanityManager;
 
 /**
  * For INSERT/UPDATE/DELETE impls.  Used to tag them.
@@ -204,7 +206,48 @@
 
 		return deferredSparseRow;
 	}
-	
+
+    /**
+     * Decode the update lock mode.
+     * <p>
+     * The value for update lock mode is in the second most significant byte for
+     * ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL isolation level. Otherwise
+     * (REPEATABLE READ, READ COMMITTED, and READ UNCOMMITTED) the lock mode is
+     * located in the least significant byte.
+     * <p>
+     * This is done to override the optimizer choice to provide maximum 
+     * concurrency of record level locking except in SERIALIZABLE where table
+     * level locking is required in heap scans for correctness.
+     *
+     * @param lockMode the compiled encoded lock mode for this query
+     * @return the lock mode (record or table) to use to open the result set
+     * @see org.apache.derby.impl.sql.compile.FromBaseTable#updateTargetLockMode
+     */
+    int decodeLockMode(int lockMode) {
+
+        if (SanityManager.DEBUG) {
+            // we want to decode lock mode when the result set is opened, not
+            // in the constructor
+            SanityManager.ASSERT(!isClosed());
+        }
+
+        if ((lockMode >>> 16) == 0) {
+            return lockMode;
+        }
+
+        // Note that isolation level encoding from getCurrentIsolationLevel()
+        // returns ExecutionContext.*ISOLATION_LEVEL constants, not
+        // TransactionController.ISOLATION* constants.
+
+        int isolationLevel = lcc.getCurrentIsolationLevel();
+
+        if (isolationLevel == ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL) {
+            return lockMode >>> 16;
+        }
+
+        return lockMode & 0xff;
+    }
+
 	/**
 	 * get the index name given the conglomerate id of the index.
 	 * 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeleteResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeleteResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeleteResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeleteResultSet.java Fri May 11 01:37:02 2007
@@ -199,6 +199,7 @@
 	//this routine open the source and find the dependent rows 
 	void  setup() throws StandardException
 	{
+		super.setup();
 
 		// Remember if this is the 1st execution
 		firstExecute = (rc == null);
@@ -251,7 +252,7 @@
 			lcc.getStatementContext().setTopResultSet(this, subqueryTrackingArray);
 		}
 		/* decode the lock mode for the execution isolation level */
-		lockMode = UpdateResultSet.decodeLockMode(lcc, constants.lockMode);
+		lockMode = decodeLockMode(constants.lockMode);
 
 		/* Open the RowChanger before the source ResultSet so that
 		 * the store will see the RowChanger's lock as a covering lock

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java Fri May 11 01:37:02 2007
@@ -389,6 +389,7 @@
 	*/
 	public void open() throws StandardException
 	{
+		setup();
 		// Remember if this is the 1st execution
 		firstExecute = (rowChanger == null);
 
@@ -885,7 +886,7 @@
 		}
 
 		/* decode lock mode for the execution isolation level */
-		int lockMode = UpdateResultSet.decodeLockMode(lcc, constants.lockMode);
+		int lockMode = decodeLockMode(constants.lockMode);
 
 		rowChanger.open(lockMode);
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MiscResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MiscResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MiscResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MiscResultSet.java Fri May 11 01:37:02 2007
@@ -60,6 +60,7 @@
 	 */
 	public void open() throws StandardException
 	{
+		setup();
 		activation.getConstantAction().executeConstantAction(activation);
 		super.close();
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java Fri May 11 01:37:02 2007
@@ -70,7 +70,8 @@
 	NoPutResultSet[]	subqueryTrackingArray;
 
 	private final boolean statisticsTimingOn;
-	private boolean isClosed;
+	/** True if the result set has been opened, and not yet closed. */
+	private boolean isOpen;
 
 	/* fields used for formating run time statistics output */
 	protected String indent;
@@ -114,6 +115,16 @@
 		}
 	}
 
+	/**
+	 * Set up the result set for use. Should always be called from
+	 * <code>open()</code>.
+	 *
+	 * @exception StandardException thrown on error
+	 */
+	void setup() throws StandardException {
+		isOpen = true;
+	}
+
     /**
 	 * Returns FALSE
 	 */
@@ -342,7 +353,7 @@
 	 */
 	public void	close() throws StandardException
 	{ 
-		isClosed = true;
+		isOpen = false;
 	}
 
 	/**
@@ -351,7 +362,7 @@
 	 * @return <code>true</code> if closed, <code>false</code> otherwise
 	 */
 	public boolean isClosed() {
-		return isClosed;
+		return !isOpen;
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java?view=diff&rev=537128&r1=537127&r2=537128
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java Fri May 11 01:37:02 2007
@@ -38,7 +38,6 @@
 import org.apache.derby.iapi.sql.execute.ConstantAction;
 import org.apache.derby.iapi.sql.execute.CursorResultSet;
 import org.apache.derby.iapi.sql.execute.ExecRow;
-import org.apache.derby.iapi.sql.execute.ExecutionContext;
 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
 import org.apache.derby.iapi.sql.execute.RowChanger;
 import org.apache.derby.iapi.store.access.ConglomerateController;
@@ -236,8 +235,6 @@
 		/* Get the new base row */
 		newBaseRow = RowUtil.getEmptyValueRow(numberOfBaseColumns, lcc);
 
-		/* decode lock mode */
-		lockMode = decodeLockMode(lcc, constants.lockMode);
 		deferred = constants.deferred;
 		
 		//update can be marked for deferred mode because the scan is being done
@@ -289,6 +286,11 @@
 	*/
 	void setup() throws StandardException
 	{
+		super.setup();
+
+		/* decode lock mode */
+		lockMode = decodeLockMode(constants.lockMode);
+
 		boolean firstOpen = (rowChanger == null);
 
 		rowCount = 0;
@@ -1097,54 +1099,6 @@
 		endTime = getCurrentTimeMillis();
 	}
 
-    /**
-     * Decode the update lock mode.
-     * <p>
-     * The value for update lock mode is in the 2nd 2 bytes for 
-     * ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL isolation level.  Otherwise
-     * (REPEATABLE READ, READ COMMITTED, and READ UNCOMMITTED) the lock mode is
-     * located in the first 2 bytes.
-     * <p>
-     * This is done to override the optimizer choice to provide maximum 
-     * concurrency of record level locking except in SERIALIZABLE where table
-     * level locking is required in heap scans for correctness.
-     * <p>
-     * See Compilation!QueryTree!FromBaseTable for encoding of the lockmode.
-     * <p>
-     *
-	 * @return The lock mode (record or table) to use to open the result set.
-     *
-     * @param lcc       The context to look for current isolation level.
-     * @param lockMode  The compiled encoded lock mode for this query.
-     *
-	 * @exception  StandardException  Standard exception policy.
-     **/
-	protected static int decodeLockMode(
-    LanguageConnectionContext   lcc, 
-    int                         lockMode)
-	{
-		if ((lockMode >>> 16) != 0)
-		{
-            // Note that isolation level encoding from 
-            // getCurrentIsolationLevel() returns 
-            // ExecutionContext.*ISOLATION_LEVEL constants, not 
-            // TransactionController.ISOLATION* constants.
-
-			int isolationLevel = lcc.getCurrentIsolationLevel();
-
-            if (isolationLevel != ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL)
-            {
-				lockMode = lockMode & 0xff;
-            }
-            else
-            {
-				lockMode = lockMode >>> 16;
-            }
-		}
-		return lockMode;
-	}
-
-	
 	void rowChangerFinish() throws StandardException
 	{
 		rowChanger.finish();