db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From banda...@apache.org
Subject svn commit: r165178 [11/26] - in /incubator/derby/code/trunk: ./ java/client/ java/client/org/ java/client/org/apache/ java/client/org/apache/derby/ java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/client/net/ java/client/org/apache/derby/client/resources/ java/client/org/apache/derby/jdbc/ tools/ant/properties/
Date Thu, 28 Apr 2005 19:05:45 GMT
Added: 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=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,3543 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.ResultSet
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+import org.apache.derby.client.am.Section;
+
+public abstract class ResultSet implements java.sql.ResultSet,
+                                           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------------------------------------------
+
+  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
+//    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 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;
+      }
+    }
+
+    // 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 {
+      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++;
+        }
+      }
+      if (count == statement_.resultSetList_.length) {
+        if (connection_.autoCommit_ && !autoCommitted_) {
+          connection_.flowAutoCommit();
+          markAutoCommitted();
+        }
+      }
+    }
+    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)) {
+        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_;
+      }
+    }
+
+    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_;
+      }
+
+    if (rowIsInCurrentRowset (currentAbsoluteRowNumber+rows, scrollOrientation_relative__)) {
+      currentRowInRowset_ += rows;
+      isValidCursorPosition_ = true;
+    }
+    else {
+      checkAndThrowReceivedQueryTerminatingException();
+      long rowNumber =
+          (sensitivity_ == sensitivity_sensitive_dynamic__) ? currentRowInRowset_+rows :
+          currentAbsoluteRowNumber+rows-absolutePosition_;
+      isValidCursorPosition_ = getRelativeRowset (rowNumber);
+    }
+
+    if (isValidCursorPosition_) {
+      updateColumnInfoFromCache ();
+      // check if there is a non-null SQLCA for the row for rowset cursors
+      checkRowsetSqlca ();
+    }
+
+    return isValidCursorPosition_;
+  }
+
+  public boolean previous () throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "previous");
+      boolean isValidCursorPosition = previousX();
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "previous", isValidCursorPosition);
+      return isValidCursorPosition;
+    }
+  }
+
+  private boolean previousX () throws SqlException
+  {
+    checkForClosedResultSet ();
+    checkThatResultSetTypeIsScrollable();
+    clearWarningsX ();
+
+    wasNull_ = ResultSet.WAS_NULL_UNSET;
+
+    // discard all previous updates when moving the cursor.
+    resetUpdatedColumns ();
+
+    isBeforeFirst_ = false;
+    isFirst_ = false;
+
+    if (rowIsInCurrentRowset (firstRowInRowset_+currentRowInRowset_-1, scrollOrientation_prior__)) {
+      isValidCursorPosition_ = true;
+      currentRowInRowset_--;
+    }
+    else {
+      checkAndThrowReceivedQueryTerminatingException();
+      isValidCursorPosition_ = getPreviousRowset ();
+    }
+
+    if (isValidCursorPosition_) {
+      updateColumnInfoFromCache ();
+      // check if there is a non-null SQLCA for the row for rowset cursors
+      checkRowsetSqlca ();
+      if (isAfterLast_) isLast_ = true;
+      isAfterLast_ = false;
+    }
+    else {
+      return isValidCursorPosition_;
+    }
+
+    if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
+        (firstRowInRowset_+currentRowInRowset_ > statement_.maxRows_))
+      isValidCursorPosition_ = false;
+    // auto-close result set if this is the last row from server and return false
+    return isValidCursorPosition_;
+  }
+
+  public void setFetchDirection (int direction) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setFetchDirection", direction);
+      checkForClosedResultSet ();
+      checkThatResultSetTypeIsScrollable();
+
+      switch (direction) {
+      case java.sql.ResultSet.FETCH_FORWARD:
+      case java.sql.ResultSet.FETCH_REVERSE:
+      case java.sql.ResultSet.FETCH_UNKNOWN:
+        fetchDirection_ = direction;
+        break;
+      default:
+        throw new SqlException (agent_.logWriter_, "Invalid fetch direction " + direction);
+      }
+    }
+  }
+
+  public int getFetchDirection () throws SqlException
+  {
+    checkForClosedResultSet ();
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFetchDirection", fetchDirection_);
+    return fetchDirection_;
+  }
+
+  public void setFetchSize (int rows) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setFetchSize", rows);
+      checkForClosedResultSet ();
+      if (rows < 0 || (statement_.maxRows_ != 0 && rows > statement_.maxRows_))
+        throw new SqlException (agent_.logWriter_, "Invalid fetch size " + rows);
+      setFetchSize_ (rows);
+    }
+  }
+
+  public int getFetchSize () throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFetchSize", fetchSize_);
+    checkForClosedResultSet ();
+    return fetchSize_;
+  }
+
+  public int getType () throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getType", resultSetType_);
+    checkForClosedResultSet ();
+    return resultSetType_;
+  }
+
+  public int getConcurrency () throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getConcurrency", resultSetConcurrency_);
+    checkForClosedResultSet ();
+    return resultSetConcurrency_;
+  }
+
+  //----------------------------- Updates --------------------------------------
+
+  public boolean rowUpdated () throws SqlException
+  {
+    // we cannot tell whether the ResultSet has been updated, so always return false here.
+    boolean rowUpdated = false;
+    checkForClosedResultSet ();
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowUpdated", rowUpdated);
+    return rowUpdated;
+  }
+
+  public boolean rowInserted () throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "rowInserted");
+    checkForClosedResultSet ();
+    if (true) throw new SqlException (agent_.logWriter_, "under construction");
+    boolean rowInserted = false;
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowInserted", rowInserted);
+    return rowInserted;
+  }
+
+  public boolean rowDeleted () throws SqlException
+  {
+    // rowDeleted is visible through a delete hole, (sqlcode +222).
+    // Always return false and do not check the return code for now.
+    boolean rowDeleted = false;
+    checkForClosedResultSet ();
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowDeleted", rowDeleted);
+    return rowDeleted;
+  }
+
+  // --------------------------- update column methods -------------------------
+
+  public void updateNull (int column) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateNull", column);
+      checkUpdatePreconditions (column);
+      if (!resultSetMetaData_.nullable_[column-1])
+        throw new SqlException (agent_.logWriter_, "Invalid operation to update a non-nullable column to null.");
+      updateColumn (column, null);
+    }
+  }
+
+  public void updateBoolean (int column, boolean x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBoolean", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateByte (int column, byte x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateByte", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateShort (int column, short x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateShort", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateInt (int column, int x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateInt", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateLong (int column, long x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateLong", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateFloat (int column, float x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateFloat", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateDouble (int column, double x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDouble", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateBigDecimal (int column, java.math.BigDecimal x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBigDecimal", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateDate (int column, java.sql.Date x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDate", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateTime (int column, java.sql.Time x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTime", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateTimestamp (int column, java.sql.Timestamp x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTimestamp", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateString (int column, String x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateString", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateBytes (int column, byte x[]) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBytes", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateBinaryStream (int column,
+                                  java.io.InputStream x,
+                                  int length) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBinaryStream", column, x, length);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObjectFromBinaryStream (resultSetMetaData_.types_[column-1], x, length));
+    }
+  }
+
+  public void updateAsciiStream (int column,
+                                 java.io.InputStream x,
+                                 int length) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateAsciiStream", column, x, length);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObjectFromCharacterStream (resultSetMetaData_.types_[column-1], x, "US-ASCII", length));
+    }
+  }
+
+  public void updateCharacterStream (int column,
+                                     java.io.Reader x,
+                                     int length) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateCharacterStream", column, x, length);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x, length));
+    }
+  }
+
+  public void updateObject (int column, Object x, int scale) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", column, x, scale);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  public void updateObject (int column, Object x) throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", column, x);
+      checkUpdatePreconditions (column);
+      updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x));
+    }
+  }
+
+  // ---------------------- update on column name methods ----------------------
+
+  public void updateNull (String columnName) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateNull", columnName);
+    updateNull (findColumnX (columnName));
+  }
+
+  public void updateBoolean (String columnName, boolean x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBoolean", columnName, x);
+    updateBoolean (findColumnX (columnName), x);
+  }
+
+  public void updateByte (String columnName, byte x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateByte", columnName, x);
+    updateByte (findColumnX (columnName), x);
+  }
+
+  public void updateShort (String columnName, short x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateShort", columnName, x);
+    updateShort (findColumnX (columnName), x);
+  }
+
+  public void updateInt (String columnName, int x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateInt", columnName, x);
+    updateInt (findColumnX (columnName), x);
+  }
+
+  public void updateLong (String columnName, long x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateLong", columnName, x);
+    updateLong (findColumnX (columnName), x);
+  }
+
+  public void updateFloat (String columnName, float x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateFloat", columnName, x);
+    updateFloat (findColumnX (columnName), x);
+  }
+
+  public void updateDouble (String columnName, double x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDouble", columnName, x);
+    updateDouble (findColumnX (columnName), x);
+  }
+
+  public void updateBigDecimal (String columnName, java.math.BigDecimal x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBigDecimal", columnName, x);
+    updateBigDecimal (findColumnX (columnName), x);
+  }
+
+  public void updateDate (String columnName, java.sql.Date x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDate", columnName, x);
+    updateDate (findColumnX (columnName), x);
+  }
+
+  public void updateTime (String columnName, java.sql.Time x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTime", columnName, x);
+    updateTime (findColumnX (columnName), x);
+  }
+
+  public void updateTimestamp (String columnName, java.sql.Timestamp x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTimestamp", columnName, x);
+    updateTimestamp (findColumnX (columnName), x);
+  }
+
+  public void updateString (String columnName, String x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateString", columnName, x);
+    updateString (findColumnX (columnName), x);
+  }
+
+  public void updateBytes (String columnName, byte x[]) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBytes", columnName, x);
+    updateBytes (findColumnX (columnName), x);
+  }
+
+  public void updateBinaryStream (String columnName,
+                                               java.io.InputStream x,
+                                               int length) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBinaryStream", columnName, x, length);
+    updateBinaryStream (findColumnX (columnName), x, length);
+  }
+
+  public void updateAsciiStream (String columnName,
+                                              java.io.InputStream x,
+                                              int length) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateAsciiStream", columnName, x, length);
+    updateAsciiStream (findColumnX (columnName), x, length);
+  }
+
+  public void updateCharacterStream (String columnName,
+                                                  java.io.Reader x,
+                                                  int length) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateCharacterStream", columnName, x, length);
+    updateCharacterStream (findColumnX (columnName), x, length);
+  }
+
+  public void updateObject (String columnName, Object x, int scale) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", columnName, x, scale);
+    updateObject (findColumnX (columnName), x, scale);
+  }
+
+  public void updateObject (String columnName, Object x) throws SqlException
+  {
+    if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", columnName, x);
+    updateObject (findColumnX (columnName), x);
+  }
+
+  // ---------------------------------------------------------------------------
+
+  public void insertRow () throws SqlException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "insertRow");
+      checkForClosedResultSet ();
+      throw new SqlException (agent_.logWriter_, "Driver not capable: insertRow");
+    }
+  }
+
+  public void updateRow () throws java.sql.SQLException
+  {
+    synchronized (connection_) {
+      if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateRow");
+      updateRowX();
+    }
+  }
+
+  private void updateRowX () throws java.sql.SQLException
+  {
+    checkForClosedResultSet ();
+    if (isOnInsertRow_ || resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY)

[... 1407 lines stripped ...]


Mime
View raw message