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 [10/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/Cursor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java?rev=165585&r1=165584&r2=165585&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java Sun May  1 23:25:59 2005
@@ -23,1131 +23,1054 @@
 // When we calculate column offsets make sure we calculate the correct offsets for double byte charactr5er data
 // length from server is number of chars, not bytes
 // Direct byte-level converters are called directly by this class, cross converters are deferred to the CrossConverters class.
-public abstract class Cursor
-{
-  protected Agent agent_;
-
-  //-----------------------------varchar representations------------------------
-
-  public final static int STRING = 0; 
-  public final static int VARIABLE_STRING = 2;       // uses a 2-byte length indicator
-  public final static int VARIABLE_SHORT_STRING = 1; // aka Pascal L; uses a 1-byte length indicator
-  public final static int NULL_TERMINATED_STRING = 3;
-
-  public final static int BYTES = 4; 
-  public final static int VARIABLE_BYTES = 5;
-  public final static int VARIABLE_SHORT_BYTES = 6;
-  public final static int NULL_TERMINATED_BYTES = 7;
-
-  public final static int SBCS_CLOB = 8;
-  public final static int MBCS_CLOB = 9;
-  public final static int DBCS_CLOB = 10;
-  //-----------------------------internal state---------------------------------
-
-  //-------------Structures for holding and scrolling the data -----------------
-  public byte[] dataBuffer_;
-  public java.io.ByteArrayOutputStream dataBufferStream_;
-  public int position_; // This is the read head
-  public int lastValidBytePosition_;
-  public boolean hasLobs_; // is there at least one LOB column?
-
-  // Current row positioning
-  protected int currentRowPosition_;
-  private int nextRowPosition_;
-  // Let's new up a 2-dimensional array based on fetch-size and reuse so that
-  protected int[] columnDataPosition_; 
-
-  // This is the actual, computed lengths of varchar fields, not the max length from query descriptor or DA
-  protected int[] columnDataComputedLength_;
-  // populate this for
-
-  // All the data is in the buffers, but user may not have necessarily stepped to the last row yet.
-  // This flag indicates that the server has returned all the rows, and is positioned
-  // after last, for both scrollable and forward-only cursors.
-  // For singleton cursors, this memeber will be set to true as soon as next is called.
-  public boolean allRowsReceivedFromServer_;
-
-  // Total number of rows read so far.
-  // This should never exceed this.statement.maxRows
-  int rowsRead_;
-
-  // Maximum column size limit in bytes.
-  int maxFieldSize_ = 0;
-
-  // Row positioning for all cached rows
-  // For scrollable result sets, these lists hold the offsets into the cached rowset buffer for each row of data.
-  protected java.util.ArrayList columnDataPositionCache_ = new java.util.ArrayList();
-  protected java.util.ArrayList columnDataLengthCache_ = new java.util.ArrayList();
-  protected java.util.ArrayList columnDataIsNullCache_ = new java.util.ArrayList();
-  public java.util.ArrayList isUpdateDeleteHoleCache_ = new java.util.ArrayList();
-  public boolean isUpdateDeleteHole_;
-  final static public java.lang.Boolean ROW_IS_NULL = new Boolean (true);
-  final static public java.lang.Boolean ROW_IS_NOT_NULL = new Boolean (false);
-
-  java.sql.Date recyclableDate_ = null;
-  java.sql.Time recyclableTime_ = null;
-  java.sql.Timestamp recyclableTimestamp_ = null;
-
-  // For the net, this data comes from the query descriptor.
-
-  public int[] jdbcTypes_;
-  public int columns_;
-  public boolean[] nullable_;
-  public String[] charsetName_;
-  public boolean[] isNull_;
-  public int[] fdocaLength_; // this is the max length for
-
-  //----------------------------------------------------------------------------
-
-  public int [] ccsid_;
-  char[] charBuffer_;
-
-  //---------------------constructors/finalizer---------------------------------
-
-  public Cursor (Agent agent)
-  {
-    agent_ = agent;
-    dataBufferStream_ = new java.io.ByteArrayOutputStream ();
-  }
-
-  public Cursor (Agent agent, byte[] dataBuffer)
-  {
-    this (agent);
-    dataBuffer_ = dataBuffer;
-    allRowsReceivedFromServer_ = false;
-  }
-
-  public void setNumberOfColumns (int numberOfColumns)
-  {
-    columnDataPosition_ = new int[numberOfColumns];
-    columnDataComputedLength_ = new int[numberOfColumns];
-
-    columns_ = numberOfColumns;
-    nullable_ = new boolean[numberOfColumns];
-    charsetName_ = new String[numberOfColumns];
-
-    ccsid_ = new int [numberOfColumns];
-
-    isNull_ = new boolean[numberOfColumns];
-    jdbcTypes_ = new int[numberOfColumns];
-  }
-
-  // Makes the next row the current row.
-  // Returns true if the current row position is a valid row position.
-  public boolean next () throws SqlException
-  {
-    // local variable usd to hold the returned value from calculateColumnOffsetsForRow()
-    boolean rowPositionIsValid = true;
-
-    // reset lob data
-    // clears out Cursor.lobs_ calculated for the current row when cursor is moved.
-    clearLobData_ ();
-
-    // mark the start of a new row.
-    makeNextRowPositionCurrent ();
-
-    // Drive the CNTQRY outside of calculateColumnOffsetsForRow() if the dataBuffer_
-    // contains no data since it has no abilities to handle replies other than
-    // the QRYDTA, i.e. ENDQRYRM when the result set contains no more rows.
-    while (!dataBufferHasUnprocessedData()) {
-      if (allRowsReceivedFromServer_)
-        return false;
-      getMoreData_();
-    }
-
-    // The parameter passed in here is used as an index into the cached rowset for
-    // scrollable cursors, for the arrays to be reused.  It is not used for forward-only
-    // cursors, so just pass in 0.
-    rowPositionIsValid = calculateColumnOffsetsForRow_(0);  // readFetchedRows()
-    markNextRowPosition ();
-    return rowPositionIsValid;
-  }
-
-  //--------------------------reseting cursor state-----------------------------
-
-  public final void setAllRowsReceivedFromServer (boolean b)
-  {
-    allRowsReceivedFromServer_ = b;
-  }
-
-  public final boolean currentRowPositionIsEqualToNextRowPosition ()
-  {
-    return (currentRowPosition_ == nextRowPosition_);
-  }
-
-  // reset the beginning and ending position in the data buffer to 0
-  // reset the currentRowPosition and nextRowPosition to 0
-  // reset lastRowReached and sqlcode100Received to false
-  // clear the column data offsets cache
-  public final void resetDataBuffer ()
-  {
-    position_ = 0;
-    lastValidBytePosition_ = 0;
-    currentRowPosition_ = 0;
-    nextRowPosition_ = 0;
-    allRowsReceivedFromServer_ = false;
-    dataBufferStream_.reset();
-  }
-
-  public final boolean dataBufferHasUnprocessedData ()
-  {
-    return (lastValidBytePosition_ - position_) > 0;
-  }
-
-  protected abstract boolean calculateColumnOffsetsForRow_ (int row) throws SqlException, DisconnectException;
-  protected abstract void clearLobData_();
-  protected abstract void getMoreData_() throws SqlException;
-
-  // Associate a new underlying COM or SQLDA output data buffer for this converter.
-  public final void setBuffer (byte[] dataBuffer)
-  {
-    dataBuffer_ = dataBuffer;
-  }
-
-  public final void setIsUpdataDeleteHole (int row, boolean isRowNull)
-  {
-    isUpdateDeleteHole_ = isRowNull;
-    Boolean nullIndicator = (isUpdateDeleteHole_ == true) ? ROW_IS_NULL : ROW_IS_NOT_NULL;
-    if (isUpdateDeleteHoleCache_.size() == row)
-      isUpdateDeleteHoleCache_.add (nullIndicator);
-    else
-      isUpdateDeleteHoleCache_.set (row, nullIndicator);
-  }
-  //---------------------------cursor positioning-------------------------------
-
-  final int getPosition ()
-  {
-    return position_;
-  }
-
-  final void setPosition (int newPosition)
-  {
-    position_ = newPosition;
-  }
-
-  public final void markCurrentRowPosition ()
-  {
-    currentRowPosition_ = position_;
-  }
-
-  public final void markNextRowPosition ()
-  {
-    nextRowPosition_ = position_;
-  }
-
-  public final void makeNextRowPositionCurrent ()
-  {
-    currentRowPosition_ = nextRowPosition_;
-  }
-
-  final void repositionCursorToCurrentRow ()
-  {
-    position_ = currentRowPosition_;
-  }
-
-  final void repositionCursorToNextRow ()
-  {
-    position_ = nextRowPosition_;
-  }
-
-  public final byte[] getDataBuffer ()
-  {
-    return dataBuffer_;
-  }
-
-  public final int getDataBufferLength()
-  {
-    return dataBuffer_.length;
-  }
-
-  public final int getLastValidBytePosition ()
-  {
-    return lastValidBytePosition_;
-  }
-
-  // This tracks the total number of rows read into the client side buffer for
-  // this result set, irregardless of scrolling.
-  // Per jdbc semantics, this should never exceed statement.maxRows.
-  // This event should be generated in the materialized cursor's implementation
-  // of calculateColumnOffsetsForRow().
-  public final void incrementRowsReadEvent()
-  {
-    rowsRead_++;
-  }
-
-  //------- the following getters are called on known column types -------------
-  // Direct conversions only, cross conversions are handled by another set of getters.
-
-  // Build a Java short from a 2-byte signed binary representation.
-  private final short get_SMALLINT (int column)
-  {
-    return org.apache.derby.client.am.SignedBinary.getShort (dataBuffer_,
-                                                             columnDataPosition_[column-1]);
-  }
-
-  // Build a Java int from a 4-byte signed binary representation.
-  private final int get_INTEGER (int column)
-  {
-    return org.apache.derby.client.am.SignedBinary.getInt (dataBuffer_,
-                                                           columnDataPosition_[column-1]);
-  }
-
-  // Build a Java long from an 8-byte signed binary representation.
-  private final long get_BIGINT (int column)
-  {
-    return org.apache.derby.client.am.SignedBinary.getLong (dataBuffer_,
-                                                            columnDataPosition_[column-1]);
-  }
-
-  // Build a Java float from a 4-byte floating point representation.
-  private final float get_FLOAT (int column)
-  {
-    return org.apache.derby.client.am.FloatingPoint.getFloat (dataBuffer_,
-                                                      columnDataPosition_[column-1]);
-  }
-
-  // Build a Java double from an 8-byte floating point representation.
-  private final double get_DOUBLE (int column)
-  {
-    return org.apache.derby.client.am.FloatingPoint.getDouble (dataBuffer_,
-                                                       columnDataPosition_[column-1]);
-  }
-
-  // Build a java.math.BigDecimal from a fixed point decimal byte representation.
-  private final java.math.BigDecimal get_DECIMAL (int column) throws SqlException
-  {
-    try {
-      return org.apache.derby.client.am.Decimal.getBigDecimal (dataBuffer_,
-                                                       columnDataPosition_[column-1],
-                                                       getColumnPrecision (column-1),
-                                                       getColumnScale (column-1));
-    }
-    catch (java.io.UnsupportedEncodingException e) {
-      throw new SqlException (agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
-    }
-  }
-
-
-  // Build a Java double from a fixed point decimal byte representation.
-  private final double getDoubleFromDECIMAL (int column) throws SqlException
-  {
-    try {
-      return org.apache.derby.client.am.Decimal.getDouble (dataBuffer_,
-                                                   columnDataPosition_[column-1],
-                                                   getColumnPrecision (column-1),
-                                                   getColumnScale (column-1));
-    }
-    catch (java.lang.IllegalArgumentException e) {
-      throw new SqlException (agent_.logWriter_, e, "Decimal value is out of range for conversion to double");
-    }
-    catch (java.io.UnsupportedEncodingException e) {
-      throw new SqlException (agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
-    }
-  }
-
-  // Build a Java long from a fixed point decimal byte representation.
-  private final long getLongFromDECIMAL (int column) throws SqlException
-  {
-    try {
-      return org.apache.derby.client.am.Decimal.getLong (dataBuffer_,
-                                                 columnDataPosition_[column-1],
-                                                 getColumnPrecision (column-1),
-                                                 getColumnScale (column-1));
-    }
-    catch (java.lang.IllegalArgumentException e) {
-      throw new SqlException (agent_.logWriter_, e, "Decimal value is out of range for conversion to long");
-    }
-    catch (java.io.UnsupportedEncodingException e) {
-      throw new SqlException (agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
-    }
-  }
-
-  // Build a Java String from a database VARCHAR or LONGVARCHAR field.
-  //
-  // Depending on the ccsid, length is the number of chars or number of bytes.
-  // For 2-byte character ccsids, length is the number of characters,
-  // for all other cases length is the number of bytes.
-  // The length does not include the null terminator.
-  private final String getVARCHAR (int column) throws SqlException
-  {
-    String tempString = null;
-    try {
-      if(ccsid_[column-1] == 1200)
-        return getStringWithoutConvert (columnDataPosition_[column-1] + 2, columnDataComputedLength_[column-1] - 2 );
-
-      // check for null encoding is needed because the net layer
-      // will no longer throw an exception if the server didn't specify
-      // a mixed or double byte ccsid (ccsid = 0).  this check for null in the
-      // cursor is only required for types which can have mixed or double
-      // byte ccsids.
-      if (charsetName_[column-1] == null)
-        throw new SqlException (agent_.logWriter_,
-          "Required character converter not available for data type.");
-
-      tempString = new String (dataBuffer_,
-			           columnDataPosition_[column-1] + 2,
-			           columnDataComputedLength_[column-1] - 2,
-			           charsetName_[column-1]);
-      return (maxFieldSize_ == 0) ? tempString :
-        tempString.substring(0, java.lang.Math.min (maxFieldSize_, tempString.length()));
-    }
-    catch (java.io.UnsupportedEncodingException e) {
-      throw new SqlException (agent_.logWriter_, e, "unsupported encoding for result set column " + column);
-    }
-  }
-
-  // Build a Java String from a database CHAR field.
-  private final String getCHAR (int column) throws SqlException
-  {
-    String tempString = null;
-    if (ccsid_[column - 1] == 1200)
-      return getStringWithoutConvert(columnDataPosition_[column - 1], columnDataComputedLength_[column - 1]);
-
-    try {
-      // check for null encoding is needed because the net layer
-      // will no longer throw an exception if the server didn't specify
-      // a mixed or double byte ccsid (ccsid = 0).  this check for null in the
-      // cursor is only required for types which can have mixed or double
-      // byte ccsids.
-      if (charsetName_[column-1] == null)
-        throw new SqlException (agent_.logWriter_,
-          "Required character converter not available for data type.");
-
-      tempString = new String (dataBuffer_,
-                               columnDataPosition_[column-1],
- 		         columnDataComputedLength_[column-1],
-	         charsetName_[column-1]);
-      return (maxFieldSize_ == 0) ? tempString :
-        tempString.substring(0, java.lang.Math.min (maxFieldSize_, tempString.length()));
-    }
-    catch (java.io.UnsupportedEncodingException e) {
-      throw new SqlException (agent_.logWriter_, e, "unsupported encoding for result set column " + column);
-    }
-  }
-
-  // Build a JDBC Date object from the DERBY ISO DATE field.
-  private final java.sql.Date getDATE (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.dateBytesToDate (dataBuffer_,
-                                                                  columnDataPosition_[column-1],
-                                                                  recyclableDate_);
-  }
-
-  // Build a JDBC Time object from the DERBY ISO TIME field.
-  private final java.sql.Time getTIME (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timeBytesToTime (dataBuffer_,
-                                                                  columnDataPosition_[column-1],
-                                                                   recyclableTime_);
-  }
-
-  // Build a JDBC Timestamp object from the DERBY ISO TIMESTAMP field.
-  private final java.sql.Timestamp getTIMESTAMP (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timestampBytesToTimestamp (dataBuffer_,
-                                                                            columnDataPosition_[column-1],
-                                                                            recyclableTimestamp_);
-  }
-
-  // Build a JDBC Timestamp object from the DERBY ISO DATE field.
-  private final java.sql.Timestamp getTimestampFromDATE (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.dateBytesToTimestamp (dataBuffer_,
-                                                                       columnDataPosition_[column-1],
-                                                                       recyclableTimestamp_);
-  }
-
-  // Build a JDBC Timestamp object from the DERBY ISO TIME field.
-  private final java.sql.Timestamp getTimestampFromTIME (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timeBytesToTimestamp (dataBuffer_,
-                                                                       columnDataPosition_[column-1],
-                                                                       recyclableTimestamp_);
-  }
-
-  // Build a JDBC Date object from the DERBY ISO TIMESTAMP field.
-  private final java.sql.Date getDateFromTIMESTAMP (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timestampBytesToDate (dataBuffer_,
-                                                                       columnDataPosition_[column-1],
-                                                                       recyclableDate_);
-  }
-
-  // Build a JDBC Time object from the DERBY ISO TIMESTAMP field.
-  private final java.sql.Time getTimeFromTIMESTAMP (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timestampBytesToTime (dataBuffer_,
-                                                                       columnDataPosition_[column-1],
-                                                                       recyclableTime_);
-  }
-
- private final String getStringFromDATE (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.dateBytesToDate (
-               dataBuffer_,
-               columnDataPosition_[column-1],
-               recyclableDate_).toString();
-  }
-
-  // Build a string object from the DERBY byte TIME representation.
-  private final String getStringFromTIME (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timeBytesToTime (
-               dataBuffer_,
-               columnDataPosition_[column-1],
-               recyclableTime_).toString();
-  }
-
-  // Build a string object from the DERBY byte TIMESTAMP representation.
-  private final String getStringFromTIMESTAMP (int column) throws SqlException
-  {
-    return org.apache.derby.client.am.DateTime.timestampBytesToTimestamp (
-               dataBuffer_,
-               columnDataPosition_[column-1],
-               recyclableTimestamp_).toString();
-  }
-
-  // Extract bytes from a database java.sql.Types.BINARY field.
-  // This is the DERBY type CHAR(n) FOR BIT DATA.
-  private final byte[] get_CHAR_FOR_BIT_DATA (int column) throws SqlException
-  {
-    // There is no limit to the size of a column if maxFieldSize is zero.
-    // Otherwise, use the smaller of maxFieldSize and the actual column length.
-    int columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column-1] :
-      java.lang.Math.min (maxFieldSize_, columnDataComputedLength_[column-1]);
-
-    byte[] bytes = new byte[columnLength];
-    System.arraycopy (dataBuffer_, columnDataPosition_[column-1], bytes, 0, columnLength);
-    return bytes;
-  }
-
-  // Extract bytes from a database java.sql.Types.VARBINARY or LONGVARBINARY field.
-  // This includes the DERBY types:
-  //   VARCHAR(n) FOR BIT DATA
-  //   LONG VARCHAR(n) FOR BIT DATA
-  private final byte[] get_VARCHAR_FOR_BIT_DATA (int column) throws SqlException
-  {
-    byte[] bytes;
-    int columnLength = 0;
-    columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column-1]-2 :
-      java.lang.Math.min (maxFieldSize_, columnDataComputedLength_[column-1]-2);
-    bytes = new byte[columnLength];
-    System.arraycopy (dataBuffer_, columnDataPosition_[column-1] + 2, bytes, 0, bytes.length);
-    return bytes;
-  }
-
-  abstract public Blob getBlobColumn_ (int column, Agent agent) throws SqlException;
-  abstract public Clob getClobColumn_ (int column, Agent agent) throws SqlException;
-
-  // get the raw clob bytes, without translation.  dataOffset must be int[1]
-  abstract public byte[] getClobBytes_ (int column, int[] dataOffset /*output*/) throws SqlException;
-
-  //------- the following getters perform any necessary cross-conversion _------
-
-  final boolean getBoolean (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return agent_.crossConverters_.getBooleanFromShort (get_SMALLINT (column));
-    case java.sql.Types.INTEGER:
-      return agent_.crossConverters_.getBooleanFromInt (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return agent_.crossConverters_.getBooleanFromLong (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return agent_.crossConverters_.getBooleanFromFloat (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getBooleanFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return agent_.crossConverters_.getBooleanFromLong (getLongFromDECIMAL (column));
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getBooleanFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getBooleanFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final byte getByte (int column) throws SqlException
-  {
-    // This needs to be changed to use jdbcTypes[] 
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return agent_.crossConverters_.getByteFromShort (get_SMALLINT (column));
-    case java.sql.Types.INTEGER:
-      return agent_.crossConverters_.getByteFromInt (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return agent_.crossConverters_.getByteFromLong (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return agent_.crossConverters_.getByteFromFloat (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getByteFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return agent_.crossConverters_.getByteFromLong (getLongFromDECIMAL (column));
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getByteFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getByteFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final short getShort (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return get_SMALLINT (column);
-    case java.sql.Types.INTEGER:
-      return agent_.crossConverters_.getShortFromInt (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return agent_.crossConverters_.getShortFromLong (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return agent_.crossConverters_.getShortFromFloat (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getShortFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return agent_.crossConverters_.getShortFromLong (getLongFromDECIMAL (column));
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getShortFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getShortFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final int getInt (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return (int) get_SMALLINT (column);
-    case java.sql.Types.INTEGER:
-      return get_INTEGER (column);
-    case java.sql.Types.BIGINT:
-      return agent_.crossConverters_.getIntFromLong (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return agent_.crossConverters_.getIntFromFloat (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getIntFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return agent_.crossConverters_.getIntFromLong (getLongFromDECIMAL (column));
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getIntFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getIntFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final long getLong (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return (long) get_SMALLINT (column);
-    case java.sql.Types.INTEGER:
-      return (long) get_INTEGER (column);
-    case java.sql.Types.BIGINT:
-      return get_BIGINT (column);
-    case java.sql.Types.REAL:
-      return agent_.crossConverters_.getLongFromFloat (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getLongFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return getLongFromDECIMAL (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getLongFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getLongFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final float getFloat (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.REAL:
-      return get_FLOAT (column);
-    case java.sql.Types.DOUBLE:
-      return agent_.crossConverters_.getFloatFromDouble (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return agent_.crossConverters_.getFloatFromDouble (getDoubleFromDECIMAL (column));
-    case java.sql.Types.SMALLINT:
-      return (float) get_SMALLINT (column);
-    case java.sql.Types.INTEGER:
-      return (float) get_INTEGER (column);
-    case java.sql.Types.BIGINT:
-      return (float) get_BIGINT (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getFloatFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getFloatFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final double getDouble (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.REAL:
-      double d = (double) get_FLOAT (column);
-      return d;
-      //return (double) get_FLOAT (column);
-    case java.sql.Types.DOUBLE:
-      return get_DOUBLE (column);
-    case java.sql.Types.DECIMAL:
-      // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
-      return getDoubleFromDECIMAL (column);
-    case java.sql.Types.SMALLINT:
-      return (double) get_SMALLINT (column);
-    case java.sql.Types.INTEGER:
-      return (double) get_INTEGER (column);
-    case java.sql.Types.BIGINT:
-      return (double) get_BIGINT (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getDoubleFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getDoubleFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final java.math.BigDecimal getBigDecimal (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.DECIMAL:
-      return get_DECIMAL (column);
-    case java.sql.Types.REAL:
-      // Can't use the following commented out line because it changes precision of the result.
-      //return new java.math.BigDecimal (get_FLOAT (column));
-      float f = get_FLOAT (column);
-      return new java.math.BigDecimal (String.valueOf(f));
-    case java.sql.Types.DOUBLE:
-      // Can't use the following commented out line because it changes precision of the result.
-      return new java.math.BigDecimal (String.valueOf (get_DOUBLE (column)));
-    case java.sql.Types.SMALLINT:
-      return java.math.BigDecimal.valueOf (get_SMALLINT (column));
-    case java.sql.Types.INTEGER:
-      return java.math.BigDecimal.valueOf (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return java.math.BigDecimal.valueOf (get_BIGINT (column));
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getBigDecimalFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getBigDecimalFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final java.sql.Date getDate (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.DATE:
-      return getDATE (column);
-    case java.sql.Types.TIMESTAMP:
-      return getDateFromTIMESTAMP (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getDateFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getDateFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final java.sql.Time getTime (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.TIME:
-      return getTIME (column);
-    case java.sql.Types.TIMESTAMP:
-      return getTimeFromTIMESTAMP (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getTimeFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getTimeFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final java.sql.Timestamp getTimestamp (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.TIMESTAMP:
-      return getTIMESTAMP (column);
-    case java.sql.Types.DATE:
-      return getTimestampFromDATE (column);
-    case java.sql.Types.TIME:
-      return getTimestampFromTIME (column);
-    case java.sql.Types.CHAR:
-      return agent_.crossConverters_.getTimestampFromString (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return agent_.crossConverters_.getTimestampFromString (getVARCHAR (column));
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final String getString (int column) throws SqlException
-  {
-    String tempString = null;
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.CHAR:
-      return getCHAR (column);
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return getVARCHAR (column);
-
-    case java.sql.Types.SMALLINT:
-      return String.valueOf (get_SMALLINT (column));
-    case java.sql.Types.INTEGER:
-      return String.valueOf (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return String.valueOf (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return String.valueOf (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return String.valueOf (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      // We could get better performance here if we didn't materialize the BigDecimal,
-      // but converted directly from decimal bytes to a string.
-      return String.valueOf (get_DECIMAL (column));
-    case java.sql.Types.DATE:
-      return getStringFromDATE (column);
-    case java.sql.Types.TIME:
-      return getStringFromTIME (column);
-    case java.sql.Types.TIMESTAMP:
-      return getStringFromTIMESTAMP (column);
-    case Types.BINARY:
-      tempString =
-        agent_.crossConverters_.getStringFromBytes (get_CHAR_FOR_BIT_DATA (column));
-      return (maxFieldSize_ == 0) ? tempString :
-        tempString.substring(0, java.lang.Math.min (maxFieldSize_, tempString.length()));
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      tempString =
-        agent_.crossConverters_.getStringFromBytes (get_VARCHAR_FOR_BIT_DATA (column));
-      return (maxFieldSize_ == 0) ? tempString :
-        tempString.substring(0, java.lang.Math.min (maxFieldSize_, tempString.length()));
-    case java.sql.Types.BLOB:
-      Blob b = (Blob) getBlobColumn_ (column, agent_);
-      return agent_.crossConverters_.getStringFromBytes (b.getBytes(1, (int) b.length()));
-    case java.sql.Types.CLOB:
-      Clob c = getClobColumn_ (column, agent_);
-      return c.getSubString (1, (int) c.length());
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  final byte[] getBytes (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.BINARY:
-      return get_CHAR_FOR_BIT_DATA (column);
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      return get_VARCHAR_FOR_BIT_DATA (column);
-    case java.sql.Types.BLOB:
-      Blob b = (Blob) getBlobColumn_ (column, agent_);
-      return b.getBytes (1, (int) b.length()); 
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.io.InputStream getBinaryStream (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.BINARY:
-      return new java.io.ByteArrayInputStream (get_CHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      return new java.io.ByteArrayInputStream (get_VARCHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.BLOB:
-      Blob b = (Blob) getBlobColumn_ (column, agent_);
-      return b.getBinaryStream();
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.io.InputStream getAsciiStream (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.CLOB:
-      Clob c = getClobColumn_ (column, agent_);
-      return c.getAsciiStream();
-    case java.sql.Types.CHAR:
-      try {
-        return new java.io.ByteArrayInputStream (getCHAR(column).getBytes("US-ASCII"));
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, e.getMessage());
-      }
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      try {
-        return new java.io.ByteArrayInputStream (getVARCHAR(column).getBytes("US-ASCII"));
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, e.getMessage());
-      }
-    case java.sql.Types.BINARY:
-      return new java.io.ByteArrayInputStream (get_CHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      return new java.io.ByteArrayInputStream (get_VARCHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.BLOB:
-      Blob b = (Blob) getBlobColumn_ (column, agent_);
-      return b.getBinaryStream();
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.io.InputStream getUnicodeStream (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.CLOB: {
-      Clob c = getClobColumn_ (column, agent_);
-      String s = c.getSubString (1L, (int) c.length());
-      try {
-        return new java.io.ByteArrayInputStream (s.getBytes ("UTF-8"));
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, e.getMessage());
-      }
-    }
-    case java.sql.Types.CHAR: {
-      try {
-        return new java.io.ByteArrayInputStream (getCHAR (column).getBytes ("UTF-8"));
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, e.getMessage());
-      }
-    }
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      try {
-        return new java.io.ByteArrayInputStream (getVARCHAR(column).getBytes ("UTF-8"));
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, e.getMessage());
-      }
-    case java.sql.Types.BINARY:
-      return new java.io.ByteArrayInputStream (get_CHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      return new java.io.ByteArrayInputStream (get_VARCHAR_FOR_BIT_DATA (column));
-    case java.sql.Types.BLOB:
-      Blob b = (Blob) getBlobColumn_ (column, agent_);
-      return b.getBinaryStream();
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.io.Reader getCharacterStream (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.CLOB:
-      Clob c = getClobColumn_ (column, agent_);
-      return c.getCharacterStream();
-    case java.sql.Types.CHAR:
-      return new java.io.StringReader (getCHAR (column));
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return new java.io.StringReader (getVARCHAR (column));
-    case java.sql.Types.BINARY:
-      try {
-        return new java.io.InputStreamReader (new java.io.ByteArrayInputStream (get_CHAR_FOR_BIT_DATA (column)), "UTF-16BE");
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
-      }
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      try {
-        return new java.io.InputStreamReader (new java.io.ByteArrayInputStream (get_VARCHAR_FOR_BIT_DATA (column)), "UTF-16BE");
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
-      }
-    case java.sql.Types.BLOB:
-      try {
-        Blob b = (Blob) getBlobColumn_ (column, agent_);
-        return new java.io.InputStreamReader (b.getBinaryStream(), "UTF-16BE");
-      }
-      catch (java.io.UnsupportedEncodingException e) {
-        throw new SqlException (agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
-      }
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.sql.Blob getBlob (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case Types.BLOB:
-      return getBlobColumn_ (column, agent_);
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.sql.Clob getClob (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case Types.CLOB:
-      return getClobColumn_ (column, agent_);
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final java.sql.Array getArray (int column) throws SqlException
-  {
-    throw new SqlException (agent_.logWriter_, "not yet implemented");
-  }
-
-  public final java.sql.Ref getRef (int column) throws SqlException
-  {
-    throw new SqlException (agent_.logWriter_, "not yet implemented");
-  }
-
-  public final Object getObject (int column) throws SqlException
-  {
-    switch (jdbcTypes_[column-1]) {
-    case java.sql.Types.SMALLINT:
-      return new Integer (get_SMALLINT (column)); // See Table 4 in JDBC 1 spec (pg. 932 in jdbc book)
-    case java.sql.Types.INTEGER:
-      return new Integer (get_INTEGER (column));
-    case java.sql.Types.BIGINT:
-      return new Long (get_BIGINT (column));
-    case java.sql.Types.REAL:
-      return new Float (get_FLOAT (column));
-    case java.sql.Types.DOUBLE:
-      return new Double (get_DOUBLE (column));
-    case java.sql.Types.DECIMAL:
-      return get_DECIMAL (column);
-    case java.sql.Types.DATE:
-      return getDATE (column);
-    case java.sql.Types.TIME:
-      return getTIME (column);
-    case java.sql.Types.TIMESTAMP:
-      return getTIMESTAMP (column);
-    case java.sql.Types.CHAR:
-      return getCHAR (column);
-    case java.sql.Types.VARCHAR:
-    case java.sql.Types.LONGVARCHAR:
-      return getVARCHAR (column);
-    case Types.BINARY:
-      return get_CHAR_FOR_BIT_DATA (column);
-    case java.sql.Types.VARBINARY:
-    case java.sql.Types.LONGVARBINARY:
-      return get_VARCHAR_FOR_BIT_DATA (column);
-    case java.sql.Types.BLOB:
-      return getBlobColumn_ (column, agent_);
-    case java.sql.Types.CLOB:
-      return getClobColumn_ (column, agent_);
-    default:
-      throw new ColumnTypeConversionException (agent_.logWriter_);
-    }
-  }
-
-  public final void allocateCharBuffer ()
-  {
-    // compute the maximum char length
-    int maxCharLength = 0;
-    for (int i=0; i<columns_; i++) {
-      switch (jdbcTypes_[i]) {
-      case Types.CHAR:
-      case Types.VARCHAR:
-      case Types.LONGVARCHAR:
-        if (fdocaLength_[i] > maxCharLength) maxCharLength = fdocaLength_[i];
-      }
-    }
-
-    // allocate char buffer to accomodate largest result column
-    charBuffer_ = new char[maxCharLength]; 
-  }
-
-  private final String getStringWithoutConvert (int position, int actualLength) throws SqlException
-  {
-    int start = position;
-    int end = position + actualLength;
-
-    int charCount = 0;
-      while (start < end)
-      {
-         charBuffer_[charCount++] = (char) (((dataBuffer_[start]&0xff)<<8) | (dataBuffer_[start+1]&0xff));
-         start += 2;
-    }
-
-    return new String(charBuffer_, 0, charCount);
-  }
-
-  public void nullDataForGC ()
-  {
-    dataBuffer_ = null;
-    dataBufferStream_ = null;
-    columnDataPosition_ = null;
-    columnDataComputedLength_ = null;
-    columnDataPositionCache_ = null;
-    columnDataLengthCache_ = null;
-    columnDataIsNullCache_ = null;
-    jdbcTypes_ = null;
-    nullable_ = null;
-    charsetName_ = null;
-    this.ccsid_ = null;
-    isUpdateDeleteHoleCache_ = null;
-    isNull_ = null;
-    fdocaLength_ = null;
-    charBuffer_ = null;
-  }
-
-  private final int getColumnPrecision (int column)
-  {
-    return ((fdocaLength_[column] >> 8) & 0xff);
-  }
-
-  private final int getColumnScale (int column)
-  {
-    return (fdocaLength_[column] & 0xff);
-  }
-
-  // Only used by Sqlca.getMessage() when using a locale encoding
-  // to convert errror message text instead of relying on server encoding as usual.
-  final byte[] getBytesFromVARCHAR (int column) throws SqlException
-  {
-    byte[] bytes;
-    bytes = new byte[columnDataComputedLength_[column-1]-2];
-    System.arraycopy (dataBuffer_, columnDataPosition_[column-1]+2, bytes, 0, bytes.length);
-    return bytes;
-  }
+
+public abstract class Cursor {
+    protected Agent agent_;
+
+    //-----------------------------varchar representations------------------------
+
+    public final static int STRING = 0;
+    public final static int VARIABLE_STRING = 2;       // uses a 2-byte length indicator
+    public final static int VARIABLE_SHORT_STRING = 1; // aka Pascal L; uses a 1-byte length indicator
+    public final static int NULL_TERMINATED_STRING = 3;
+
+    public final static int BYTES = 4;
+    public final static int VARIABLE_BYTES = 5;
+    public final static int VARIABLE_SHORT_BYTES = 6;
+    public final static int NULL_TERMINATED_BYTES = 7;
+
+    public final static int SBCS_CLOB = 8;
+    public final static int MBCS_CLOB = 9;
+    public final static int DBCS_CLOB = 10;
+    //-----------------------------internal state---------------------------------
+
+    //-------------Structures for holding and scrolling the data -----------------
+    public byte[] dataBuffer_;
+    public java.io.ByteArrayOutputStream dataBufferStream_;
+    public int position_; // This is the read head
+    public int lastValidBytePosition_;
+    public boolean hasLobs_; // is there at least one LOB column?
+
+    // Current row positioning
+    protected int currentRowPosition_;
+    private int nextRowPosition_;
+    // Let's new up a 2-dimensional array based on fetch-size and reuse so that
+    protected int[] columnDataPosition_;
+
+    // This is the actual, computed lengths of varchar fields, not the max length from query descriptor or DA
+    protected int[] columnDataComputedLength_;
+    // populate this for
+
+    // All the data is in the buffers, but user may not have necessarily stepped to the last row yet.
+    // This flag indicates that the server has returned all the rows, and is positioned
+    // after last, for both scrollable and forward-only cursors.
+    // For singleton cursors, this memeber will be set to true as soon as next is called.
+    public boolean allRowsReceivedFromServer_;
+
+    // Total number of rows read so far.
+    // This should never exceed this.statement.maxRows
+    int rowsRead_;
+
+    // Maximum column size limit in bytes.
+    int maxFieldSize_ = 0;
+
+    // Row positioning for all cached rows
+    // For scrollable result sets, these lists hold the offsets into the cached rowset buffer for each row of data.
+    protected java.util.ArrayList columnDataPositionCache_ = new java.util.ArrayList();
+    protected java.util.ArrayList columnDataLengthCache_ = new java.util.ArrayList();
+    protected java.util.ArrayList columnDataIsNullCache_ = new java.util.ArrayList();
+    public java.util.ArrayList isUpdateDeleteHoleCache_ = new java.util.ArrayList();
+    public boolean isUpdateDeleteHole_;
+    final static public java.lang.Boolean ROW_IS_NULL = new Boolean(true);
+    final static public java.lang.Boolean ROW_IS_NOT_NULL = new Boolean(false);
+
+    java.sql.Date recyclableDate_ = null;
+    java.sql.Time recyclableTime_ = null;
+    java.sql.Timestamp recyclableTimestamp_ = null;
+
+    // For the net, this data comes from the query descriptor.
+
+    public int[] jdbcTypes_;
+    public int columns_;
+    public boolean[] nullable_;
+    public String[] charsetName_;
+    public boolean[] isNull_;
+    public int[] fdocaLength_; // this is the max length for
+
+    //----------------------------------------------------------------------------
+
+    public int[] ccsid_;
+    char[] charBuffer_;
+
+    //---------------------constructors/finalizer---------------------------------
+
+    public Cursor(Agent agent) {
+        agent_ = agent;
+        dataBufferStream_ = new java.io.ByteArrayOutputStream();
+    }
+
+    public Cursor(Agent agent, byte[] dataBuffer) {
+        this(agent);
+        dataBuffer_ = dataBuffer;
+        allRowsReceivedFromServer_ = false;
+    }
+
+    public void setNumberOfColumns(int numberOfColumns) {
+        columnDataPosition_ = new int[numberOfColumns];
+        columnDataComputedLength_ = new int[numberOfColumns];
+
+        columns_ = numberOfColumns;
+        nullable_ = new boolean[numberOfColumns];
+        charsetName_ = new String[numberOfColumns];
+
+        ccsid_ = new int[numberOfColumns];
+
+        isNull_ = new boolean[numberOfColumns];
+        jdbcTypes_ = new int[numberOfColumns];
+    }
+
+    // Makes the next row the current row.
+    // Returns true if the current row position is a valid row position.
+    public boolean next() throws SqlException {
+        // local variable usd to hold the returned value from calculateColumnOffsetsForRow()
+        boolean rowPositionIsValid = true;
+
+        // reset lob data
+        // clears out Cursor.lobs_ calculated for the current row when cursor is moved.
+        clearLobData_();
+
+        // mark the start of a new row.
+        makeNextRowPositionCurrent();
+
+        // Drive the CNTQRY outside of calculateColumnOffsetsForRow() if the dataBuffer_
+        // contains no data since it has no abilities to handle replies other than
+        // the QRYDTA, i.e. ENDQRYRM when the result set contains no more rows.
+        while (!dataBufferHasUnprocessedData()) {
+            if (allRowsReceivedFromServer_) {
+                return false;
+            }
+            getMoreData_();
+        }
+
+        // The parameter passed in here is used as an index into the cached rowset for
+        // scrollable cursors, for the arrays to be reused.  It is not used for forward-only
+        // cursors, so just pass in 0.
+        rowPositionIsValid = calculateColumnOffsetsForRow_(0);  // readFetchedRows()
+        markNextRowPosition();
+        return rowPositionIsValid;
+    }
+
+    //--------------------------reseting cursor state-----------------------------
+
+    public final void setAllRowsReceivedFromServer(boolean b) {
+        allRowsReceivedFromServer_ = b;
+    }
+
+    public final boolean currentRowPositionIsEqualToNextRowPosition() {
+        return (currentRowPosition_ == nextRowPosition_);
+    }
+
+    // reset the beginning and ending position in the data buffer to 0
+    // reset the currentRowPosition and nextRowPosition to 0
+    // reset lastRowReached and sqlcode100Received to false
+    // clear the column data offsets cache
+    public final void resetDataBuffer() {
+        position_ = 0;
+        lastValidBytePosition_ = 0;
+        currentRowPosition_ = 0;
+        nextRowPosition_ = 0;
+        allRowsReceivedFromServer_ = false;
+        dataBufferStream_.reset();
+    }
+
+    public final boolean dataBufferHasUnprocessedData() {
+        return (lastValidBytePosition_ - position_) > 0;
+    }
+
+    protected abstract boolean calculateColumnOffsetsForRow_(int row) throws SqlException, DisconnectException;
+
+    protected abstract void clearLobData_();
+
+    protected abstract void getMoreData_() throws SqlException;
+
+    // Associate a new underlying COM or SQLDA output data buffer for this converter.
+    public final void setBuffer(byte[] dataBuffer) {
+        dataBuffer_ = dataBuffer;
+    }
+
+    public final void setIsUpdataDeleteHole(int row, boolean isRowNull) {
+        isUpdateDeleteHole_ = isRowNull;
+        Boolean nullIndicator = (isUpdateDeleteHole_ == true) ? ROW_IS_NULL : ROW_IS_NOT_NULL;
+        if (isUpdateDeleteHoleCache_.size() == row) {
+            isUpdateDeleteHoleCache_.add(nullIndicator);
+        } else {
+            isUpdateDeleteHoleCache_.set(row, nullIndicator);
+        }
+    }
+    //---------------------------cursor positioning-------------------------------
+
+    final int getPosition() {
+        return position_;
+    }
+
+    final void setPosition(int newPosition) {
+        position_ = newPosition;
+    }
+
+    public final void markCurrentRowPosition() {
+        currentRowPosition_ = position_;
+    }
+
+    public final void markNextRowPosition() {
+        nextRowPosition_ = position_;
+    }
+
+    public final void makeNextRowPositionCurrent() {
+        currentRowPosition_ = nextRowPosition_;
+    }
+
+    final void repositionCursorToCurrentRow() {
+        position_ = currentRowPosition_;
+    }
+
+    final void repositionCursorToNextRow() {
+        position_ = nextRowPosition_;
+    }
+
+    public final byte[] getDataBuffer() {
+        return dataBuffer_;
+    }
+
+    public final int getDataBufferLength() {
+        return dataBuffer_.length;
+    }
+
+    public final int getLastValidBytePosition() {
+        return lastValidBytePosition_;
+    }
+
+    // This tracks the total number of rows read into the client side buffer for
+    // this result set, irregardless of scrolling.
+    // Per jdbc semantics, this should never exceed statement.maxRows.
+    // This event should be generated in the materialized cursor's implementation
+    // of calculateColumnOffsetsForRow().
+    public final void incrementRowsReadEvent() {
+        rowsRead_++;
+    }
+
+    //------- the following getters are called on known column types -------------
+    // Direct conversions only, cross conversions are handled by another set of getters.
+
+    // Build a Java short from a 2-byte signed binary representation.
+    private final short get_SMALLINT(int column) {
+        return org.apache.derby.client.am.SignedBinary.getShort(dataBuffer_,
+                columnDataPosition_[column - 1]);
+    }
+
+    // Build a Java int from a 4-byte signed binary representation.
+    private final int get_INTEGER(int column) {
+        return org.apache.derby.client.am.SignedBinary.getInt(dataBuffer_,
+                columnDataPosition_[column - 1]);
+    }
+
+    // Build a Java long from an 8-byte signed binary representation.
+    private final long get_BIGINT(int column) {
+        return org.apache.derby.client.am.SignedBinary.getLong(dataBuffer_,
+                columnDataPosition_[column - 1]);
+    }
+
+    // Build a Java float from a 4-byte floating point representation.
+    private final float get_FLOAT(int column) {
+        return org.apache.derby.client.am.FloatingPoint.getFloat(dataBuffer_,
+                columnDataPosition_[column - 1]);
+    }
+
+    // Build a Java double from an 8-byte floating point representation.
+    private final double get_DOUBLE(int column) {
+        return org.apache.derby.client.am.FloatingPoint.getDouble(dataBuffer_,
+                columnDataPosition_[column - 1]);
+    }
+
+    // Build a java.math.BigDecimal from a fixed point decimal byte representation.
+    private final java.math.BigDecimal get_DECIMAL(int column) throws SqlException {
+        try {
+            return org.apache.derby.client.am.Decimal.getBigDecimal(dataBuffer_,
+                    columnDataPosition_[column - 1],
+                    getColumnPrecision(column - 1),
+                    getColumnScale(column - 1));
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new SqlException(agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
+        }
+    }
+
+
+    // Build a Java double from a fixed point decimal byte representation.
+    private final double getDoubleFromDECIMAL(int column) throws SqlException {
+        try {
+            return org.apache.derby.client.am.Decimal.getDouble(dataBuffer_,
+                    columnDataPosition_[column - 1],
+                    getColumnPrecision(column - 1),
+                    getColumnScale(column - 1));
+        } catch (java.lang.IllegalArgumentException e) {
+            throw new SqlException(agent_.logWriter_, e, "Decimal value is out of range for conversion to double");
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new SqlException(agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
+        }
+    }
+
+    // Build a Java long from a fixed point decimal byte representation.
+    private final long getLongFromDECIMAL(int column) throws SqlException {
+        try {
+            return org.apache.derby.client.am.Decimal.getLong(dataBuffer_,
+                    columnDataPosition_[column - 1],
+                    getColumnPrecision(column - 1),
+                    getColumnScale(column - 1));
+        } catch (java.lang.IllegalArgumentException e) {
+            throw new SqlException(agent_.logWriter_, e, "Decimal value is out of range for conversion to long");
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new SqlException(agent_.logWriter_, e, "Encoding is unsupported for conversion to BigDecimal");
+        }
+    }
+
+    // Build a Java String from a database VARCHAR or LONGVARCHAR field.
+    //
+    // Depending on the ccsid, length is the number of chars or number of bytes.
+    // For 2-byte character ccsids, length is the number of characters,
+    // for all other cases length is the number of bytes.
+    // The length does not include the null terminator.
+    private final String getVARCHAR(int column) throws SqlException {
+        String tempString = null;
+        try {
+            if (ccsid_[column - 1] == 1200) {
+                return getStringWithoutConvert(columnDataPosition_[column - 1] + 2, columnDataComputedLength_[column - 1] - 2);
+            }
+
+            // check for null encoding is needed because the net layer
+            // will no longer throw an exception if the server didn't specify
+            // a mixed or double byte ccsid (ccsid = 0).  this check for null in the
+            // cursor is only required for types which can have mixed or double
+            // byte ccsids.
+            if (charsetName_[column - 1] == null) {
+                throw new SqlException(agent_.logWriter_,
+                        "Required character converter not available for data type.");
+            }
+
+            tempString = new String(dataBuffer_,
+                    columnDataPosition_[column - 1] + 2,
+                    columnDataComputedLength_[column - 1] - 2,
+                    charsetName_[column - 1]);
+            return (maxFieldSize_ == 0) ? tempString :
+                    tempString.substring(0, java.lang.Math.min(maxFieldSize_, tempString.length()));
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new SqlException(agent_.logWriter_, e, "unsupported encoding for result set column " + column);
+        }
+    }
+
+    // Build a Java String from a database CHAR field.
+    private final String getCHAR(int column) throws SqlException {
+        String tempString = null;
+        if (ccsid_[column - 1] == 1200) {
+            return getStringWithoutConvert(columnDataPosition_[column - 1], columnDataComputedLength_[column - 1]);
+        }
+
+        try {
+            // check for null encoding is needed because the net layer
+            // will no longer throw an exception if the server didn't specify
+            // a mixed or double byte ccsid (ccsid = 0).  this check for null in the
+            // cursor is only required for types which can have mixed or double
+            // byte ccsids.
+            if (charsetName_[column - 1] == null) {
+                throw new SqlException(agent_.logWriter_,
+                        "Required character converter not available for data type.");
+            }
+
+            tempString = new String(dataBuffer_,
+                    columnDataPosition_[column - 1],
+                    columnDataComputedLength_[column - 1],
+                    charsetName_[column - 1]);
+            return (maxFieldSize_ == 0) ? tempString :
+                    tempString.substring(0, java.lang.Math.min(maxFieldSize_, tempString.length()));
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new SqlException(agent_.logWriter_, e, "unsupported encoding for result set column " + column);
+        }
+    }
+
+    // Build a JDBC Date object from the DERBY ISO DATE field.
+    private final java.sql.Date getDATE(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.dateBytesToDate(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableDate_);
+    }
+
+    // Build a JDBC Time object from the DERBY ISO TIME field.
+    private final java.sql.Time getTIME(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timeBytesToTime(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTime_);
+    }
+
+    // Build a JDBC Timestamp object from the DERBY ISO TIMESTAMP field.
+    private final java.sql.Timestamp getTIMESTAMP(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timestampBytesToTimestamp(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTimestamp_);
+    }
+
+    // Build a JDBC Timestamp object from the DERBY ISO DATE field.
+    private final java.sql.Timestamp getTimestampFromDATE(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.dateBytesToTimestamp(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTimestamp_);
+    }
+
+    // Build a JDBC Timestamp object from the DERBY ISO TIME field.
+    private final java.sql.Timestamp getTimestampFromTIME(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timeBytesToTimestamp(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTimestamp_);
+    }
+
+    // Build a JDBC Date object from the DERBY ISO TIMESTAMP field.
+    private final java.sql.Date getDateFromTIMESTAMP(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timestampBytesToDate(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableDate_);
+    }
+
+    // Build a JDBC Time object from the DERBY ISO TIMESTAMP field.
+    private final java.sql.Time getTimeFromTIMESTAMP(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timestampBytesToTime(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTime_);
+    }
+
+    private final String getStringFromDATE(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.dateBytesToDate(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableDate_).toString();
+    }
+
+    // Build a string object from the DERBY byte TIME representation.
+    private final String getStringFromTIME(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timeBytesToTime(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTime_).toString();
+    }
+
+    // Build a string object from the DERBY byte TIMESTAMP representation.
+    private final String getStringFromTIMESTAMP(int column) throws SqlException {
+        return org.apache.derby.client.am.DateTime.timestampBytesToTimestamp(dataBuffer_,
+                columnDataPosition_[column - 1],
+                recyclableTimestamp_).toString();
+    }
+
+    // Extract bytes from a database java.sql.Types.BINARY field.
+    // This is the DERBY type CHAR(n) FOR BIT DATA.
+    private final byte[] get_CHAR_FOR_BIT_DATA(int column) throws SqlException {
+        // There is no limit to the size of a column if maxFieldSize is zero.
+        // Otherwise, use the smaller of maxFieldSize and the actual column length.
+        int columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column - 1] :
+                java.lang.Math.min(maxFieldSize_, columnDataComputedLength_[column - 1]);
+
+        byte[] bytes = new byte[columnLength];
+        System.arraycopy(dataBuffer_, columnDataPosition_[column - 1], bytes, 0, columnLength);
+        return bytes;
+    }
+
+    // Extract bytes from a database java.sql.Types.VARBINARY or LONGVARBINARY field.
+    // This includes the DERBY types:
+    //   VARCHAR(n) FOR BIT DATA
+    //   LONG VARCHAR(n) FOR BIT DATA
+    private final byte[] get_VARCHAR_FOR_BIT_DATA(int column) throws SqlException {
+        byte[] bytes;
+        int columnLength = 0;
+        columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column - 1] - 2 :
+                java.lang.Math.min(maxFieldSize_, columnDataComputedLength_[column - 1] - 2);
+        bytes = new byte[columnLength];
+        System.arraycopy(dataBuffer_, columnDataPosition_[column - 1] + 2, bytes, 0, bytes.length);
+        return bytes;
+    }
+
+    abstract public Blob getBlobColumn_(int column, Agent agent) throws SqlException;
+
+    abstract public Clob getClobColumn_(int column, Agent agent) throws SqlException;
+
+    // get the raw clob bytes, without translation.  dataOffset must be int[1]
+    abstract public byte[] getClobBytes_(int column, int[] dataOffset /*output*/) throws SqlException;
+
+    //------- the following getters perform any necessary cross-conversion _------
+
+    final boolean getBoolean(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return agent_.crossConverters_.getBooleanFromShort(get_SMALLINT(column));
+        case java.sql.Types.INTEGER:
+            return agent_.crossConverters_.getBooleanFromInt(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return agent_.crossConverters_.getBooleanFromLong(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return agent_.crossConverters_.getBooleanFromFloat(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getBooleanFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return agent_.crossConverters_.getBooleanFromLong(getLongFromDECIMAL(column));
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getBooleanFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getBooleanFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final byte getByte(int column) throws SqlException {
+        // This needs to be changed to use jdbcTypes[]
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return agent_.crossConverters_.getByteFromShort(get_SMALLINT(column));
+        case java.sql.Types.INTEGER:
+            return agent_.crossConverters_.getByteFromInt(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return agent_.crossConverters_.getByteFromLong(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return agent_.crossConverters_.getByteFromFloat(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getByteFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return agent_.crossConverters_.getByteFromLong(getLongFromDECIMAL(column));
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getByteFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getByteFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final short getShort(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return get_SMALLINT(column);
+        case java.sql.Types.INTEGER:
+            return agent_.crossConverters_.getShortFromInt(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return agent_.crossConverters_.getShortFromLong(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return agent_.crossConverters_.getShortFromFloat(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getShortFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return agent_.crossConverters_.getShortFromLong(getLongFromDECIMAL(column));
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getShortFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getShortFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final int getInt(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return (int) get_SMALLINT(column);
+        case java.sql.Types.INTEGER:
+            return get_INTEGER(column);
+        case java.sql.Types.BIGINT:
+            return agent_.crossConverters_.getIntFromLong(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return agent_.crossConverters_.getIntFromFloat(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getIntFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return agent_.crossConverters_.getIntFromLong(getLongFromDECIMAL(column));
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getIntFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getIntFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final long getLong(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return (long) get_SMALLINT(column);
+        case java.sql.Types.INTEGER:
+            return (long) get_INTEGER(column);
+        case java.sql.Types.BIGINT:
+            return get_BIGINT(column);
+        case java.sql.Types.REAL:
+            return agent_.crossConverters_.getLongFromFloat(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getLongFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return getLongFromDECIMAL(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getLongFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getLongFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final float getFloat(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.REAL:
+            return get_FLOAT(column);
+        case java.sql.Types.DOUBLE:
+            return agent_.crossConverters_.getFloatFromDouble(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return agent_.crossConverters_.getFloatFromDouble(getDoubleFromDECIMAL(column));
+        case java.sql.Types.SMALLINT:
+            return (float) get_SMALLINT(column);
+        case java.sql.Types.INTEGER:
+            return (float) get_INTEGER(column);
+        case java.sql.Types.BIGINT:
+            return (float) get_BIGINT(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getFloatFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getFloatFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final double getDouble(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.REAL:
+            double d = (double) get_FLOAT(column);
+            return d;
+            //return (double) get_FLOAT (column);
+        case java.sql.Types.DOUBLE:
+            return get_DOUBLE(column);
+        case java.sql.Types.DECIMAL:
+            // For performance we don't materialize the BigDecimal, but convert directly from decimal bytes to a long.
+            return getDoubleFromDECIMAL(column);
+        case java.sql.Types.SMALLINT:
+            return (double) get_SMALLINT(column);
+        case java.sql.Types.INTEGER:
+            return (double) get_INTEGER(column);
+        case java.sql.Types.BIGINT:
+            return (double) get_BIGINT(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getDoubleFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getDoubleFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final java.math.BigDecimal getBigDecimal(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.DECIMAL:
+            return get_DECIMAL(column);
+        case java.sql.Types.REAL:
+            // Can't use the following commented out line because it changes precision of the result.
+            //return new java.math.BigDecimal (get_FLOAT (column));
+            float f = get_FLOAT(column);
+            return new java.math.BigDecimal(String.valueOf(f));
+        case java.sql.Types.DOUBLE:
+            // Can't use the following commented out line because it changes precision of the result.
+            return new java.math.BigDecimal(String.valueOf(get_DOUBLE(column)));
+        case java.sql.Types.SMALLINT:
+            return java.math.BigDecimal.valueOf(get_SMALLINT(column));
+        case java.sql.Types.INTEGER:
+            return java.math.BigDecimal.valueOf(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return java.math.BigDecimal.valueOf(get_BIGINT(column));
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getBigDecimalFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getBigDecimalFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final java.sql.Date getDate(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.DATE:
+            return getDATE(column);
+        case java.sql.Types.TIMESTAMP:
+            return getDateFromTIMESTAMP(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getDateFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getDateFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final java.sql.Time getTime(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.TIME:
+            return getTIME(column);
+        case java.sql.Types.TIMESTAMP:
+            return getTimeFromTIMESTAMP(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getTimeFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getTimeFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final java.sql.Timestamp getTimestamp(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.TIMESTAMP:
+            return getTIMESTAMP(column);
+        case java.sql.Types.DATE:
+            return getTimestampFromDATE(column);
+        case java.sql.Types.TIME:
+            return getTimestampFromTIME(column);
+        case java.sql.Types.CHAR:
+            return agent_.crossConverters_.getTimestampFromString(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return agent_.crossConverters_.getTimestampFromString(getVARCHAR(column));
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final String getString(int column) throws SqlException {
+        String tempString = null;
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.CHAR:
+            return getCHAR(column);
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return getVARCHAR(column);
+
+        case java.sql.Types.SMALLINT:
+            return String.valueOf(get_SMALLINT(column));
+        case java.sql.Types.INTEGER:
+            return String.valueOf(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return String.valueOf(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return String.valueOf(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return String.valueOf(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            // We could get better performance here if we didn't materialize the BigDecimal,
+            // but converted directly from decimal bytes to a string.
+            return String.valueOf(get_DECIMAL(column));
+        case java.sql.Types.DATE:
+            return getStringFromDATE(column);
+        case java.sql.Types.TIME:
+            return getStringFromTIME(column);
+        case java.sql.Types.TIMESTAMP:
+            return getStringFromTIMESTAMP(column);
+        case Types.BINARY:
+            tempString =
+                    agent_.crossConverters_.getStringFromBytes(get_CHAR_FOR_BIT_DATA(column));
+            return (maxFieldSize_ == 0) ? tempString :
+                    tempString.substring(0, java.lang.Math.min(maxFieldSize_, tempString.length()));
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            tempString =
+                    agent_.crossConverters_.getStringFromBytes(get_VARCHAR_FOR_BIT_DATA(column));
+            return (maxFieldSize_ == 0) ? tempString :
+                    tempString.substring(0, java.lang.Math.min(maxFieldSize_, tempString.length()));
+        case java.sql.Types.BLOB:
+            Blob b = (Blob) getBlobColumn_(column, agent_);
+            return agent_.crossConverters_.getStringFromBytes(b.getBytes(1, (int) b.length()));
+        case java.sql.Types.CLOB:
+            Clob c = getClobColumn_(column, agent_);
+            return c.getSubString(1, (int) c.length());
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    final byte[] getBytes(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.BINARY:
+            return get_CHAR_FOR_BIT_DATA(column);
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            return get_VARCHAR_FOR_BIT_DATA(column);
+        case java.sql.Types.BLOB:
+            Blob b = (Blob) getBlobColumn_(column, agent_);
+            return b.getBytes(1, (int) b.length());
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.io.InputStream getBinaryStream(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.BINARY:
+            return new java.io.ByteArrayInputStream(get_CHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            return new java.io.ByteArrayInputStream(get_VARCHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.BLOB:
+            Blob b = (Blob) getBlobColumn_(column, agent_);
+            return b.getBinaryStream();
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.io.InputStream getAsciiStream(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.CLOB:
+            Clob c = getClobColumn_(column, agent_);
+            return c.getAsciiStream();
+        case java.sql.Types.CHAR:
+            try {
+                return new java.io.ByteArrayInputStream(getCHAR(column).getBytes("US-ASCII"));
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, e.getMessage());
+            }
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            try {
+                return new java.io.ByteArrayInputStream(getVARCHAR(column).getBytes("US-ASCII"));
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, e.getMessage());
+            }
+        case java.sql.Types.BINARY:
+            return new java.io.ByteArrayInputStream(get_CHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            return new java.io.ByteArrayInputStream(get_VARCHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.BLOB:
+            Blob b = (Blob) getBlobColumn_(column, agent_);
+            return b.getBinaryStream();
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.io.InputStream getUnicodeStream(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.CLOB:
+            {
+                Clob c = getClobColumn_(column, agent_);
+                String s = c.getSubString(1L, (int) c.length());
+                try {
+                    return new java.io.ByteArrayInputStream(s.getBytes("UTF-8"));
+                } catch (java.io.UnsupportedEncodingException e) {
+                    throw new SqlException(agent_.logWriter_, e.getMessage());
+                }
+            }
+        case java.sql.Types.CHAR:
+            {
+                try {
+                    return new java.io.ByteArrayInputStream(getCHAR(column).getBytes("UTF-8"));
+                } catch (java.io.UnsupportedEncodingException e) {
+                    throw new SqlException(agent_.logWriter_, e.getMessage());
+                }
+            }
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            try {
+                return new java.io.ByteArrayInputStream(getVARCHAR(column).getBytes("UTF-8"));
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, e.getMessage());
+            }
+        case java.sql.Types.BINARY:
+            return new java.io.ByteArrayInputStream(get_CHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            return new java.io.ByteArrayInputStream(get_VARCHAR_FOR_BIT_DATA(column));
+        case java.sql.Types.BLOB:
+            Blob b = (Blob) getBlobColumn_(column, agent_);
+            return b.getBinaryStream();
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.io.Reader getCharacterStream(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.CLOB:
+            Clob c = getClobColumn_(column, agent_);
+            return c.getCharacterStream();
+        case java.sql.Types.CHAR:
+            return new java.io.StringReader(getCHAR(column));
+        case java.sql.Types.VARCHAR:
+        case java.sql.Types.LONGVARCHAR:
+            return new java.io.StringReader(getVARCHAR(column));
+        case java.sql.Types.BINARY:
+            try {
+                return new java.io.InputStreamReader(new java.io.ByteArrayInputStream(get_CHAR_FOR_BIT_DATA(column)), "UTF-16BE");
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
+            }
+        case java.sql.Types.VARBINARY:
+        case java.sql.Types.LONGVARBINARY:
+            try {
+                return new java.io.InputStreamReader(new java.io.ByteArrayInputStream(get_VARCHAR_FOR_BIT_DATA(column)), "UTF-16BE");
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
+            }
+        case java.sql.Types.BLOB:
+            try {
+                Blob b = (Blob) getBlobColumn_(column, agent_);
+                return new java.io.InputStreamReader(b.getBinaryStream(), "UTF-16BE");
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new SqlException(agent_.logWriter_, "UnsupportedEncodingException: " + e.getMessage());
+            }
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.sql.Blob getBlob(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case Types.BLOB:
+            return getBlobColumn_(column, agent_);
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.sql.Clob getClob(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case Types.CLOB:
+            return getClobColumn_(column, agent_);
+        default:
+            throw new ColumnTypeConversionException(agent_.logWriter_);
+        }
+    }
+
+    public final java.sql.Array getArray(int column) throws SqlException {
+        throw new SqlException(agent_.logWriter_, "not yet implemented");
+    }
+
+    public final java.sql.Ref getRef(int column) throws SqlException {
+        throw new SqlException(agent_.logWriter_, "not yet implemented");
+    }
+
+    public final Object getObject(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case java.sql.Types.SMALLINT:
+            return new Integer(get_SMALLINT(column)); // See Table 4 in JDBC 1 spec (pg. 932 in jdbc book)
+        case java.sql.Types.INTEGER:
+            return new Integer(get_INTEGER(column));
+        case java.sql.Types.BIGINT:
+            return new Long(get_BIGINT(column));
+        case java.sql.Types.REAL:
+            return new Float(get_FLOAT(column));
+        case java.sql.Types.DOUBLE:
+            return new Double(get_DOUBLE(column));
+        case java.sql.Types.DECIMAL:
+            return get_DECIMAL(column);
+        case java.sql.Types.DATE:
+            return getDATE(column);
+        case java.sql.Types.TIME:

[... 89 lines stripped ...]