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 jb...@apache.org on 2005/05/02 08:26:03 UTC

svn commit: r165585 [19/42] - in /incubator/derby/code/trunk/java/client/org/apache/derby: client/ client/am/ client/net/ client/resources/ jdbc/

Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=165585&r1=165584&r2=165585&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Sun May  1 23:25:59 2005
@@ -20,3512 +20,3778 @@
 
 package org.apache.derby.client.am;
 
-import org.apache.derby.client.am.Section;
+
 
 public abstract class ResultSet implements java.sql.ResultSet,
-                                           ResultSetCallbackInterface,
-                                           UnitOfWorkListener
+        ResultSetCallbackInterface,
+        UnitOfWorkListener {
+    //---------------------navigational members-----------------------------------
+
+    public Statement statement_;
+    public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
+    private SqlWarning warnings_;
+    public Cursor cursor_;
+    protected Agent agent_;
+
+    public Section generatedSection_ = null;
+
+    //---------------------navigational cheat-links-------------------------------
+    // Cheat-links are for convenience only, and are not part of the conceptual model.
+    // Warning:
+    //   Cheat-links should only be defined for invariant state data.
+    //   That is, the state data is set by the constructor and never changes.
+
+    // Alias for statement_.connection
+    public final Connection connection_;
+
+    //----------------------------- constants ------------------------------------
+
+    public final static int scrollOrientation_relative__ = 1;
+    public final static int scrollOrientation_absolute__ = 2;
+    public final static int scrollOrientation_after__ = 3;
+    public final static int scrollOrientation_before__ = 4;
+    public final static int scrollOrientation_prior__ = 5;
+    public final static int scrollOrientation_first__ = 6;
+    public final static int scrollOrientation_last__ = 7;
+    public final static int scrollOrientation_current__ = 8;
+    public final static int scrollOrientation_next__ = 0;
+
+    public final static int updatability_unknown__ = 0;
+    public final static int updatability_readOnly__ = 1;
+    public final static int updatability_delete__ = 2;
+    public final static int updatability_update__ = 4;
+
+    public final static int sensitivity_unknown__ = 0;
+    public final static int sensitivity_insensitive__ = 1;
+    public final static int sensitivity_sensitive_static__ = 2;
+    public final static int sensitivity_sensitive_dynamic__ = 3;
+
+    static final private int WAS_NULL = 1;
+    static final private int WAS_NOT_NULL = 2;
+    static final private int WAS_NULL_UNSET = 0;
+
+    static final public int NEXT_ROWSET = 1;
+    static final public int PREVIOUS_ROWSET = 2;
+    static final public int ABSOLUTE_ROWSET = 3;
+    static final public int FIRST_ROWSET = 4;
+    static final public int LAST_ROWSET = 5;
+    static final public int RELATIVE_ROWSET = 6;
+    static final public int REFRESH_ROWSET = 7;
+    //  determines if a cursor is a:
+    //    Return to Client - not to be read by the stored procedure only by client
+    //    Return to Caller
+    public static final byte DDM_RETURN_CALLER = 0x01;
+    public static final byte DDM_RETURN_CLIENT = 0x02;
+
+    //-----------------------------state------------------------------------------
+
+    // Note:
+    //   Result set meta data as described by the SQLDA is described in ColumnMetaData.
+
+    private int wasNull_ = WAS_NULL_UNSET;
+
+    // ResultSet returnability for Stored Procedure cursors
+    //  determines if a cursor is a:
+    //    Return to Client - not to be read by the stored procedure only by client
+    //    Return to Caller - only calling JSP can read it, not the client
+    protected byte rsReturnability_ = DDM_RETURN_CLIENT;
+
+    // This means the client-side jdbc result set object is open.
+    boolean openOnClient_ = true;
+    // This means a server-side DERBY query section (cursor) for this result set is in the open state.
+    // A jdbc result set may remain open even after the server has closed its cursor
+    // (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
+    public boolean openOnServer_ = true;
+
+    // there is a query terminating sqlca returned from the server when the server closes
+    // it's cursor and the client moves to the close-only state.
+    public Sqlca queryTerminatingSqlca_;
+
+    // Only true for forward cursors after next() returns false (+100).
+    // Used to prevent multiple commits for subsequent next() calls.
+    boolean autoCommitted_ = false;
+
+    // Before the first call to next() or any cursor positioning method, the cursor position is invalid
+    // and getter methods cannot be called.
+    // Also, if a cursor is exhausted (+100), the cursor position is invalid.
+    public boolean isValidCursorPosition_ = false;
+
+    public boolean cursorHold_;
+
+    // query instance identifier returned on open by uplevel servers.
+    // this value plus the package information uniquely identifies a query.
+    // it is 64 bits long and it's value is unarchitected.
+    public long queryInstanceIdentifier_ = 0;
+
+    public int resultSetType_;
+    public int resultSetConcurrency_;
+    public int resultSetHoldability_;
+    public boolean scrollable_ = false;
+    public int sensitivity_;
+    public boolean isRowsetCursor_ = false;
+    public boolean isBeforeFirst_ = true;
+    public boolean isAfterLast_ = false;
+    public boolean isFirst_ = false;
+    public boolean isLast_ = false;
+    public boolean rowsetContainsLastRow_ = false;
+    public Sqlca[] rowsetSqlca_;
+    public int fetchSize_;
+    public int fetchDirection_;
+
+    public long rowCount_ = -1;
+
+    protected long absolutePosition_ = 0;       // absolute position of the current row
+    protected long firstRowInRowset_ = 0;       // absolute position of the first row in the current rowset
+    protected long lastRowInRowset_ = 0;        // absolute position of the last row in the current rowset
+    protected long currentRowInRowset_ = -1;     // relative position to the first row in the current rowsetwel
+
+    protected long absoluteRowNumberForTheIntendedRow_;
+
+    // This variable helps keep track of whether cancelRowUpdates() should have any effect.
+    protected boolean updateRowCalled_ = false;
+    private boolean isOnInsertRow_ = false;  // reserved for later
+    protected boolean isOnCurrentRow_ = true;
+    public int rowsReceivedInCurrentRowset_ = 0;  // keep track of the number of rows received in the
+    // current rowset so far
+
+    // maybe be able to consolidate with rowsReceivedInCurrentRowset_
+    // Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
+    // fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
+    // Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
+    // for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
+    // when it's reset.  By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
+    // request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
+    // otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
+    public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
+    // be received to complete the rowset
+
+    private Object updatedColumns_[];
+
+    // Keeps track of whether a column has been updated.  If a column is updated to null,
+    // the object array updatedColumns_ entry is null, and we will use this array to distinguish
+    // between column not updated and column updated to null.
+    private boolean columnUpdated_[];
+
+    public PreparedStatement preparedStatementForUpdate_;
+    public PreparedStatement preparedStatementForDelete_;
+
+    // Nesting level of the result set in a stored procedure
+    public int nestingLevel_ = -1;
+
+    // Whenever a commit occurs, it unpositions the cursor on the server.  We need to
+    // reposition the cursor before updating/deleting again.  This flag will be set to true
+    // whenever a commit happens, and reset to false again after we repositoin the cursor.
+    public boolean cursorUnpositionedOnServer_ = false;
+
+    //---------------------constructors/finalizer---------------------------------
+
+    protected ResultSet(Agent agent,
+                        Statement statement,
+                        Cursor cursor,
+                        int resultSetType,
+                        int resultSetConcurrency,
+                        int resultSetHoldability) {
+        agent_ = agent;
+        statement_ = statement;
+        connection_ = statement_.connection_;
+        cursor_ = cursor;
+        if (cursor_ != null) {
+            cursor_.maxFieldSize_ = statement_.maxFieldSize_;
+        }
+        resultSetType_ = resultSetType;
+        resultSetConcurrency_ = resultSetConcurrency;
+        resultSetHoldability_ = resultSetHoldability;
+        fetchDirection_ = statement_.fetchDirection_;
+        fetchSize_ = statement_.fetchSize_;
+
+        // Only set the warning if actual resultSetType returned by the server is less
+        // than the application requested resultSetType.
+        // TYPE_FORWARD_ONLY = 1003
+        // TYPE_SCROLL_INSENSITIVE = 1004
+        // TYPE_SCROLL_SENSITIVE = 1005
+        if (resultSetType_ < statement_.resultSetType_) {
+            statement_.accumulateWarning
+                    (new SqlWarning(agent_.logWriter_, "Unable to open resultSet type " +
+                    statement_.resultSetType_ + "." +
+                    " ResultSet type " + resultSetType_ + " opened."));
+        }
+
+        // Only set the warning if actual resultSetConcurrency returned by the server is
+        // less than the application requested resultSetConcurrency.
+        // CONCUR_READ_ONLY = 1007
+        // CONCUR_UPDATABLE = 1008
+        if (resultSetConcurrency_ < statement_.resultSetConcurrency_) {
+            statement_.accumulateWarning
+                    (new SqlWarning(agent_.logWriter_, "Unable to open ResultSet with concurrency  " +
+                    statement_.resultSetConcurrency_ + "." +
+                    " ResultSet concurrency " + resultSetConcurrency_ + " is used."));
+        }
+
+        listenToUnitOfWork();
+    }
+
+    // ---------------------------jdbc 1------------------------------------------
 
-{
-  //---------------------navigational members-----------------------------------
+    public final boolean next() throws SqlException {
+        synchronized (connection_) {
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceEntry(this, "next");
+            }
+            boolean isValidCursorPosition = nextX();
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceExit(this, "next", isValidCursorPosition);
+            }
+            return isValidCursorPosition;
+        }
+    }
 
-  public Statement statement_;
-  public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
-  private SqlWarning warnings_;
-  public Cursor cursor_;
-  protected Agent agent_;
-
-  public Section generatedSection_ = null;
-
-  //---------------------navigational cheat-links-------------------------------
-  // Cheat-links are for convenience only, and are not part of the conceptual model.
-  // Warning:
-  //   Cheat-links should only be defined for invariant state data.
-  //   That is, the state data is set by the constructor and never changes.
-
-  // Alias for statement_.connection
-  public final Connection connection_;
-
-  //----------------------------- constants ------------------------------------
-
-  public final static int scrollOrientation_relative__ = 1;
-  public final static int scrollOrientation_absolute__ = 2;
-  public final static int scrollOrientation_after__ = 3;
-  public final static int scrollOrientation_before__ = 4;
-  public final static int scrollOrientation_prior__ = 5;
-  public final static int scrollOrientation_first__ = 6;
-  public final static int scrollOrientation_last__ = 7;
-  public final static int scrollOrientation_current__ = 8;
-  public final static int scrollOrientation_next__ = 0;
-
-  public final static int updatability_unknown__ = 0;
-  public final static int updatability_readOnly__ = 1;
-  public final static int updatability_delete__ = 2;
-  public final static int updatability_update__ = 4;
-
-  public final static int sensitivity_unknown__ = 0;
-  public final static int sensitivity_insensitive__ = 1;
-  public final static int sensitivity_sensitive_static__ = 2;
-  public final static int sensitivity_sensitive_dynamic__ = 3;
-
-  static final private int WAS_NULL = 1;
-  static final private int WAS_NOT_NULL = 2;
-  static final private int WAS_NULL_UNSET = 0;
-
-  static final public int NEXT_ROWSET = 1;
-  static final public int PREVIOUS_ROWSET = 2;
-  static final public int ABSOLUTE_ROWSET = 3;
-  static final public int FIRST_ROWSET = 4;
-  static final public int LAST_ROWSET = 5;
-  static final public int RELATIVE_ROWSET = 6;
-  static final public int REFRESH_ROWSET = 7;
-  //  determines if a cursor is a:
-  //    Return to Client - not to be read by the stored procedure only by client
-  //    Return to Caller
-  public static final byte DDM_RETURN_CALLER = 0x01;
-  public static final byte DDM_RETURN_CLIENT = 0x02;
-
-  //-----------------------------state------------------------------------------
-
-  // Note:
-  //   Result set meta data as described by the SQLDA is described in ColumnMetaData.
-
-  private int wasNull_ = WAS_NULL_UNSET;
-
-  // ResultSet returnability for Stored Procedure cursors
-  //  determines if a cursor is a:
-  //    Return to Client - not to be read by the stored procedure only by client
-  //    Return to Caller - only calling JSP can read it, not the client
-  protected byte rsReturnability_ = DDM_RETURN_CLIENT;
-
-  // This means the client-side jdbc result set object is open.
-  boolean openOnClient_ = true;
-  // This means a server-side DERBY query section (cursor) for this result set is in the open state.
-  // A jdbc result set may remain open even after the server has closed its cursor
-  // (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
-  public boolean openOnServer_ = true;
-
-  // there is a query terminating sqlca returned from the server when the server closes
-  // it's cursor and the client moves to the close-only state.
-  public Sqlca queryTerminatingSqlca_;
-
-  // Only true for forward cursors after next() returns false (+100).
-  // Used to prevent multiple commits for subsequent next() calls.
-  boolean autoCommitted_ = false;
-
-  // Before the first call to next() or any cursor positioning method, the cursor position is invalid
-  // and getter methods cannot be called.
-  // Also, if a cursor is exhausted (+100), the cursor position is invalid.
-  public boolean isValidCursorPosition_ = false;
-
-  public boolean cursorHold_;
-
-  // query instance identifier returned on open by uplevel servers.
-  // this value plus the package information uniquely identifies a query.
-  // it is 64 bits long and it's value is unarchitected.
-  public long queryInstanceIdentifier_ = 0;
-
-  public int resultSetType_;
-  public int resultSetConcurrency_;
-  public int resultSetHoldability_;
-  public boolean scrollable_ = false;
-  public int sensitivity_;
-  public boolean isRowsetCursor_ = false;
-  public boolean isBeforeFirst_ = true;
-  public boolean isAfterLast_ = false;
-  public boolean isFirst_ = false;
-  public boolean isLast_ = false;
-  public boolean rowsetContainsLastRow_ = false;
-  public Sqlca[] rowsetSqlca_;
-  public int fetchSize_;
-  public int fetchDirection_;
-
-  public long rowCount_ = -1;
-
-  protected long absolutePosition_ = 0;       // absolute position of the current row
-  protected long firstRowInRowset_ = 0;       // absolute position of the first row in the current rowset
-  protected long lastRowInRowset_ = 0;        // absolute position of the last row in the current rowset
-  protected long currentRowInRowset_ = -1;     // relative position to the first row in the current rowsetwel
-
-  protected long absoluteRowNumberForTheIntendedRow_;
-
-  // This variable helps keep track of whether cancelRowUpdates() should have any effect.
-  protected boolean updateRowCalled_ = false;
-  private boolean isOnInsertRow_ = false;  // reserved for later
-  protected boolean isOnCurrentRow_ = true;
-  public int rowsReceivedInCurrentRowset_ = 0;  // keep track of the number of rows received in the
-                                                // current rowset so far
-
-  // maybe be able to consolidate with rowsReceivedInCurrentRowset_
-  // Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
-  // fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
-  // Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
-  // for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
-  // when it's reset.  By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
-  // request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
-  // otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
-  public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
-                                                // be received to complete the rowset
-
-  private Object updatedColumns_[];
-
-  // Keeps track of whether a column has been updated.  If a column is updated to null,
-  // the object array updatedColumns_ entry is null, and we will use this array to distinguish
-  // between column not updated and column updated to null.
-  private boolean columnUpdated_[];
-
-  public PreparedStatement preparedStatementForUpdate_;
-  public PreparedStatement preparedStatementForDelete_;
-
-  // Nesting level of the result set in a stored procedure
-  public int nestingLevel_ = -1;
-
-  // Whenever a commit occurs, it unpositions the cursor on the server.  We need to
-  // reposition the cursor before updating/deleting again.  This flag will be set to true
-  // whenever a commit happens, and reset to false again after we repositoin the cursor.
-  public boolean cursorUnpositionedOnServer_ = false;
-
-  //---------------------constructors/finalizer---------------------------------
-
-  protected ResultSet (Agent agent,
-                       Statement statement,
-                       Cursor cursor,
-                       int resultSetType,
-                       int resultSetConcurrency,
-                       int resultSetHoldability)
-  {
-    agent_ = agent;
-    statement_ = statement;
-    connection_ = statement_.connection_;
-    cursor_ = cursor;
-    if (cursor_ != null) cursor_.maxFieldSize_ = statement_.maxFieldSize_;
-    resultSetType_ = resultSetType;
-    resultSetConcurrency_ = resultSetConcurrency;
-    resultSetHoldability_ = resultSetHoldability;
-    fetchDirection_ = statement_.fetchDirection_;
-    fetchSize_ = statement_.fetchSize_;
-
-    // Only set the warning if actual resultSetType returned by the server is less
-    // than the application requested resultSetType.
-    // TYPE_FORWARD_ONLY = 1003
-    // TYPE_SCROLL_INSENSITIVE = 1004
-    // TYPE_SCROLL_SENSITIVE = 1005
-    if (resultSetType_ < statement_.resultSetType_)
-      statement_.accumulateWarning
-        (new SqlWarning (agent_.logWriter_, "Unable to open resultSet type " +
-                         statement_.resultSetType_ + "." +
-                         " ResultSet type " + resultSetType_ + " opened."));
-
-    // Only set the warning if actual resultSetConcurrency returned by the server is
-    // less than the application requested resultSetConcurrency.
-    // CONCUR_READ_ONLY = 1007
-    // CONCUR_UPDATABLE = 1008
-    if (resultSetConcurrency_ < statement_.resultSetConcurrency_)
-      statement_.accumulateWarning
-        (new SqlWarning (agent_.logWriter_, "Unable to open ResultSet with concurrency  " +
-                         statement_.resultSetConcurrency_ + "." +
-                         " ResultSet concurrency " + resultSetConcurrency_ + " is used."));
-
-    listenToUnitOfWork();
-  }
-
-  // ---------------------------jdbc 1------------------------------------------
-
-  public final boolean next () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "next");
-      boolean isValidCursorPosition = nextX();
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "next", isValidCursorPosition);
-      return isValidCursorPosition;
-    }
-  }
-
-  // used by DBMD
-  boolean nextX () throws SqlException
-  {
-    checkForClosedResultSet ();
-    clearWarningsX ();
-
-    wasNull_ = ResultSet.WAS_NULL_UNSET;
-
-    // discard all previous updates when moving the cursor
-    resetUpdatedColumns ();
-
-    // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
-    if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
-      // cursor is null for singleton selects that do not return data.
-      isValidCursorPosition_ = (cursor_ == null) ? false : cursor_.next ();
-
-      // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
-      // then we must count the rows returned in the rowset to make sure we received a
-      // complete rowset.  if not, we need to complete the rowset on the next fetch.
-      if (fetchSize_ != 0) {
-        if (rowsYetToBeReceivedForRowset_ == 0) rowsYetToBeReceivedForRowset_ = fetchSize_;
-        if (isValidCursorPosition_) rowsYetToBeReceivedForRowset_--;
-      }
-
-      // Auto-commit semantics for exhausted cursors follows.
-      // From Connection.setAutoCommit() javadoc:
-      //   The commit occurs when the statement completes or the next execute occurs, whichever comes first.
-      //   In the case of statements returning a ResultSet object, the statement completes when the
-      //   last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
-      //   In advanced cases, a single statement may return multiple results as well as output parameter values.
-      //   In these cases, the commit occurs when all results and output parameter values have been retrieved.
-      // we will check to see if the forward only result set has gone past the end,
-      // we will close the result set, the autocommit logic is in the closeX() method
+    // used by DBMD
+    boolean nextX() throws SqlException {
+        checkForClosedResultSet();
+        clearWarningsX();
+
+        wasNull_ = ResultSet.WAS_NULL_UNSET;
+
+        // discard all previous updates when moving the cursor
+        resetUpdatedColumns();
+
+        // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
+        if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
+            // cursor is null for singleton selects that do not return data.
+            isValidCursorPosition_ = (cursor_ == null) ? false : cursor_.next();
+
+            // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
+            // then we must count the rows returned in the rowset to make sure we received a
+            // complete rowset.  if not, we need to complete the rowset on the next fetch.
+            if (fetchSize_ != 0) {
+                if (rowsYetToBeReceivedForRowset_ == 0) {
+                    rowsYetToBeReceivedForRowset_ = fetchSize_;
+                }
+                if (isValidCursorPosition_) {
+                    rowsYetToBeReceivedForRowset_--;
+                }
+            }
+
+            // Auto-commit semantics for exhausted cursors follows.
+            // From Connection.setAutoCommit() javadoc:
+            //   The commit occurs when the statement completes or the next execute occurs, whichever comes first.
+            //   In the case of statements returning a ResultSet object, the statement completes when the
+            //   last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
+            //   In advanced cases, a single statement may return multiple results as well as output parameter values.
+            //   In these cases, the commit occurs when all results and output parameter values have been retrieved.
+            // we will check to see if the forward only result set has gone past the end,
+            // we will close the result set, the autocommit logic is in the closeX() method
 //    if (!isValidCursorPosition_ && // We've gone past the end (+100)
 //        cursor_ != null) {
-      if ((!isValidCursorPosition_ && cursor_ != null) ||
-          (statement_.maxRows_ > 0 && cursor_.rowsRead_ > statement_.maxRows_)) {
-        isValidCursorPosition_ = false;
+            if ((!isValidCursorPosition_ && cursor_ != null) ||
+                    (statement_.maxRows_ > 0 && cursor_.rowsRead_ > statement_.maxRows_)) {
+                isValidCursorPosition_ = false;
+
+                // if not on a valid row and the query is closed at the server.
+                // check for an error which may have caused the cursor to terminate.
+                // if there were no more rows because of an error, then this method
+                // should throw an SqlException rather than just returning false.
+                // note: closeX is still called and this will cause the
+                // result set to be closed on the client. any additional calls to
+                // next() will fail checkForClosedResultSet(), the query terminating exception is
+                // only thrown once.
+                // depending on how this works with scrollable cursors, there may be
+                // a better way/more common place for this logic.
+                SqlException sqlException = null;
+                if (!openOnServer_) {
+                    int sqlcode = Utils.getSqlcodeFromSqlca(queryTerminatingSqlca_);
+                    if (sqlcode > 0 && sqlcode != 100) {
+                        accumulateWarning(new SqlWarning(agent_.logWriter_, queryTerminatingSqlca_));
+                    } else if (sqlcode < 0) {
+                        sqlException = new SqlException(agent_.logWriter_, queryTerminatingSqlca_);
+                    }
+                }
+                try {
+                    closeX(); // the auto commit logic is in closeX()
+                } catch (SqlException sqle) {
+                    sqlException = Utils.accumulateSQLException(sqle, sqlException);
+                }
+                if (sqlException != null) {
+                    throw sqlException;
+                }
+            }
+        }
 
-        // if not on a valid row and the query is closed at the server.
-        // check for an error which may have caused the cursor to terminate.
-        // if there were no more rows because of an error, then this method
-        // should throw an SqlException rather than just returning false.
-        // note: closeX is still called and this will cause the
-        // result set to be closed on the client. any additional calls to
-        // next() will fail checkForClosedResultSet(), the query terminating exception is
-        // only thrown once.
-        // depending on how this works with scrollable cursors, there may be
-        // a better way/more common place for this logic.
-        SqlException sqlException = null;
-        if (!openOnServer_) {
-          int sqlcode = Utils.getSqlcodeFromSqlca (queryTerminatingSqlca_);
-          if (sqlcode > 0 && sqlcode != 100) {
-            accumulateWarning(new SqlWarning (agent_.logWriter_, queryTerminatingSqlca_));
-          }
-          else if (sqlcode < 0)
-            sqlException = new SqlException (agent_.logWriter_, queryTerminatingSqlca_);
+        // for scrollable ResultSet's,
+        // if the "next" request is still fetching within the current rowset,
+        //   update column info from cache and increment the current row index
+        // else
+        //   fetch the next rowset from the server
+        else {
+
+            // These flags will only be used for dynamic cursors where we don't know the row count
+            // and can't keep track of the absolute position of the cursor.
+            isAfterLast_ = false;
+            isLast_ = false;
+
+            // if the next row is still within the current rowset
+            if (rowIsInCurrentRowset(firstRowInRowset_ + currentRowInRowset_ + 1, scrollOrientation_next__)) {
+                isValidCursorPosition_ = true;
+                currentRowInRowset_++;
+            } else {
+                checkAndThrowReceivedQueryTerminatingException();
+                isValidCursorPosition_ = getNextRowset();
+            }
+
+            if (isValidCursorPosition_) {
+                updateColumnInfoFromCache();
+                // check if there is a non-null SQLCA for the current row for rowset cursors
+                checkRowsetSqlca();
+                if (isBeforeFirst_) {
+                    isFirst_ = true;
+                }
+                isBeforeFirst_ = false;
+            } else {
+                isFirst_ = false;
+                return isValidCursorPosition_;
+            }
+        }
+
+        // for forward-only cursors, check if rowsRead_ > maxRows_.
+        // for scrollable cursors, check if absolute row number > maxRows_.
+        // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
+        if (!openOnClient_) {
+            isValidCursorPosition_ = false;
+        } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
+                (firstRowInRowset_ + currentRowInRowset_ > statement_.maxRows_)) {
+            isValidCursorPosition_ = false;
+        }
+        return isValidCursorPosition_;
+    }
+
+
+    public void close() throws SqlException {
+        synchronized (connection_) {
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceEntry(this, "close");
+            }
+            closeX();
+        }
+    }
+
+    // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
+    // that we later check to drive a commit.
+    // An untraced version of close()
+    public final void closeX() throws SqlException {
+        if (!openOnClient_) {
+            return;
         }
         try {
-          closeX(); // the auto commit logic is in closeX()
+            if (openOnServer_) {
+                flowCloseAndAutoCommitIfNotAutoCommitted();
+            } else {
+                flowAutoCommitIfNotAutoCommitted(); // in case of early close
+            }
+        } finally {
+            markClosed();
+            connection_.CommitAndRollbackListeners_.remove(this);
         }
-        catch (SqlException sqle) {
-          sqlException = Utils.accumulateSQLException (sqle, sqlException);
+
+        flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed();
+        if (statement_.openOnClient_ && statement_.isCatalogQuery_) {
+            statement_.closeX();
         }
-        if (sqlException != null)
-          throw sqlException;
-      }
-    }
-
-    // for scrollable ResultSet's,
-    // if the "next" request is still fetching within the current rowset,
-    //   update column info from cache and increment the current row index
-    // else
-    //   fetch the next rowset from the server
-    else {
-
-      // These flags will only be used for dynamic cursors where we don't know the row count
-      // and can't keep track of the absolute position of the cursor.
-      isAfterLast_ = false;
-      isLast_ = false;
-
-      // if the next row is still within the current rowset
-      if (rowIsInCurrentRowset (firstRowInRowset_+currentRowInRowset_+1, scrollOrientation_next__)) {
-        isValidCursorPosition_ = true;
-        currentRowInRowset_++;
-      }
-      else {
-        checkAndThrowReceivedQueryTerminatingException();
-        isValidCursorPosition_ = getNextRowset ();
-      }
 
-      if (isValidCursorPosition_) {
-        updateColumnInfoFromCache ();
-        // check if there is a non-null SQLCA for the current row for rowset cursors
-        checkRowsetSqlca ();
-        if (isBeforeFirst_) isFirst_ = true;
-        isBeforeFirst_ = false;
-      }
-      else {
-        isFirst_ = false;
-        return isValidCursorPosition_;
-      }
+        nullDataForGC();
     }
 
-    // for forward-only cursors, check if rowsRead_ > maxRows_.
-    // for scrollable cursors, check if absolute row number > maxRows_.
-    // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
-    if (!openOnClient_) {
-      isValidCursorPosition_ = false;
-    }
-    else if (sensitivity_ != sensitivity_sensitive_dynamic__  && statement_.maxRows_ > 0 &&
-             (firstRowInRowset_+currentRowInRowset_ > statement_.maxRows_)) {
-      isValidCursorPosition_ = false;
-    }
-    return isValidCursorPosition_;
-  }
-
-
-  public void close () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "close");
-      closeX();
-    }
-  }
-
-  // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
-  // that we later check to drive a commit.
-  // An untraced version of close()
-  public final void closeX () throws SqlException
-  {
-    if (!openOnClient_) return;
-    try {
-      if (openOnServer_) flowCloseAndAutoCommitIfNotAutoCommitted();
-      else flowAutoCommitIfNotAutoCommitted(); // in case of early close
-    }
-    finally {
-      markClosed();
-      connection_.CommitAndRollbackListeners_.remove (this);
-    }
-
-    flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed ();
-    if (statement_.openOnClient_ && statement_.isCatalogQuery_) statement_.closeX();
-
-    nullDataForGC();
-  }
-
-  public void nullDataForGC()
-  {
-    // This method is called by closeX().  We cannot call this if cursor is cached,
-    // otherwise it will cause NullPointerException's when cursor is reused.
-    // Cursor is only cached for PreparedStatement's.
-    if (cursor_ != null && !statement_.isPreparedStatement_)
-      cursor_.nullDataForGC();
-    cursor_ = null;
-    resultSetMetaData_ = null;
-  }
-
-  void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
-  {
-    agent_.beginWriteChain (statement_);
-    writeCloseAndAutoCommitIfNotAutoCommitted();
-    agent_.flow (statement_);
-    readCloseAndAutoCommitIfNotAutoCommitted();
-    agent_.endReadChain();
-  }
-
-  private void writeCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
-  {
-    // set autoCommitted_ to false so commit will flow following
-    // close cursor if autoCommit is true.
-    autoCommitted_ = false;
-    if (generatedSection_ == null) { // none call statement result set case
-      writeCursorClose_ (statement_.section_);
-      writeAutoCommitIfNotAutoCommitted();
-    }
-    else { // call statement result set(s) case
-      writeCursorClose_ (generatedSection_);
-    }
-  }
-
-  private void readCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
-  {
-    if (generatedSection_ == null) { // none call statement result set case
-      readCursorClose_ ();
-      readAutoCommitIfNotAutoCommitted();
-    }
-    else { // call statement result set(s) case
-      readCursorClose_ ();
-    }
-  }
-
-  void writeClose() throws SqlException
-  {
-    // set autoCommitted_ to false so commit will flow following
-    // close cursor if autoCommit is true.
-    autoCommitted_ = false;
-    if (generatedSection_ == null) { // none call statement result set case
-      writeCursorClose_ (statement_.section_);
-    }
-    else { // call statement result set(s) case
-      writeCursorClose_ (generatedSection_);
-    }
-  }
-
-  void readClose() throws SqlException
-  {
-    try {
-      if (generatedSection_ == null) { // none call statement result set case
-        readCursorClose_ ();
-      }
-      else { // call statement result set(s) case
-        readCursorClose_ ();
-      }
-    }
-    finally {
-      markClosed();
-    }
-  }
-
-  void flowAutoCommitIfNotAutoCommitted () throws SqlException
-  {
-    if (generatedSection_ == null && connection_.autoCommit_ && !autoCommitted_)  {
-      connection_.flowAutoCommit ();
-      markAutoCommitted();
-    }
-  }
-
-  // precondition: transaction state allows for auto commit to generate flow
-  private void writeAutoCommitIfNotAutoCommitted () throws SqlException
-  {
-    if (connection_.autoCommit_ && !autoCommitted_)  connection_.writeAutoCommit ();
-  }
-
-  private void readAutoCommitIfNotAutoCommitted () throws SqlException
-  {
-    if (connection_.autoCommit_ && !autoCommitted_) {
-      connection_.readAutoCommit ();
-      markAutoCommitted();
-    }
-  }
-
-  private void flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed () throws SqlException
-  {
-    // After this call, the generatedSection_ is reset to null to avoid repeating the commit.
-    if (generatedSection_ != null && statement_ != null && statement_.resultSetList_ != null ) {
-      int count = 0;
-      for (int i = 0; i < statement_.resultSetList_.length; i++) {
-        if (statement_.resultSetList_[i] == null) {
-          count++;
+    public void nullDataForGC() {
+        // This method is called by closeX().  We cannot call this if cursor is cached,
+        // otherwise it will cause NullPointerException's when cursor is reused.
+        // Cursor is only cached for PreparedStatement's.
+        if (cursor_ != null && !statement_.isPreparedStatement_) {
+            cursor_.nullDataForGC();
         }
-      }
-      if (count == statement_.resultSetList_.length) {
-        if (connection_.autoCommit_ && !autoCommitted_) {
-          connection_.flowAutoCommit();
-          markAutoCommitted();
+        cursor_ = null;
+        resultSetMetaData_ = null;
+    }
+
+    void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+        agent_.beginWriteChain(statement_);
+        writeCloseAndAutoCommitIfNotAutoCommitted();
+        agent_.flow(statement_);
+        readCloseAndAutoCommitIfNotAutoCommitted();
+        agent_.endReadChain();
+    }
+
+    private void writeCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+        // set autoCommitted_ to false so commit will flow following
+        // close cursor if autoCommit is true.
+        autoCommitted_ = false;
+        if (generatedSection_ == null) { // none call statement result set case
+            writeCursorClose_(statement_.section_);
+            writeAutoCommitIfNotAutoCommitted();
+        } else { // call statement result set(s) case
+            writeCursorClose_(generatedSection_);
         }
-      }
     }
-    generatedSection_ = null; // this is prevent a subsequent close() call from doing another autocommit.
-  }
 
-  public boolean wasNull () throws SqlException
-  {
-
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "wasNull");
-    checkForClosedResultSet ();
-
-    if (wasNull_ == ResultSet.WAS_NULL_UNSET)
-      throw new SqlException (agent_.logWriter_, "Invalid operation: wasNull() called with no data retrieved");
-
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "wasNull", wasNull_ == ResultSet.WAS_NULL);
-    return wasNull_ == ResultSet.WAS_NULL;
-  }
-
-  //------------------- getters on column index --------------------------------
-
-  // Live life on the edge and run unsynchronized
-  public boolean getBoolean (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBoolean", column);
-      checkGetterPreconditions (column);
-      boolean result = false;
-      if (wasNonNullSensitiveUpdate (column))
-        result = agent_.crossConverters_.setBooleanFromObject (updatedColumns_[column-1],
-                                                               resultSetMetaData_.types_[column-1]);
-      else
-        result = isNull (column) ? false : cursor_.getBoolean (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBoolean", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public byte getByte (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getByte", column);
-      checkGetterPreconditions (column);
-      byte result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = agent_.crossConverters_.setByteFromObject (updatedColumns_[column-1],
-                                                                    resultSetMetaData_.types_[column-1]);
-      else
-        result = isNull (column) ? 0 : cursor_.getByte (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getByte", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public short getShort (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getShort", column);
-      checkGetterPreconditions (column);
-      short result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = ((Short) agent_.crossConverters_.setObject (java.sql.Types.SMALLINT,
-                                                            updatedColumns_[column-1])).shortValue();
-      else
-        result = isNull (column) ? 0 : cursor_.getShort (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getShort", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public int getInt (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getInt", column);
-      checkGetterPreconditions (column);
-      int result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = ((Integer) agent_.crossConverters_.setObject (java.sql.Types.INTEGER,
-                                                              updatedColumns_[column-1])).intValue();
-      else
-        result = isNull (column) ? 0 : cursor_.getInt (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getInt", result);
-      setWasNull (column); // this is placed here close to the return to minimize risk of race condition.
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public long getLong (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getLong", column);
-      checkGetterPreconditions (column);
-      long result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = ((Long) agent_.crossConverters_.setObject (java.sql.Types.BIGINT,
-                                                            updatedColumns_[column-1])).longValue();
-      else
-        result = isNull (column) ? 0 : cursor_.getLong (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getLong", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public float getFloat (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getFloat", column);
-      checkGetterPreconditions (column);
-      float result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = ((Float) agent_.crossConverters_.setObject (java.sql.Types.REAL,
-                                                             updatedColumns_[column-1])).floatValue();
-      else
-        result = isNull (column) ? 0 : cursor_.getFloat (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFloat", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public double getDouble (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDouble", column);
-      checkGetterPreconditions (column);
-      double result = 0;
-      if (wasNonNullSensitiveUpdate (column))
-        result = ((Double) agent_.crossConverters_.setObject (java.sql.Types.DOUBLE,
-                                                              updatedColumns_[column-1])).doubleValue();
-      else
-        result = isNull (column) ? 0 : cursor_.getDouble (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDouble", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.math.BigDecimal getBigDecimal (int column, int scale) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getBigDecimal", column, scale);
-      checkGetterPreconditions (column);
-      java.math.BigDecimal result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result =
-          ((java.math.BigDecimal)agent_.crossConverters_.setObject (java.sql.Types.DECIMAL,
-                                                                    updatedColumns_[column-1])).setScale (scale, java.math.BigDecimal.ROUND_DOWN);
-      else
-        result =
-          isNull (column) ? null : cursor_.getBigDecimal (column).setScale (scale, java.math.BigDecimal.ROUND_DOWN);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedExit (this, "getBigDecimal", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.math.BigDecimal getBigDecimal (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBigDecimal", column);
-      checkGetterPreconditions (column);
-      java.math.BigDecimal result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result =
-          (java.math.BigDecimal)agent_.crossConverters_.setObject (java.sql.Types.DECIMAL,
-                                                                   updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getBigDecimal (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBigDecimal", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Date getDate (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", column);
-      checkGetterPreconditions (column);
-      java.sql.Date result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (java.sql.Date) agent_.crossConverters_.setObject (java.sql.Types.DATE, updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getDate (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDate", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Date getDate (int column, java.util.Calendar calendar) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", column, calendar);
-      if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
-      java.sql.Date date = getDate (column);
-      if (date != null) {
-        java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-        targetCalendar.clear();
-        targetCalendar.setTime(date);
-        java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-        defaultCalendar.clear();
-        defaultCalendar.setTime(date);
-        long timeZoneOffset =
-          targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
-          targetCalendar.get(java.util.Calendar.DST_OFFSET)  - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-        date.setTime (date.getTime() - timeZoneOffset);
-      }
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDate", date);
-      return date;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Time getTime (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", column);
-      checkGetterPreconditions (column);
-      java.sql.Time result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (java.sql.Time) agent_.crossConverters_.setObject (java.sql.Types.TIME, updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getTime (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTime", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Time getTime (int column, java.util.Calendar calendar) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", column, calendar);
-      if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
-      java.sql.Time time = getTime (column);
-      if (time != null) {
-        java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-        targetCalendar.clear();
-        targetCalendar.setTime(time);
-        java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-        defaultCalendar.clear();
-        defaultCalendar.setTime(time);
-        long timeZoneOffset =
-          targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
-          targetCalendar.get(java.util.Calendar.DST_OFFSET)  - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-        time.setTime (time.getTime() - timeZoneOffset);
-      }
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTime", time);
-      return time;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Timestamp getTimestamp (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", column);
-      checkGetterPreconditions (column);
-      java.sql.Timestamp result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (java.sql.Timestamp) agent_.crossConverters_.setObject (java.sql.Types.TIMESTAMP, updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getTimestamp (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTimestamp", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Timestamp getTimestamp (int column, java.util.Calendar calendar) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", column, calendar);
-      if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
-      java.sql.Timestamp timestamp = getTimestamp (column);
-      if (timestamp != null) {
-        int nano = timestamp.getNanos();
-        java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-        targetCalendar.clear();
-        targetCalendar.setTime(timestamp);
-        java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-        defaultCalendar.clear();
-        defaultCalendar.setTime(timestamp);
-        long timeZoneOffset =
-          targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
-          targetCalendar.get(java.util.Calendar.DST_OFFSET)  - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-        timestamp.setTime (timestamp.getTime() - timeZoneOffset);
-        timestamp.setNanos (nano);
-      }
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTimestamp", timestamp);
-      return timestamp;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public String getString (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getString", column);
-      checkGetterPreconditions (column);
-      String result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (String) agent_.crossConverters_.setObject (java.sql.Types.CHAR, updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getString (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getString", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public byte[] getBytes (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBytes", column);
-      checkGetterPreconditions (column);
-      byte[] result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (byte[]) agent_.crossConverters_.setObject (java.sql.Types.BINARY, updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getBytes (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBytes", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.io.InputStream getBinaryStream (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBinaryStream", column);
-      checkGetterPreconditions (column);
-      java.io.InputStream result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = new java.io.ByteArrayInputStream (
-          (byte[]) agent_.crossConverters_.setObject (java.sql.Types.BINARY, updatedColumns_[column-1]));
-      else
-        result = isNull (column) ? null : cursor_.getBinaryStream (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBinaryStream", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.io.InputStream getAsciiStream (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getAsciiStream", column);
-      checkGetterPreconditions (column);
-      java.io.InputStream result = null;
-      if (wasNonNullSensitiveUpdate (column)) {
-        try {
-          result = new java.io.ByteArrayInputStream
-            (((String) agent_.crossConverters_.setObject (java.sql.Types.CHAR,
-                                                         updatedColumns_[column-1])).getBytes ("US-ASCII"));
-        }
-        catch (java.io.UnsupportedEncodingException e) {
-          throw new SqlException (agent_.logWriter_, e, e.getMessage());
-        }
-      }
-      else
-        result = isNull (column) ? null : cursor_.getAsciiStream (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getAsciiStream", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.io.InputStream getUnicodeStream (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getUnicodeStream", column);
-      checkGetterPreconditions (column);
-      java.io.InputStream result = null;
-      if (wasNonNullSensitiveUpdate (column)) {
+    private void readCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+        if (generatedSection_ == null) { // none call statement result set case
+            readCursorClose_();
+            readAutoCommitIfNotAutoCommitted();
+        } else { // call statement result set(s) case
+            readCursorClose_();
+        }
+    }
+
+    void writeClose() throws SqlException {
+        // set autoCommitted_ to false so commit will flow following
+        // close cursor if autoCommit is true.
+        autoCommitted_ = false;
+        if (generatedSection_ == null) { // none call statement result set case
+            writeCursorClose_(statement_.section_);
+        } else { // call statement result set(s) case
+            writeCursorClose_(generatedSection_);
+        }
+    }
+
+    void readClose() throws SqlException {
         try {
-          result = new java.io.ByteArrayInputStream
-            (((String)agent_.crossConverters_.setObject (java.sql.Types.CHAR,
-                                                         updatedColumns_[column-1])).getBytes("UTF-8"));
-        }
-        catch (java.io.UnsupportedEncodingException e) {
-          throw new SqlException (agent_.logWriter_, e, e.getMessage());
-        }
-      }
-      else
-        result = isNull (column) ? null : cursor_.getUnicodeStream (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedExit (this, "getUnicodeStream", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.io.Reader getCharacterStream (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCharacterStream", column);
-      checkGetterPreconditions (column);
-      java.io.Reader result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = new java.io.StringReader
-         ((String)agent_.crossConverters_.setObject (java.sql.Types.CHAR, updatedColumns_[column-1]));
-      else
-        result = isNull (column) ? null : cursor_.getCharacterStream (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getCharacterStream", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Blob getBlob (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBlob", column);
-      checkGetterPreconditions (column);
-      java.sql.Blob result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (java.sql.Blob)agent_.crossConverters_.setObject (java.sql.Types.BLOB,
-                                                                   updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getBlob (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBlob", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Clob getClob (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getClob", column);
-      checkGetterPreconditions (column);
-      java.sql.Clob result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = (java.sql.Clob) agent_.crossConverters_.setObject (java.sql.Types.CLOB,
-                                                                   updatedColumns_[column-1]);
-      else
-        result = isNull (column) ? null : cursor_.getClob (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getClob", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Ref getRef (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRef", column);
-      checkGetterPreconditions (column);
-      java.sql.Ref result = isNull (column) ? null : cursor_.getRef (column);
-      if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getRef", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public java.sql.Array getArray (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getArray", column);
-      checkGetterPreconditions (column);
-      java.sql.Array result = isNull (column) ? null : cursor_.getArray (column);
-      if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getArray", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public Object getObject (int column) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", column);
-      Object result = getObjectX (column);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getObject", result);
-      return result;
-  }
-
-  // used by DBMD
-  Object getObjectX (int column) throws SqlException
-  {
-      checkGetterPreconditions (column);
-      Object result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = updatedColumns_[column-1];
-      else
-        result = isNull (column) ? null : cursor_.getObject (column);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  // Live life on the edge and run unsynchronized
-  public Object getObject (int column, java.util.Map map) throws SqlException
-  {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", column, map);
-      checkGetterPreconditions (column);
-      Object result = null;
-      if (wasNonNullSensitiveUpdate (column))
-        result = updatedColumns_[column-1];
-      else
-        result = isNull (column) ? null : cursor_.getObject (column);
-      if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getObject", result);
-      setWasNull (column);  // Placed close to the return to minimize risk of thread interference
-      return result;
-  }
-
-  //----------------------------------------------------------------------------
-
-  // This method only returns true if there is a new non-null updated value.
-  // If the resultset is updatable, sensitive, and updated, return the new non-null updated value.
-  // Otherwise this method will return false.
-  // If the column is updated to null, or if the column has not been update but is null,
-  // a null will be returned by isNull(), which first calls wasNullSensitiveUpdate() to check for a column
-  // that is updated to null, and columnUpdated_ is checked there.
-  private boolean wasNonNullSensitiveUpdate (int column)
-  {
-    return
-      updatedColumns_ != null &&
-      updatedColumns_[column-1] != null;
-  }
-
-  // if updatedColumns_ entry is null, but columnUpdated_ entry
-  // indicates column has been updated, then column is updated to null.
-  private boolean wasNullSensitiveUpdate (int column)
-  {
-    return
-      resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE &&
-      updatedColumns_ != null &&
-      updatedColumns_[column-1] == null &&
-      columnUpdated_[column-1];
-  }
-
-  private void setWasNull (int column)
-  {
-    if (wasNullSensitiveUpdate (column))
-      wasNull_ = WAS_NULL;
-    else
-      wasNull_ = (cursor_.isNull_ == null || cursor_.isNull_[column-1]) ? WAS_NULL : WAS_NOT_NULL ;
-  }
-
-  private boolean isNull (int column)
-  {
-    if (wasNullSensitiveUpdate (column))
-      return true;
-    else
-      return (cursor_.isUpdateDeleteHole_ == true || cursor_.isNull_[column-1]);
-  }
-
-  // ------------- Methods for accessing results by column name ----------------
-
-  public final boolean getBoolean (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBoolean", columnName);
-    return getBoolean (findColumnX (columnName));
-  }
-
-  public final byte getByte (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getByte", columnName);
-    return getByte (findColumnX (columnName));
-  }
-
-  public final short getShort (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getShort", columnName);
-    return getShort (findColumnX (columnName));
-  }
-
-  public final int getInt (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getInt", columnName);
-    return getInt (findColumnX (columnName));
-  }
-
-  public final long getLong (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getLong", columnName);
-    return getLong (findColumnX (columnName));
-  }
-
-  public final float getFloat (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getFloat", columnName);
-    return getFloat (findColumnX (columnName));
-  }
-
-  public final double getDouble (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDouble", columnName);
-    return getDouble (findColumnX (columnName));
-  }
-
-  public final java.math.BigDecimal getBigDecimal (String columnName, int scale) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getBigDecimal", columnName, scale);
-    return getBigDecimal (findColumnX (columnName), scale);
-  }
-
-  public final java.math.BigDecimal getBigDecimal (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBigDecimal", columnName);
-    return getBigDecimal (findColumnX (columnName));
-  }
-
-  public final java.sql.Date getDate (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", columnName);
-    return getDate (findColumnX (columnName));
-  }
-
-  public final java.sql.Date getDate (String columnName, java.util.Calendar cal) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", columnName, cal);
-    return getDate (findColumnX (columnName), cal);
-  }
-
-  public final java.sql.Time getTime (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", columnName);
-    return getTime (findColumnX (columnName));
-  }
-
-  public final java.sql.Time getTime (String columnName, java.util.Calendar cal) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", columnName, cal);
-    return getTime (findColumnX (columnName), cal);
-  }
-
-  public final java.sql.Timestamp getTimestamp (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", columnName);
-    return getTimestamp (findColumnX (columnName));
-  }
-
-  public final java.sql.Timestamp getTimestamp (String columnName, java.util.Calendar cal) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", columnName, cal);
-    return getTimestamp (findColumnX (columnName), cal);
-  }
-
-  public final String getString (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getString", columnName);
-    return getString (findColumnX (columnName));
-  }
-
-  public final byte[] getBytes (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBytes", columnName);
-    return getBytes (findColumnX (columnName));
-  }
-
-  public final java.io.InputStream getBinaryStream (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBinaryStream", columnName);
-    return getBinaryStream (findColumnX (columnName));
-  }
-
-  public final java.io.InputStream getAsciiStream (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getAsciiStream", columnName);
-    return getAsciiStream (findColumnX (columnName));
-  }
-
-  public final java.io.InputStream getUnicodeStream (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getUnicodeStream", columnName);
-    return getUnicodeStream (findColumnX (columnName));
-  }
-
-  public final java.io.Reader getCharacterStream (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCharacterStream", columnName);
-    return getCharacterStream (findColumnX (columnName));
-  }
-
-  public final java.sql.Blob getBlob (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBlob", columnName);
-    return getBlob (findColumnX (columnName));
-  }
-
-  public final java.sql.Clob getClob (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getClob", columnName);
-    return getClob (findColumnX (columnName));
-  }
-
-  public final java.sql.Array getArray (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getArray", columnName);
-    return getArray (findColumnX (columnName));
-  }
-
-  public final java.sql.Ref getRef (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRef", columnName);
-    return getRef (findColumnX (columnName));
-  }
-
-  public final Object getObject (String columnName) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", columnName);
-    return getObject (findColumnX (columnName));
-  }
-
-  public final Object getObject (String columnName, java.util.Map map) throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", columnName, map);
-    return getObject (findColumnX (columnName), map);
-  }
-
-  // ----------------Advanced features -----------------------------------------
-
-  public final java.sql.SQLWarning getWarnings ()
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getWarnings", warnings_);
-    return warnings_;
-  }
-
-  public final void clearWarnings () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "clearWarnings");
-      warnings_ = null;
-    }
-  }
-
-  // An untraced version of clearWarnings()
-  public final void clearWarningsX ()
-  {
-    warnings_ = null;
-  }
-
-  public String getCursorName () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCursorName");
-      checkForClosedResultSet();
-      if (generatedSection_ != null)
-        return "stored procedure generated cursor:" + generatedSection_.getServerCursorName();
-      if (statement_.cursorName_ == null) {// cursor name is not in the maps yet.
-        statement_.cursorName_ = statement_.section_.getServerCursorName ();
-        if (statement_.section_ instanceof Section)
-          agent_.sectionManager_.mapCursorNameToQuerySection (statement_.cursorName_,
-                                                              (Section) statement_.section_);
-      }
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getCursorName", statement_.cursorName_);
-      return statement_.cursorName_;
-    }
-  }
-
-  public java.sql.ResultSetMetaData getMetaData () throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getMetaData");
-    java.sql.ResultSetMetaData resultSetMetaData = getMetaDataX();
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getMetaData", resultSetMetaData);
-    return resultSetMetaData;
-  }
-
-  // used by DBMD
-  ColumnMetaData getMetaDataX () throws SqlException
-  {
-    checkForClosedResultSet ();
-    return resultSetMetaData_;
-  }
-
-
-  public final int findColumn (String columnName) throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "findColumn", columnName);
-      int column = findColumnX (columnName);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "findColumn", column);
-      return column;
-    }
-  }
-
-  // An untraced version of findColumn()
-  private final int findColumnX (String columnName) throws SqlException
-  {
-    checkForClosedResultSet ();
-    return resultSetMetaData_.findColumnX(columnName);
-  }
-
-  //-------------------------- Traversal/Positioning ---------------------------
-
-  public boolean isBeforeFirst () throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isBeforeFirst");
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    // Returns false if the ResultSet contains no rows.
-    boolean isBeforeFirst = isBeforeFirstX ();
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isBeforeFirst", isBeforeFirst);
-    return isBeforeFirst;
-  }
-
-  private boolean isBeforeFirstX () throws SqlException
-  {
-    if (sensitivity_ == sensitivity_sensitive_dynamic__)
-      return isBeforeFirst_;
-    else
-      //return ((resultSetContainsNoRows()) ? false : (currentRowInRowset_ == -1));
-      return ((currentRowInRowset_ == -1) && !resultSetContainsNoRows());
-  }
-
-  public boolean isAfterLast () throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isAfterLast");
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    // Returns false if the ResultSet contains no rows.
-    boolean isAfterLast = isAfterLastX ();
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isAfterLast", isAfterLast);
-    return isAfterLast;
-  }
-
-  private boolean isAfterLastX () throws SqlException
-  {
-    if (sensitivity_ == sensitivity_sensitive_dynamic__)
-      return isAfterLast_;
-    else
-      return (resultSetContainsNoRows() ? false :
-            (firstRowInRowset_ == currentRowInRowset_ &&
-            currentRowInRowset_ == lastRowInRowset_ &&
-            lastRowInRowset_ == 0 &&
-            absolutePosition_ == rowCount_ + 1));
-  }
-
-  public boolean isFirst () throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isFirst");
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    // Not necessary to get the rowCount_ since currentRowInRowset_ is initialized to -1,
-    // and it will not be changed if there is no rows in the ResultSet.
-    boolean isFirst = isFirstX ();
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isFirst", isFirst);
-    return isFirst;
-  }
-
-  private boolean isFirstX ()
-  {
-    if (sensitivity_ == sensitivity_sensitive_dynamic__) return isFirst_;
-    return (firstRowInRowset_ == 1 && currentRowInRowset_ == 0);
-  }
-
-  public boolean isLast () throws SqlException
-  {
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isLast");
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    // Returns false if the ResultSet contains no rows.
-    boolean isLast = isLastX ();
-    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isLast", isLast);
-    return isLast;
-  }
-
-  private boolean isLastX () throws SqlException
-  {
-    if (sensitivity_ == sensitivity_sensitive_dynamic__)
-      return isLast_;
-    else
-      return (resultSetContainsNoRows() ? false :
-              (firstRowInRowset_ + currentRowInRowset_) == rowCount_);
-  }
-
-  public void beforeFirst () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "beforeFirst");
-      checkForClosedResultSet();
-      checkThatResultSetTypeIsScrollable();
-      clearWarningsX();
-      beforeFirstX();
-    }
-  }
-
-  private void beforeFirstX () throws SqlException
-  {
-    resetRowsetFlags ();
-
-    // this method has no effect if the result set has no rows.
-    // only send cntqry to position the cursor before first if
-    // resultset contains rows and it is not already before first, or
-    // if the cursor is a dynamic cursor.
-    if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
-        (!resultSetContainsNoRows() && !isServersCursorPositionBeforeFirst())) {
-      moveToBeforeFirst();
-    }
-      isBeforeFirst_ = true;
-      setRowsetBeforeFirstEvent();
-      cursor_.resetDataBuffer();
-      resetRowsetSqlca();
-    isValidCursorPosition_ = false;
-  }
-
-  public void afterLast () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "afterLast");
-      checkForClosedResultSet ();
-      checkThatResultSetTypeIsScrollable();
-      clearWarningsX ();
-      afterLastX();
-    }
-  }
-
-  private void afterLastX () throws SqlException
-  {
-    resetRowsetFlags ();
-
-    // this method has no effect if the result set has no rows.
-    // only send cntqry to position the cursor after last if
-    // resultset contains rows and it is not already after last, or
-    // if the cursor is a dynamic cursor.
-    if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
-        (!resultSetContainsNoRows() && !isServerCursorPositionAfterLast())) {
-      moveToAfterLast();
-    }
-      isAfterLast_ = true;
-      setRowsetAfterLastEvent();
-      cursor_.resetDataBuffer();
-      resetRowsetSqlca();
-    isValidCursorPosition_ = false;
-  }
-
-  public boolean first () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "first");
-      boolean isValidCursorPosition = firstX();
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "first", isValidCursorPosition);
-      return isValidCursorPosition;
-    }
-  }
-
-  private boolean firstX () throws SqlException
-  {
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    clearWarningsX ();
-
-    wasNull_ = ResultSet.WAS_NULL_UNSET;
-
-    // discard all previous updates when moving the cursor
-    resetUpdatedColumns ();
-
-    resetRowsetFlags ();
-
-    // if first row is not in the current rowset, fetch the first rowset from the server.
-    // rowIsInCurrentRowset with orientation first will always return false for dynamic cursors.
-    if (rowIsInCurrentRowset(1, scrollOrientation_first__)) {
-      isValidCursorPosition_ = true;
-      currentRowInRowset_ = 0;
-    }
-    else {
-      checkAndThrowReceivedQueryTerminatingException();
-      isValidCursorPosition_ = getFirstRowset ();
-    }
-
-    if (isValidCursorPosition_) {
-      updateColumnInfoFromCache ();
-      isFirst_ = true;
-      // check if there is a non-null SQLCA for the row for rowset cursors
-      checkRowsetSqlca ();
-    }
-
-    return isValidCursorPosition_;
-  }
-
-  public boolean last () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "last");
-      boolean isValidCursorPosition = lastX();
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "last", isValidCursorPosition);
-      return isValidCursorPosition;
-    }
-  }
-
-  private boolean lastX () throws SqlException
-  {
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    clearWarningsX ();
-
-    wasNull_ = ResultSet.WAS_NULL_UNSET;
-
-    // discard all previous updates when moving the cursor
-    resetUpdatedColumns ();
-
-    resetRowsetFlags();
-
-    // only get the rowCount for static cursors.
-    if (rowCountIsUnknown()) getRowCount();
-    long row = rowCount_;
-    if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0) {
-      if (rowCount_ > statement_.maxRows_)
-        row = statement_.maxRows_;
-    }
-
-    // rowIsInCurrentRowset with orientation last will always return false for dynamic cursors.
-    if (rowIsInCurrentRowset (row, scrollOrientation_last__)) {
-      isValidCursorPosition_ = true;
-      currentRowInRowset_ = row - firstRowInRowset_;
-    }
-    else {
-      checkAndThrowReceivedQueryTerminatingException();
-      isValidCursorPosition_ = getLastRowset (row);
-    }
-
-    if (isValidCursorPosition_) {
-      updateColumnInfoFromCache ();
-      isLast_ = true;
-      // check if there is a non-null SQLCA for the current row for rowset cursors
-      checkRowsetSqlca ();
-    }
-
-    return isValidCursorPosition_;
-  }
-
-  public int getRow () throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRow");
-      int row = getRowX();
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getRow", row);
-      return row;
-    }
-  }
-
-  private int getRowX () throws SqlException
-  {
-    checkForClosedResultSet ();
-    long row;
-    checkThatResultSetIsNotDynamic ();
-    if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
-      // for forward-only cursors, getRow() should return 0 if cursor is not on a valid row,
-      // i.e. afterlast.
-      row = (cursor_.allRowsReceivedFromServer_ &&
-             cursor_.currentRowPositionIsEqualToNextRowPosition ()) ? 0 : cursor_.rowsRead_;
-    else {
-      if (rowCountIsUnknown()) {
-        // commented out here because the following method is called the first thing
-        // inside getRowCount();
-        //checkAndThrowReceivedQueryTerminatingException();
-        getRowCount();
-      }
-      if (rowCount_ == 0 || currentRowInRowset_ < 0) // || currentRowInRowset_ > rowCount_)
-        row = 0;
-      else
-        row = firstRowInRowset_ + currentRowInRowset_;
-    }
-    if (row > Integer.MAX_VALUE)
-      this.accumulateWarning (new SqlWarning (agent_.logWriter_, "Value too large to fit in an int."));
-    return (int)row;
-  }
-
-  public boolean absolute (int row) throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "absolute", row);
-      boolean isValidCursorPosition = absoluteX (row);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "absolute", isValidCursorPosition);
-      return isValidCursorPosition;
-    }
-  }
-
-  public boolean absoluteX (int row) throws SqlException
-  {
-    checkForClosedResultSet();
-    checkThatResultSetTypeIsScrollable();
-    clearWarningsX();
-
-    wasNull_ = ResultSet.WAS_NULL_UNSET;
-
-    // discard all previous updates when moving the cursor.
-    resetUpdatedColumns ();
-
-    resetRowsetFlags ();
-
-    if (statement_.maxRows_ > 0) {
-      // if "row" is positive and > maxRows, fetch afterLast
-      // else if "row" is negative, and abs(row) > maxRows, fetch beforeFirst
-      if (row > 0 && row > statement_.maxRows_) {
-        afterLastX();
-        isValidCursorPosition_ = false;
-        return isValidCursorPosition_;
-      }
-      else if (row <= 0 && java.lang.Math.abs(row) > statement_.maxRows_) {
-        beforeFirstX();
-        isValidCursorPosition_ = false;
-        return isValidCursorPosition_;
-      }
+            if (generatedSection_ == null) { // none call statement result set case
+                readCursorClose_();
+            } else { // call statement result set(s) case
+                readCursorClose_();
+            }
+        } finally {
+            markClosed();
+        }
     }
 
-    int fetchAbsoluteRow = 0;
-    if (rowCountIsUnknown()) getRowCount();
-    if (sensitivity_ == sensitivity_sensitive_dynamic__)
-      fetchAbsoluteRow = row;
-    else
-      // calculate the positive absolute row number based on rowCount for static or insensitive cursors.
-      fetchAbsoluteRow = (row >= 0) ? row : (int)(rowCount_ + row + 1);
-
-    // rowIsInCurrentRowset with orientation absolute will always return false for dynamic cursors.
-    if (rowIsInCurrentRowset (fetchAbsoluteRow, scrollOrientation_absolute__)) {
-      isValidCursorPosition_ = true;
-      currentRowInRowset_ = fetchAbsoluteRow - firstRowInRowset_;
-    }
-    else {
-      checkAndThrowReceivedQueryTerminatingException();
-      isValidCursorPosition_ = getAbsoluteRowset (fetchAbsoluteRow);
-    }
-
-    if (isValidCursorPosition_) {
-      updateColumnInfoFromCache ();
-      if (row == 1) isFirst_ = true;
-      if (row == -1) isLast_ = true;
-      // check if there is a non-null SQLCA for the row for rowset cursors
-      checkRowsetSqlca ();
-    }
-
-    return isValidCursorPosition_;
-  }
-
-  public boolean relative (int rows) throws SqlException
-  {
-    synchronized (connection_) {
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "relative", rows);
-      boolean isValidCursorPosition = relativeX (rows);
-      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "relative", isValidCursorPosition);
-      return isValidCursorPosition;
-    }
-  }
-
-  private boolean relativeX (int rows) throws SqlException
-  {
-    checkForClosedResultSet ();
-    checkThatResultSetTypeIsScrollable();
-    clearWarningsX ();
-    wasNull_ = ResultSet.WAS_NULL_UNSET;
-
-    // discard all previous updates when moving the cursor.
-    resetUpdatedColumns ();
-
-    // this method may only be called when the cursor on a valid row,
-    // not after the last row, before the first row, or on the insert row.
-    // throw exception if result set contains no rows, because there is no current row.
-    if (isBeforeFirstX() || isAfterLastX() || isOnInsertRow_ || resultSetContainsNoRows())
-      throw new SqlException (agent_.logWriter_, "Cursor is Not on a Valid Row");
-
-    if (rows == 0) {
-      isValidCursorPosition_ = true;
-      return isValidCursorPosition_;
-    }
-
-    resetRowsetFlags ();
-
-    // currentAbsoluteRowNumber is used for static cursors only.
-    long currentAbsoluteRowNumber = firstRowInRowset_ + currentRowInRowset_;
-
-    // if "rows" is positive, and currentRow+rows > maxRows, fetch afterLast.
-    // if "rows" is negative, and if the absolute value of "rows" is greater than
-    // the currentrow number, will fetch beforeFirst anyways.  do not need to check
-    // for maxRows.
-    if (sensitivity_ != sensitivity_sensitive_dynamic__ &&
-        statement_.maxRows_ > 0 && rows > 0 && currentAbsoluteRowNumber+rows > statement_.maxRows_) {
-        afterLastX();
-        isValidCursorPosition_ = false;
-        return isValidCursorPosition_;
-      }

[... 5197 lines stripped ...]