db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r645438 - in /db/derby/code/branches/10.4/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ testing/org/apache/derbyTesting/functionTests/tests/derbynet/
Date Mon, 07 Apr 2008 10:03:03 GMT
Author: kristwaa
Date: Mon Apr  7 03:03:01 2008
New Revision: 645438

URL: http://svn.apache.org/viewvc?rev=645438&view=rev
Log:
DERBY-3571: LOB locators are not released if the LOB columns are not accessed by the client.
Merge from trunk revision 643819 (derby-3571-2a-simple_release.diff).
The patch added the client side LOB state tracking, used to release LOB locators in a timely
manner.

Added:
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java
      - copied unchanged from r643819, db/derby/code/trunk/java/client/org/apache/derby/client/am/LOBStateTracker.java
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/LOBLocatorReleaseTest.java
      - copied unchanged from r643819, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/LOBLocatorReleaseTest.java
Modified:
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Connection.java
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Cursor.java
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Statement.java
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetConnection.java
    db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java
    db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Connection.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Connection.java Mon
Apr  7 03:03:01 2008
@@ -1000,6 +1000,13 @@
      */
     protected abstract boolean supportsSessionDataCaching();
 
+    /**
+     * Checks whether the server supports locators for large objects.
+     *
+     * @return {@code true} if LOB locators are supported.
+     */
+    protected abstract boolean serverSupportsLocators();
+
     public int getTransactionIsolation() throws SQLException {
     	
     	// Store the current auto-commit value and use it to restore 

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Cursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Cursor.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Cursor.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Cursor.java Mon Apr
 7 03:03:01 2008
@@ -663,6 +663,29 @@
         return recyclableCalendar_;
     }
 
+    /**
+     * Returns a reference to the locator procedures.
+     * <p>
+     * These procedures are used to operate on large objects referenced on the
+     * server by locators.
+     *
+     * @return The locator procedures object.
+     */
+    CallableLocatorProcedures getLocatorProcedures() {
+        return agent_.connection_.locatorProcedureCall();
+    }
+
+    /**
+     * Obtains the locator for the specified LOB column.
+     * <p>
+     * Note that this method cannot be invoked on a LOB column that is NULL.
+     *
+     * @param column 1-based column index
+     * @return A positive integer locator if valid, {@link Lob#INVALID_LOCATOR}
+     *      otherwise.
+     */
+    protected abstract int locator(int column);
+
     abstract public Blob getBlobColumn_(int column, Agent agent) throws SqlException;
 
     abstract public Clob getClobColumn_(int column, Agent agent) throws SqlException;

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java Mon
Apr  7 03:03:01 2008
@@ -28,6 +28,7 @@
 import org.apache.derby.client.am.SQLExceptionFactory;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.shared.common.i18n.MessageUtil;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 public abstract class ResultSet implements java.sql.ResultSet,
         ResultSetCallbackInterface {
@@ -37,6 +38,8 @@
     public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
     private SqlWarning warnings_;
     public Cursor cursor_;
+    /** Tracker object for LOB state, used to free locators on the server. */
+    private LOBStateTracker lobState = null;
     protected Agent agent_;
 
     public Section generatedSection_ = null;
@@ -427,6 +430,12 @@
             return;
         }
         closeCloseFilterInputStream();
+        // See if there are open locators on the current row, if valid.
+        if (isValidCursorPosition_ && !isOnInsertRow_) {
+            lobState.checkCurrentRow(cursor_);
+        }
+        // NOTE: The preClose_ method must also check for locators if
+        //       prefetching of data is enabled for result sets containing LOBs.
         preClose_();
         try {
             if (openOnServer_) {
@@ -3758,6 +3767,12 @@
         }
     }
     
+    /**
+     * Moves off the insert row if positioned there, and checks the current row
+     * for releasable LOB locators if positioned on a valid data row.
+     *
+     * @throws SqlException if releasing a LOB locator fails
+     */
     private void moveToCurrentRowX() throws SqlException {
         if (isOnInsertRow_) {
             resetUpdatedColumns();
@@ -3768,6 +3783,14 @@
             }
             isValidCursorPosition_ = true;
         }
+        if (isValidCursorPosition_) {
+            // isOnInsertRow must be false here.
+            if (SanityManager.DEBUG) {
+                SanityManager.ASSERT(!isOnInsertRow_,
+                        "Cannot check current row if positioned on insert row");
+            }
+            lobState.checkCurrentRow(cursor_);
+        }
     }
 
     /**
@@ -4339,6 +4362,7 @@
 
     public void completeLocalCommit(java.util.Iterator listenerIterator) {
         cursorUnpositionedOnServer_ = true;
+        lobState.discardState(); // Locators released on server side.
         markAutoCommitted();
         if (!cursorHold_) {
             // only non-held cursors need to be closed at commit
@@ -4351,6 +4375,7 @@
     }
 
     public void completeLocalRollback(java.util.Iterator listenerIterator) {
+        lobState.discardState(); // Locators released on server side.
         markAutoCommitted();
         // all cursors need to be closed at rollback
         markClosed();
@@ -6172,6 +6197,54 @@
             updateClob(findColumnX(columnLabel), x);
         } catch (SqlException se) {
             throw se.getSQLException();
+        }
+    }
+
+    /**
+     * Marks the LOB at the specified column as accessed.
+     * <p>
+     * When a LOB is marked as accessed, the release mechanism will not be
+     * invoked by the result set. It is expected that the code accessing the
+     * LOB releases the locator when it is done with the LOB.
+     *
+     * @param index 1-based column index
+     */
+    public final void markLOBAsAccessed(int index) {
+        this.lobState.markAccessed(index);
+    }
+
+    /**
+     * Initializes the LOB state tracker.
+     * <p>
+     * The state tracker is used to free LOB locators on the server.
+     */
+    final void createLOBColumnTracker() {
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(this.lobState == null,
+                    "LOB state tracker already initialized.");
+        }
+        if (this.resultSetMetaData_.hasLobColumns()) {
+            final int columnCount = this.resultSetMetaData_.columns_;
+            int lobCount = 0;
+            int[] tmpIndexes = new int[columnCount];
+            boolean[] tmpIsBlob = new boolean[columnCount];
+            for (int i=0; i < columnCount; i++) {
+                int type = this.resultSetMetaData_.types_[i];
+                if (type == Types.BLOB || type == Types.CLOB) {
+                    tmpIndexes[lobCount] = i +1; // Convert to 1-based index.
+                    tmpIsBlob[lobCount++] = (type == Types.BLOB);
+                }
+            }
+            // Create a tracker for the LOB columns found.
+            int[] lobIndexes = new int[lobCount];
+            boolean[] isBlob = new boolean[lobCount];
+            System.arraycopy(tmpIndexes, 0, lobIndexes, 0, lobCount);
+            System.arraycopy(tmpIsBlob, 0, isBlob, 0, lobCount);
+            this.lobState = new LOBStateTracker(lobIndexes, isBlob,
+                    this.connection_.serverSupportsLocators());
+        } else {
+            // Use a no-op state tracker to simplify code expecting a tracker.
+            this.lobState = LOBStateTracker.NO_OP_TRACKER;
         }
     }
 }

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Statement.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Statement.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/Statement.java Mon
Apr  7 03:03:01 2008
@@ -1489,6 +1489,8 @@
         }
         resultSet.resultSetMetaData_ = resultSetMetaData_;
         resultSet.resultSetMetaData_.resultSetConcurrency_ = resultSet.resultSetConcurrency_;
+        // Create tracker for LOB locator columns.
+        resultSet.createLOBColumnTracker();
 
         // only cache the Cursor object for a PreparedStatement and if a Cursor object is
         // not already cached.
@@ -1521,6 +1523,8 @@
         resultSet.completeSqlca(sqlca);
         // For CallableStatements we can't just clobber the resultSet_ here, must use setResultSetEvent()
separately
         resultSet.resultSetMetaData_ = resultSetMetaData;
+        // Create tracker for LOB locator columns.
+        resultSet.createLOBColumnTracker();
 
         // The following two assignments should have already happened via prepareEvent(),
         // but are included here for safety for the time being.

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetConnection.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetConnection.java
(original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetConnection.java
Mon Apr  7 03:03:01 2008
@@ -1731,6 +1731,17 @@
     }
 
     /**
+     * Checks whether the server supports locators for large objects.
+     *
+     * @return {@code true} if LOB locators are supported.
+     */
+    protected final boolean serverSupportsLocators() {
+        // Support for locators was added in the same version as layer B
+        // streaming.
+        return serverSupportsLayerBStreaming();
+    }
+
+    /**
      * Returns if a transaction is in process
      * @return open
      */

Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java Mon
Apr  7 03:03:01 2008
@@ -1054,11 +1054,14 @@
     
     /**
      * Get locator for LOB of the designated column
+     * <p>
+     * Note that this method cannot be invoked on a LOB column that is NULL.
+     *
      * @param column column number, starts at 1
      * @return locator value, <code>Lob.INVALID_LOCATOR</code> if LOB
      *         value was sent instead of locator
      */
-    private int locator(int column)
+    protected int locator(int column)
     {
         int locator = get_INTEGER(column);
         // If Lob value was sent instead of locator, the value will be
@@ -1075,6 +1078,7 @@
 
     public Blob getBlobColumn_(int column, Agent agent) throws SqlException 
     {
+        netResultSet_.markLOBAsAccessed(column);
         // Check for locator
         int locator = locator(column);
         if (locator > 0) { // Create locator-based LOB object
@@ -1109,6 +1113,7 @@
 
 
     public Clob getClobColumn_(int column, Agent agent) throws SqlException {
+        netResultSet_.markLOBAsAccessed(column);
         // Check for locator
         int locator = locator(column);
         if (locator > 0) { // Create locator-based LOB object

Modified: db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java?rev=645438&r1=645437&r2=645438&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java
(original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java
Mon Apr  7 03:03:01 2008
@@ -58,6 +58,7 @@
         suite.addTest(NSinSameJVMTest.suite());
         suite.addTest(NetworkServerControlClientCommandTest.suite());
         suite.addTest(ServerPropertiesTest.suite());
+        suite.addTest(LOBLocatorReleaseTest.suite());
         
         
         // Disabled due to "java.sql.SQLSyntaxErrorException: The class



Mime
View raw message