Re: Fwd: org/postgresql/jdbc2/ResultSet.java - Mailing list pgsql-jdbc

From Barry Lind
Subject Re: Fwd: org/postgresql/jdbc2/ResultSet.java
Date
Msg-id 3CAA90A4.4020804@xythos.com
Whole thread Raw
In response to Fwd: org/postgresql/jdbc2/ResultSet.java  (Peter Mount <peter@retep.org.uk>)
List pgsql-jdbc
Harish,

Could you resend this patch in diff -c format?  Also it would be helpful
to explain what the problem is you are trying to fix.

thanks,
--Barry


Peter Mount wrote:
>
>> X-Sieve: cmu-sieve 2.0
>> Date: Sun, 31 Mar 2002 01:32:55 -0800
>> From: harishr@pacbell.net
>> Subject: org/postgresql/jdbc2/ResultSet.java
>> To: peter@retep.org.uk
>> X-Mailer: Apple Mail (2.481)
>>
>> Hello,
>>
>> Submitting changes to toTimestamp().
>> Please clean up if something is wrong.
>>
>> Works for me, in a development environment.
>>
>> Regards,
>>  harish
>>
>>
>>
>>
>>
>
> ------------------------------------------------------------------------
>
> package org.postgresql.jdbc2;
>
> // IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
> // If you make any modifications to this file, you must make sure that the
> // changes are also made (if relevent) to the related JDBC 1 class in the
> // org.postgresql.jdbc1 package.
>
> import java.lang.*;
> import java.io.*;
> import java.math.*;
> import java.text.*;
> import java.util.*;
> import java.sql.*;
> import org.postgresql.Field;
> import org.postgresql.largeobject.*;
> import org.postgresql.util.*;
> import org.postgresql.core.Encoding;
>
> /*
>  * A ResultSet provides access to a table of data generated by executing a
>  * Statement.  The table rows are retrieved in sequence.  Within a row its
>  * column values can be accessed in any order.
>  *
>  * <P>A ResultSet maintains a cursor pointing to its current row of data.
>  * Initially the cursor is positioned before the first row.  The 'next'
>  * method moves the cursor to the next row.
>  *
>  * <P>The getXXX methods retrieve column values for the current row.  You can
>  * retrieve values either using the index number of the column, or by using
>  * the name of the column.    In general using the column index will be more
>  * efficient.  Columns are numbered from 1.
>  *
>  * <P>For maximum portability, ResultSet columns within each row should be read
>  * in left-to-right order and each column should be read only once.
>  *
>  *<P> For the getXXX methods, the JDBC driver attempts to convert the
>  * underlying data to the specified Java type and returns a suitable Java
>  * value.  See the JDBC specification for allowable mappings from SQL types
>  * to Java types with the ResultSet getXXX methods.
>  *
>  * <P>Column names used as input to getXXX methods are case insenstive.  When
>  * performing a getXXX using a column name, if several columns have the same
>  * name, then the value of the first matching column will be returned.    The
>  * column name option is designed to be used when column names are used in the
>  * SQL Query.  For columns that are NOT explicitly named in the query, it is
>  * best to use column numbers.    If column names were used there is no way for
>  * the programmer to guarentee that they actually refer to the intended
>  * columns.
>  *
>  * <P>A ResultSet is automatically closed by the Statement that generated it
>  * when that Statement is closed, re-executed, or is used to retrieve the
>  * next result from a sequence of multiple results.
>  *
>  * <P>The number, types and properties of a ResultSet's columns are provided by
>  * the ResultSetMetaData object returned by the getMetaData method.
>  *
>  * @see ResultSetMetaData
>  * @see java.sql.ResultSet
>  */
> public class ResultSet extends org.postgresql.ResultSet implements java.sql.ResultSet
> {
>     protected org.postgresql.jdbc2.Statement statement;
>
>     private StringBuffer sbuf = null;
>
>     /*
>      * Create a new ResultSet - Note that we create ResultSets to
>      * represent the results of everything.
>      *
>      * @param fields an array of Field objects (basically, the
>      *    ResultSet MetaData)
>      * @param tuples Vector of the actual data
>      * @param status the status string returned from the back end
>      * @param updateCount the number of rows affected by the operation
>      * @param cursor the positioned update/delete cursor name
>      */
>     public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, long insertOID,
booleanbinaryCursor) 
>     {
>         super(conn, fields, tuples, status, updateCount, insertOID, binaryCursor);
>     }
>
>     /*
>      * Create a new ResultSet - Note that we create ResultSets to
>      * represent the results of everything.
>      *
>      * @param fields an array of Field objects (basically, the
>      *    ResultSet MetaData)
>      * @param tuples Vector of the actual data
>      * @param status the status string returned from the back end
>      * @param updateCount the number of rows affected by the operation
>      * @param cursor the positioned update/delete cursor name
>      */
>     public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
>     {
>         super(conn, fields, tuples, status, updateCount, 0, false);
>     }
>
>     /*
>      * A ResultSet is initially positioned before its first row,
>      * the first call to next makes the first row the current row;
>      * the second call makes the second row the current row, etc.
>      *
>      * <p>If an input stream from the previous row is open, it is
>      * implicitly closed.  The ResultSet's warning chain is cleared
>      * when a new row is read
>      *
>      * @return true if the new current is valid; false if there are no
>      *    more rows
>      * @exception SQLException if a database access error occurs
>      */
>     public boolean next() throws SQLException
>     {
>         if (++current_row >= rows.size())
>             return false;
>         this_row = (byte [][])rows.elementAt(current_row);
>         return true;
>     }
>
>     /*
>      * In some cases, it is desirable to immediately release a ResultSet
>      * database and JDBC resources instead of waiting for this to happen
>      * when it is automatically closed.  The close method provides this
>      * immediate release.
>      *
>      * <p><B>Note:</B> A ResultSet is automatically closed by the Statement
>      * the Statement that generated it when that Statement is closed,
>      * re-executed, or is used to retrieve the next result from a sequence
>      * of multiple results.  A ResultSet is also automatically closed
>      * when it is garbage collected.
>      *
>      * @exception SQLException if a database access error occurs
>      */
>     public void close() throws SQLException
>     {
>         //release resources held (memory for tuples)
>         if (rows != null)
>         {
>             rows = null;
>         }
>     }
>
>     /*
>      * A column may have the value of SQL NULL; wasNull() reports whether
>      * the last column read had this special value.  Note that you must
>      * first call getXXX on a column to try to read its value and then
>      * call wasNull() to find if the value was SQL NULL
>      *
>      * @return true if the last column read was SQL NULL
>      * @exception SQLException if a database access error occurred
>      */
>     public boolean wasNull() throws SQLException
>     {
>         return wasNullFlag;
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java String
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return the column value, null for SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public String getString(int columnIndex) throws SQLException
>     {
>         if (columnIndex < 1 || columnIndex > fields.length)
>             throw new PSQLException("postgresql.res.colrange");
>
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         Encoding encoding = connection.getEncoding();
>         return encoding.decode(this_row[columnIndex - 1]);
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java boolean
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return the column value, false for SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public boolean getBoolean(int columnIndex) throws SQLException
>     {
>         return toBoolean( getString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java byte.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public byte getByte(int columnIndex) throws SQLException
>     {
>         String s = getString(columnIndex);
>
>         if (s != null)
>         {
>             try
>             {
>                 return Byte.parseByte(s);
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException("postgresql.res.badbyte", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java short.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public short getShort(int columnIndex) throws SQLException
>     {
>         String s = getFixedString(columnIndex);
>
>         if (s != null)
>         {
>             try
>             {
>                 return Short.parseShort(s);
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException("postgresql.res.badshort", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java int.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public int getInt(int columnIndex) throws SQLException
>     {
>         return toInt( getFixedString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java long.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public long getLong(int columnIndex) throws SQLException
>     {
>         return toLong( getFixedString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java float.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public float getFloat(int columnIndex) throws SQLException
>     {
>         return toFloat( getFixedString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java double.
>      *
>      * @param columnIndex the first column is 1, the second is 2,...
>      * @return the column value; 0 if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public double getDouble(int columnIndex) throws SQLException
>     {
>         return toDouble( getFixedString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a
>      * java.math.BigDecimal object
>      *
>      * @param columnIndex  the first column is 1, the second is 2...
>      * @param scale the number of digits to the right of the decimal
>      * @return the column value; if the value is SQL NULL, null
>      * @exception SQLException if a database access error occurs
>      * @deprecated
>      */
>     public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
>     {
>         return toBigDecimal( getFixedString(columnIndex), scale );
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java byte array.
>      *
>      * <p>In normal use, the bytes represent the raw values returned by the
>      * backend. However, if the column is an OID, then it is assumed to
>      * refer to a Large Object, and that object is returned as a byte array.
>      *
>      * <p><b>Be warned</b> If the large object is huge, then you may run out
>      * of memory.
>      *
>      * @param columnIndex the first column is 1, the second is 2, ...
>      * @return the column value; if the value is SQL NULL, the result
>      *    is null
>      * @exception SQLException if a database access error occurs
>      */
>     public byte[] getBytes(int columnIndex) throws SQLException
>     {
>         if (columnIndex < 1 || columnIndex > fields.length)
>             throw new PSQLException("postgresql.res.colrange");
>
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (!wasNullFlag)
>         {
>             if (binaryCursor)
>             {
>                 //If the data is already binary then just return it
>                 return this_row[columnIndex - 1];
>             }
>             else if (connection.haveMinimumCompatibleVersion("7.2"))
>             {
>                 //Version 7.2 supports the bytea datatype for byte arrays
>                 if (fields[columnIndex - 1].getPGType().equals("bytea"))
>                 {
>                     return PGbytea.toBytes(this_row[columnIndex - 1]);
>                 }
>                 else
>                 {
>                     return this_row[columnIndex - 1];
>                 }
>             }
>             else
>             {
>                 //Version 7.1 and earlier supports LargeObjects for byte arrays
>                 // Handle OID's as BLOBS
>                 if ( fields[columnIndex - 1].getOID() == 26)
>                 {
>                     LargeObjectManager lom = connection.getLargeObjectAPI();
>                     LargeObject lob = lom.open(getInt(columnIndex));
>                     byte buf[] = lob.read(lob.size());
>                     lob.close();
>                     return buf;
>                 }
>                 else
>                 {
>                     return this_row[columnIndex - 1];
>                 }
>             }
>         }
>         return null;
>     }
>
>     /*
>      * Get the value of a column in the current row as a java.sql.Date
>      * object
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return the column value; null if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public java.sql.Date getDate(int columnIndex) throws SQLException
>     {
>         return toDate( getString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a java.sql.Time
>      * object
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return the column value; null if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public Time getTime(int columnIndex) throws SQLException
>     {
>         return toTime( getString(columnIndex) );
>     }
>
>     /*
>      * Get the value of a column in the current row as a
>      * java.sql.Timestamp object
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return the column value; null if SQL NULL
>      * @exception SQLException if a database access error occurs
>      */
>     public Timestamp getTimestamp(int columnIndex) throws SQLException
>     {
>         return toTimestamp( getString(columnIndex), this );
>     }
>
>     /*
>      * A column value can be retrieved as a stream of ASCII characters
>      * and then read in chunks from the stream.  This method is
>      * particular suitable for retrieving large LONGVARCHAR values.
>      * The JDBC driver will do any necessary conversion from the
>      * database format into ASCII.
>      *
>      * <p><B>Note:</B> All the data in the returned stream must be read
>      * prior to getting the value of any other column.    The next call
>      * to a get method implicitly closes the stream.  Also, a stream
>      * may return 0 for available() whether there is data available
>      * or not.
>      *
>      *<p> We implement an ASCII stream as a Binary stream - we should really
>      * do the data conversion, but I cannot be bothered to implement this
>      * right now.
>      *
>      * @param columnIndex the first column is 1, the second is 2, ...
>      * @return a Java InputStream that delivers the database column
>      *    value as a stream of one byte ASCII characters.  If the
>      *    value is SQL NULL then the result is null
>      * @exception SQLException if a database access error occurs
>      * @see getBinaryStream
>      */
>     public InputStream getAsciiStream(int columnIndex) throws SQLException
>     {
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         if (connection.haveMinimumCompatibleVersion("7.2"))
>         {
>             //Version 7.2 supports AsciiStream for all the PG text types
>             //As the spec/javadoc for this method indicate this is to be used for
>             //large text values (i.e. LONGVARCHAR)    PG doesn't have a separate
>             //long string datatype, but with toast the text datatype is capable of
>             //handling very large values.  Thus the implementation ends up calling
>             //getString() since there is no current way to stream the value from the server
>             try
>             {
>                 return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
>             }
>             catch (UnsupportedEncodingException l_uee)
>             {
>                 throw new PSQLException("postgresql.unusual", l_uee);
>             }
>         }
>         else
>         {
>             // In 7.1 Handle as BLOBS so return the LargeObject input stream
>             return getBinaryStream(columnIndex);
>         }
>     }
>
>     /*
>      * A column value can also be retrieved as a stream of Unicode
>      * characters. We implement this as a binary stream.
>      *
>      * ** DEPRECATED IN JDBC 2 **
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return a Java InputStream that delivers the database column value
>      *    as a stream of two byte Unicode characters.  If the value is
>      *    SQL NULL, then the result is null
>      * @exception SQLException if a database access error occurs
>      * @see getAsciiStream
>      * @see getBinaryStream
>      * @deprecated in JDBC2.0
>      */
>     public InputStream getUnicodeStream(int columnIndex) throws SQLException
>     {
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         if (connection.haveMinimumCompatibleVersion("7.2"))
>         {
>             //Version 7.2 supports AsciiStream for all the PG text types
>             //As the spec/javadoc for this method indicate this is to be used for
>             //large text values (i.e. LONGVARCHAR)    PG doesn't have a separate
>             //long string datatype, but with toast the text datatype is capable of
>             //handling very large values.  Thus the implementation ends up calling
>             //getString() since there is no current way to stream the value from the server
>             try
>             {
>                 return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
>             }
>             catch (UnsupportedEncodingException l_uee)
>             {
>                 throw new PSQLException("postgresql.unusual", l_uee);
>             }
>         }
>         else
>         {
>             // In 7.1 Handle as BLOBS so return the LargeObject input stream
>             return getBinaryStream(columnIndex);
>         }
>     }
>
>     /*
>      * A column value can also be retrieved as a binary strea.    This
>      * method is suitable for retrieving LONGVARBINARY values.
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return a Java InputStream that delivers the database column value
>      * as a stream of bytes.  If the value is SQL NULL, then the result
>      * is null
>      * @exception SQLException if a database access error occurs
>      * @see getAsciiStream
>      * @see getUnicodeStream
>      */
>     public InputStream getBinaryStream(int columnIndex) throws SQLException
>     {
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         if (connection.haveMinimumCompatibleVersion("7.2"))
>         {
>             //Version 7.2 supports BinaryStream for all PG bytea type
>             //As the spec/javadoc for this method indicate this is to be used for
>             //large binary values (i.e. LONGVARBINARY)    PG doesn't have a separate
>             //long binary datatype, but with toast the bytea datatype is capable of
>             //handling very large values.  Thus the implementation ends up calling
>             //getBytes() since there is no current way to stream the value from the server
>             byte b[] = getBytes(columnIndex);
>             if (b != null)
>                 return new ByteArrayInputStream(b);
>         }
>         else
>         {
>             // In 7.1 Handle as BLOBS so return the LargeObject input stream
>             if ( fields[columnIndex - 1].getOID() == 26)
>             {
>                 LargeObjectManager lom = connection.getLargeObjectAPI();
>                 LargeObject lob = lom.open(getInt(columnIndex));
>                 return lob.getInputStream();
>             }
>         }
>         return null;
>     }
>
>     /*
>      * The following routines simply convert the columnName into
>      * a columnIndex and then call the appropriate routine above.
>      *
>      * @param columnName is the SQL name of the column
>      * @return the column value
>      * @exception SQLException if a database access error occurs
>      */
>     public String getString(String columnName) throws SQLException
>     {
>         return getString(findColumn(columnName));
>     }
>
>     public boolean getBoolean(String columnName) throws SQLException
>     {
>         return getBoolean(findColumn(columnName));
>     }
>
>     public byte getByte(String columnName) throws SQLException
>     {
>
>         return getByte(findColumn(columnName));
>     }
>
>     public short getShort(String columnName) throws SQLException
>     {
>         return getShort(findColumn(columnName));
>     }
>
>     public int getInt(String columnName) throws SQLException
>     {
>         return getInt(findColumn(columnName));
>     }
>
>     public long getLong(String columnName) throws SQLException
>     {
>         return getLong(findColumn(columnName));
>     }
>
>     public float getFloat(String columnName) throws SQLException
>     {
>         return getFloat(findColumn(columnName));
>     }
>
>     public double getDouble(String columnName) throws SQLException
>     {
>         return getDouble(findColumn(columnName));
>     }
>
>     /*
>      * @deprecated
>      */
>     public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException
>     {
>         return getBigDecimal(findColumn(columnName), scale);
>     }
>
>     public byte[] getBytes(String columnName) throws SQLException
>     {
>         return getBytes(findColumn(columnName));
>     }
>
>     public java.sql.Date getDate(String columnName) throws SQLException
>     {
>         return getDate(findColumn(columnName));
>     }
>
>     public Time getTime(String columnName) throws SQLException
>     {
>         return getTime(findColumn(columnName));
>     }
>
>     public Timestamp getTimestamp(String columnName) throws SQLException
>     {
>         return getTimestamp(findColumn(columnName));
>     }
>
>     public InputStream getAsciiStream(String columnName) throws SQLException
>     {
>         return getAsciiStream(findColumn(columnName));
>     }
>
>     /*
>      *
>      * ** DEPRECATED IN JDBC 2 **
>      *
>      * @deprecated
>      */
>     public InputStream getUnicodeStream(String columnName) throws SQLException
>     {
>         return getUnicodeStream(findColumn(columnName));
>     }
>
>     public InputStream getBinaryStream(String columnName) throws SQLException
>     {
>         return getBinaryStream(findColumn(columnName));
>     }
>
>     /*
>      * The first warning reported by calls on this ResultSet is
>      * returned.  Subsequent ResultSet warnings will be chained
>      * to this SQLWarning.
>      *
>      * <p>The warning chain is automatically cleared each time a new
>      * row is read.
>      *
>      * <p><B>Note:</B> This warning chain only covers warnings caused by
>      * ResultSet methods.  Any warnings caused by statement methods
>      * (such as reading OUT parameters) will be chained on the
>      * Statement object.
>      *
>      * @return the first SQLWarning or null;
>      * @exception SQLException if a database access error occurs.
>      */
>     public SQLWarning getWarnings() throws SQLException
>     {
>         return warnings;
>     }
>
>     /*
>      * After this call, getWarnings returns null until a new warning
>      * is reported for this ResultSet
>      *
>      * @exception SQLException if a database access error occurs
>      */
>     public void clearWarnings() throws SQLException
>     {
>         warnings = null;
>     }
>
>     /*
>      * Get the name of the SQL cursor used by this ResultSet
>      *
>      * <p>In SQL, a result table is retrieved though a cursor that is
>      * named.  The current row of a result can be updated or deleted
>      * using a positioned update/delete statement that references
>      * the cursor name.
>      *
>      * <p>JDBC supports this SQL feature by providing the name of the
>      * SQL cursor used by a ResultSet.    The current row of a ResulSet
>      * is also the current row of this SQL cursor.
>      *
>      * <p><B>Note:</B> If positioned update is not supported, a SQLException
>      * is thrown.
>      *
>      * @return the ResultSet's SQL cursor name.
>      * @exception SQLException if a database access error occurs
>      */
>     public String getCursorName() throws SQLException
>     {
>         return connection.getCursorName();
>     }
>
>     /*
>      * The numbers, types and properties of a ResultSet's columns are
>      * provided by the getMetaData method
>      *
>      * @return a description of the ResultSet's columns
>      * @exception SQLException if a database access error occurs
>      */
>     public java.sql.ResultSetMetaData getMetaData() throws SQLException
>     {
>         return new ResultSetMetaData(rows, fields);
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java object
>      *
>      * <p>This method will return the value of the given column as a
>      * Java object.  The type of the Java object will be the default
>      * Java Object type corresponding to the column's SQL type, following
>      * the mapping specified in the JDBC specification.
>      *
>      * <p>This method may also be used to read database specific abstract
>      * data types.
>      *
>      * @param columnIndex the first column is 1, the second is 2...
>      * @return a Object holding the column value
>      * @exception SQLException if a database access error occurs
>      */
>     public Object getObject(int columnIndex) throws SQLException
>     {
>         Field field;
>
>         if (columnIndex < 1 || columnIndex > fields.length)
>             throw new PSQLException("postgresql.res.colrange");
>
>         wasNullFlag = (this_row[columnIndex - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         field = fields[columnIndex - 1];
>
>         // some fields can be null, mainly from those returned by MetaData methods
>         if (field == null)
>         {
>             wasNullFlag = true;
>             return null;
>         }
>
>         switch (field.getSQLType())
>         {
>             case Types.BIT:
>                 return new Boolean(getBoolean(columnIndex));
>             case Types.SMALLINT:
>                 return new Integer(getInt(columnIndex));
>             case Types.INTEGER:
>                 return new Integer(getInt(columnIndex));
>             case Types.BIGINT:
>                 return new Long(getLong(columnIndex));
>             case Types.NUMERIC:
>                 return getBigDecimal
>                        (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff));
>             case Types.REAL:
>                 return new Float(getFloat(columnIndex));
>             case Types.DOUBLE:
>                 return new Double(getDouble(columnIndex));
>             case Types.CHAR:
>             case Types.VARCHAR:
>                 return getString(columnIndex);
>             case Types.DATE:
>                 return getDate(columnIndex);
>             case Types.TIME:
>                 return getTime(columnIndex);
>             case Types.TIMESTAMP:
>                 return getTimestamp(columnIndex);
>             case Types.BINARY:
>             case Types.VARBINARY:
>                 return getBytes(columnIndex);
>             default:
>                 String type = field.getPGType();
>                 // if the backend doesn't know the type then coerce to String
>                 if (type.equals("unknown"))
>                 {
>                     return getString(columnIndex);
>                 }
>                 else
>                 {
>                     return connection.getObject(field.getPGType(), getString(columnIndex));
>                 }
>         }
>     }
>
>     /*
>      * Get the value of a column in the current row as a Java object
>      *
>      *<p> This method will return the value of the given column as a
>      * Java object.  The type of the Java object will be the default
>      * Java Object type corresponding to the column's SQL type, following
>      * the mapping specified in the JDBC specification.
>      *
>      * <p>This method may also be used to read database specific abstract
>      * data types.
>      *
>      * @param columnName is the SQL name of the column
>      * @return a Object holding the column value
>      * @exception SQLException if a database access error occurs
>      */
>     public Object getObject(String columnName) throws SQLException
>     {
>         return getObject(findColumn(columnName));
>     }
>
>     /*
>      * Map a ResultSet column name to a ResultSet column index
>      *
>      * @param columnName the name of the column
>      * @return the column index
>      * @exception SQLException if a database access error occurs
>      */
>     public int findColumn(String columnName) throws SQLException
>     {
>         int i;
>
>         final int flen = fields.length;
>         for (i = 0 ; i < flen; ++i)
>             if (fields[i].getName().equalsIgnoreCase(columnName))
>                 return (i + 1);
>         throw new PSQLException ("postgresql.res.colname", columnName);
>     }
>
>     // ** JDBC 2 Extensions **
>
>     public boolean absolute(int index) throws SQLException
>     {
>         // index is 1-based, but internally we use 0-based indices
>         int internalIndex;
>
>         if (index == 0)
>             throw new SQLException("Cannot move to index of 0");
>
>         final int rows_size = rows.size();
>
>         //if index<0, count from the end of the result set, but check
>         //to be sure that it is not beyond the first index
>         if (index < 0)
>         {
>             if (index >= -rows_size)
>                 internalIndex = rows_size + index;
>             else
>             {
>                 beforeFirst();
>                 return false;
>             }
>         }
>         else
>         {
>             //must be the case that index>0,
>             //find the correct place, assuming that
>             //the index is not too large
>             if (index <= rows_size)
>                 internalIndex = index - 1;
>             else
>             {
>                 afterLast();
>                 return false;
>             }
>         }
>
>         current_row = internalIndex;
>         this_row = (byte [][])rows.elementAt(internalIndex);
>         return true;
>     }
>
>     public void afterLast() throws SQLException
>     {
>         final int rows_size = rows.size();
>         if (rows_size > 0)
>             current_row = rows_size;
>     }
>
>     public void beforeFirst() throws SQLException
>     {
>         if (rows.size() > 0)
>             current_row = -1;
>     }
>
>     public void cancelRowUpdates() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void deleteRow() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public boolean first() throws SQLException
>     {
>         if (rows.size() <= 0)
>             return false;
>         current_row = 0;
>         this_row = (byte [][])rows.elementAt(current_row);
>         return true;
>     }
>
>     public java.sql.Array getArray(String colName) throws SQLException
>     {
>         return getArray(findColumn(colName));
>     }
>
>     public java.sql.Array getArray(int i) throws SQLException
>     {
>         wasNullFlag = (this_row[i - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         if (i < 1 || i > fields.length)
>             throw new PSQLException("postgresql.res.colrange");
>         return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], this );
>     }
>
>     public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException
>     {
>         return getBigDecimal(columnIndex, -1);
>     }
>
>     public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException
>     {
>         return getBigDecimal(findColumn(columnName));
>     }
>
>     public Blob getBlob(String columnName) throws SQLException
>     {
>         return getBlob(findColumn(columnName));
>     }
>
>     public Blob getBlob(int i) throws SQLException
>     {
>         return new org.postgresql.largeobject.PGblob(connection, getInt(i));
>     }
>
>     public java.io.Reader getCharacterStream(String columnName) throws SQLException
>     {
>         return getCharacterStream(findColumn(columnName));
>     }
>
>     public java.io.Reader getCharacterStream(int i) throws SQLException
>     {
>         wasNullFlag = (this_row[i - 1] == null);
>         if (wasNullFlag)
>             return null;
>
>         if (connection.haveMinimumCompatibleVersion("7.2"))
>         {
>             //Version 7.2 supports AsciiStream for all the PG text types
>             //As the spec/javadoc for this method indicate this is to be used for
>             //large text values (i.e. LONGVARCHAR)    PG doesn't have a separate
>             //long string datatype, but with toast the text datatype is capable of
>             //handling very large values.  Thus the implementation ends up calling
>             //getString() since there is no current way to stream the value from the server
>             return new CharArrayReader(getString(i).toCharArray());
>         }
>         else
>         {
>             // In 7.1 Handle as BLOBS so return the LargeObject input stream
>             Encoding encoding = connection.getEncoding();
>             InputStream input = getBinaryStream(i);
>             return encoding.getDecodingReader(input);
>         }
>     }
>
>     /*
>      * New in 7.1
>      */
>     public Clob getClob(String columnName) throws SQLException
>     {
>         return getClob(findColumn(columnName));
>     }
>
>     /*
>      * New in 7.1
>      */
>     public Clob getClob(int i) throws SQLException
>     {
>         return new org.postgresql.largeobject.PGclob(connection, getInt(i));
>     }
>
>     public int getConcurrency() throws SQLException
>     {
>         // New in 7.1 - The standard ResultSet class will now return
>         // CONCUR_READ_ONLY. A sub-class will overide this if the query was
>         // updateable.
>         return CONCUR_READ_ONLY;
>     }
>
>     public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException
>     {
>         // new in 7.1: If I read the specs, this should use cal only if we don't
>         // store the timezone, and if we do, then act just like getDate()?
>         // for now...
>         return getDate(i);
>     }
>
>     public Time getTime(int i, java.util.Calendar cal) throws SQLException
>     {
>         // new in 7.1: If I read the specs, this should use cal only if we don't
>         // store the timezone, and if we do, then act just like getTime()?
>         // for now...
>         return getTime(i);
>     }
>
>     public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException
>     {
>         // new in 7.1: If I read the specs, this should use cal only if we don't
>         // store the timezone, and if we do, then act just like getDate()?
>         // for now...
>         return getTimestamp(i);
>     }
>
>     public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException
>     {
>         return getDate(findColumn(c), cal);
>     }
>
>     public Time getTime(String c, java.util.Calendar cal) throws SQLException
>     {
>         return getTime(findColumn(c), cal);
>     }
>
>     public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException
>     {
>         return getTimestamp(findColumn(c), cal);
>     }
>
>     public int getFetchDirection() throws SQLException
>     {
>         // new in 7.1: PostgreSQL normally sends rows first->last
>         return FETCH_FORWARD;
>     }
>
>     public int getFetchSize() throws SQLException
>     {
>         // new in 7.1: In this implementation we return the entire result set, so
>         // here return the number of rows we have. Sub-classes can return a proper
>         // value
>         return rows.size();
>     }
>
>     public Object getObject(String columnName, java.util.Map map) throws SQLException
>     {
>         return getObject(findColumn(columnName), map);
>     }
>
>     /*
>      * This checks against map for the type of column i, and if found returns
>      * an object based on that mapping. The class must implement the SQLData
>      * interface.
>      */
>     public Object getObject(int i, java.util.Map map) throws SQLException
>     {
>         /* In preparation
>         SQLInput s = new PSQLInput(this,i);
>         String t = getTypeName(i);
>         SQLData o = (SQLData) map.get(t);
>         // If the type is not in the map, then pass to the existing code
>         if (o==null)
>           return getObject(i);
>         o.readSQL(s,t);
>         return o;
>         */throw org.postgresql.Driver.notImplemented();
>     }
>
>     public Ref getRef(String columnName) throws SQLException
>     {
>         return getRef(findColumn(columnName));
>     }
>
>     public Ref getRef(int i) throws SQLException
>     {
>         // new in 7.1: The backend doesn't yet have SQL3 REF types
>         throw new PSQLException("postgresql.psqlnotimp");
>     }
>
>     public int getRow() throws SQLException
>     {
>         final int rows_size = rows.size();
>
>         if (current_row < 0 || current_row >= rows_size)
>             return 0;
>
>         return current_row + 1;
>     }
>
>     // This one needs some thought, as not all ResultSets come from a statement
>     public java.sql.Statement getStatement() throws SQLException
>     {
>         return statement;
>     }
>
>     public int getType() throws SQLException
>     {
>         // New in 7.1. This implementation allows scrolling but is not able to
>         // see any changes. Sub-classes may overide this to return a more
>         // meaningful result.
>         return TYPE_SCROLL_INSENSITIVE;
>     }
>
>     public void insertRow() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public boolean isAfterLast() throws SQLException
>     {
>         final int rows_size = rows.size();
>         return (current_row >= rows_size && rows_size > 0);
>     }
>
>     public boolean isBeforeFirst() throws SQLException
>     {
>         return (current_row < 0 && rows.size() > 0);
>     }
>
>     public boolean isFirst() throws SQLException
>     {
>         return (current_row == 0 && rows.size() >= 0);
>     }
>
>     public boolean isLast() throws SQLException
>     {
>         final int rows_size = rows.size();
>         return (current_row == rows_size - 1 && rows_size > 0);
>     }
>
>     public boolean last() throws SQLException
>     {
>         final int rows_size = rows.size();
>         if (rows_size <= 0)
>             return false;
>         current_row = rows_size - 1;
>         this_row = (byte [][])rows.elementAt(current_row);
>         return true;
>     }
>
>     public void moveToCurrentRow() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void moveToInsertRow() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public boolean previous() throws SQLException
>     {
>         if (--current_row < 0)
>             return false;
>         this_row = (byte [][])rows.elementAt(current_row);
>         return true;
>     }
>
>     public void refreshRow() throws SQLException
>     {
>         throw new PSQLException("postgresql.notsensitive");
>     }
>
>     // Peter: Implemented in 7.0
>     public boolean relative(int rows) throws SQLException
>     {
>         //have to add 1 since absolute expects a 1-based index
>         return absolute(current_row + 1 + rows);
>     }
>
>     public boolean rowDeleted() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>         return false; // javac complains about not returning a value!
>     }
>
>     public boolean rowInserted() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>         return false; // javac complains about not returning a value!
>     }
>
>     public boolean rowUpdated() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>         return false; // javac complains about not returning a value!
>     }
>
>     public void setFetchDirection(int direction) throws SQLException
>     {
>         // In 7.1, the backend doesn't yet support this
>         throw new PSQLException("postgresql.psqlnotimp");
>     }
>
>     public void setFetchSize(int rows) throws SQLException
>     {
>         // Sub-classes should implement this as part of their cursor support
>         throw org.postgresql.Driver.notImplemented();
>     }
>
>     public void updateAsciiStream(int columnIndex,
>                                   java.io.InputStream x,
>                                   int length
>                                  ) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateAsciiStream(String columnName,
>                                   java.io.InputStream x,
>                                   int length
>                                  ) throws SQLException
>     {
>         updateAsciiStream(findColumn(columnName), x, length);
>     }
>
>     public void updateBigDecimal(int columnIndex,
>                                  java.math.BigDecimal x
>                                 ) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateBigDecimal(String columnName,
>                                  java.math.BigDecimal x
>                                 ) throws SQLException
>     {
>         updateBigDecimal(findColumn(columnName), x);
>     }
>
>     public void updateBinaryStream(int columnIndex,
>                                    java.io.InputStream x,
>                                    int length
>                                   ) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateBinaryStream(String columnName,
>                                    java.io.InputStream x,
>                                    int length
>                                   ) throws SQLException
>     {
>         updateBinaryStream(findColumn(columnName), x, length);
>     }
>
>     public void updateBoolean(int columnIndex, boolean x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateBoolean(String columnName, boolean x) throws SQLException
>     {
>         updateBoolean(findColumn(columnName), x);
>     }
>
>     public void updateByte(int columnIndex, byte x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateByte(String columnName, byte x) throws SQLException
>     {
>         updateByte(findColumn(columnName), x);
>     }
>
>     public void updateBytes(String columnName, byte[] x) throws SQLException
>     {
>         updateBytes(findColumn(columnName), x);
>     }
>
>     public void updateBytes(int columnIndex, byte[] x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateCharacterStream(int columnIndex,
>                                       java.io.Reader x,
>                                       int length
>                                      ) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateCharacterStream(String columnName,
>                                       java.io.Reader x,
>                                       int length
>                                      ) throws SQLException
>     {
>         updateCharacterStream(findColumn(columnName), x, length);
>     }
>
>     public void updateDate(int columnIndex, java.sql.Date x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateDate(String columnName, java.sql.Date x) throws SQLException
>     {
>         updateDate(findColumn(columnName), x);
>     }
>
>     public void updateDouble(int columnIndex, double x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateDouble(String columnName, double x) throws SQLException
>     {
>         updateDouble(findColumn(columnName), x);
>     }
>
>     public void updateFloat(int columnIndex, float x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateFloat(String columnName, float x) throws SQLException
>     {
>         updateFloat(findColumn(columnName), x);
>     }
>
>     public void updateInt(int columnIndex, int x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateInt(String columnName, int x) throws SQLException
>     {
>         updateInt(findColumn(columnName), x);
>     }
>
>     public void updateLong(int columnIndex, long x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateLong(String columnName, long x) throws SQLException
>     {
>         updateLong(findColumn(columnName), x);
>     }
>
>     public void updateNull(int columnIndex) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateNull(String columnName) throws SQLException
>     {
>         updateNull(findColumn(columnName));
>     }
>
>     public void updateObject(int columnIndex, Object x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateObject(String columnName, Object x) throws SQLException
>     {
>         updateObject(findColumn(columnName), x);
>     }
>
>     public void updateObject(int columnIndex, Object x, int scale) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateObject(String columnName, Object x, int scale) throws SQLException
>     {
>         updateObject(findColumn(columnName), x, scale);
>     }
>
>     public void updateRow() throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateShort(int columnIndex, short x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateShort(String columnName, short x) throws SQLException
>     {
>         updateShort(findColumn(columnName), x);
>     }
>
>     public void updateString(int columnIndex, String x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateString(String columnName, String x) throws SQLException
>     {
>         updateString(findColumn(columnName), x);
>     }
>
>     public void updateTime(int columnIndex, Time x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateTime(String columnName, Time x) throws SQLException
>     {
>         updateTime(findColumn(columnName), x);
>     }
>
>     public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException
>     {
>         // only sub-classes implement CONCUR_UPDATEABLE
>         notUpdateable();
>     }
>
>     public void updateTimestamp(String columnName, Timestamp x) throws SQLException
>     {
>         updateTimestamp(findColumn(columnName), x);
>     }
>
>     // helper method. Throws an SQLException when an update is not possible
>     public void notUpdateable() throws SQLException
>     {
>         throw new PSQLException("postgresql.noupdate");
>     }
>
>     /*
>      * This is called by Statement to register itself with this statement.
>      * It's used currently by getStatement() but may also with the new core
>      * package.
>      */
>     public void setStatement(org.postgresql.jdbc2.Statement statement)
>     {
>         this.statement = statement;
>     }
>
>     //----------------- Formatting Methods -------------------
>
>     public static boolean toBoolean(String s)
>     {
>         if (s != null)
>         {
>             int c = s.charAt(0);
>             return ((c == 't') || (c == 'T') || (c == '1'));
>         }
>         return false;        // SQL NULL
>     }
>
>     public static int toInt(String s) throws SQLException
>     {
>         if (s != null)
>         {
>             try
>             {
>                 return Integer.parseInt(s);
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException ("postgresql.res.badint", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     public static long toLong(String s) throws SQLException
>     {
>         if (s != null)
>         {
>             try
>             {
>                 return Long.parseLong(s);
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException ("postgresql.res.badlong", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     public static BigDecimal toBigDecimal(String s, int scale) throws SQLException
>     {
>         BigDecimal val;
>         if (s != null)
>         {
>             try
>             {
>                 val = new BigDecimal(s);
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException ("postgresql.res.badbigdec", s);
>             }
>             if (scale == -1)
>                 return val;
>             try
>             {
>                 return val.setScale(scale);
>             }
>             catch (ArithmeticException e)
>             {
>                 throw new PSQLException ("postgresql.res.badbigdec", s);
>             }
>         }
>         return null;        // SQL NULL
>     }
>
>     public static float toFloat(String s) throws SQLException
>     {
>         if (s != null)
>         {
>             try
>             {
>                 return Float.valueOf(s).floatValue();
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException ("postgresql.res.badfloat", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     public static double toDouble(String s) throws SQLException
>     {
>         if (s != null)
>         {
>             try
>             {
>                 return Double.valueOf(s).doubleValue();
>             }
>             catch (NumberFormatException e)
>             {
>                 throw new PSQLException ("postgresql.res.baddouble", s);
>             }
>         }
>         return 0;        // SQL NULL
>     }
>
>     public static java.sql.Date toDate(String s) throws SQLException
>     {
>         if (s == null)
>             return null;
>         // length == 10: SQL Date
>         // length >  10: SQL Timestamp, assumes PGDATESTYLE=ISO
>         try
>         {
>             return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10));
>         }
>         catch (NumberFormatException e)
>         {
>             throw new PSQLException("postgresql.res.baddate", s);
>         }
>     }
>
>     public static Time toTime(String s) throws SQLException
>     {
>         if (s == null)
>             return null; // SQL NULL
>         // length == 8: SQL Time
>         // length >  8: SQL Timestamp
>         try
>         {
>             return java.sql.Time.valueOf((s.length() == 8) ? s : s.substring(11, 19));
>         }
>         catch (NumberFormatException e)
>         {
>             throw new PSQLException("postgresql.res.badtime", s);
>         }
>     }
>
>     /**
>     * Parse a string and return a timestamp representing its value.
>     *
>     * The driver is set to return ISO date formated strings. We modify this
>     * string from the ISO format to a format that Java can understand. Java
>     * expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
>     * Java also expects fractional seconds to 3 places where postgres
>     * will give, none, 2 or 6 depending on the time and postgres version.
>     * From version 7.2 postgres returns fractional seconds to 6 places.
>     * If available, we drop the last 3 digits.
>     *
>     * @param s         The ISO formated date string to parse.
>     * @param resultSet The ResultSet this date is part of.
>     *
>     * @return null if s is null or a timestamp of the parsed string s.
>     *
>     * @throws SQLException if there is a problem parsing s.
>     **/
>     public static Timestamp toTimestamp(String s, ResultSet resultSet)
>     throws SQLException
>     {
>         if (s == null)
>             return null;
>
>         // We must be synchronized here incase more theads access the ResultSet
>         // bad practice but possible. Anyhow this is to protect sbuf and
>         // SimpleDateFormat objects
>         synchronized (resultSet)
>         {
>             SimpleDateFormat df = null;
>             StringBuffer nanos= new StringBuffer();
>             nanos.setLength(0);
>             // If first time, create the buffer, otherwise clear it.
>             if (resultSet.sbuf == null)
>                 resultSet.sbuf = new StringBuffer();
>             else
>                 resultSet.sbuf.setLength(0);
>             // Copy s into sbuf for parsing.
>             resultSet.sbuf.append(s);
>             if (s.length() > 19)
>             {
>                 // The len of the ISO string to the second value is 19 chars. If
>                 // greater then 19, there should be tz info and perhaps fractional
>                 // second info which we need to change to java to read it.
>
>                 // cut the copy to second value "2001-12-07 16:29:22"
>                 int i = 19;
>                 resultSet.sbuf.setLength(i);
>                 char c = s.charAt(i++);
>                 if (c == '.')
>                 {
>                     // Found a fractional value. Append up to 6 digits including
>                     // the leading '.'
>                     do
>                     {
>                         if (i < 27) {
>                             resultSet.sbuf.append(c);
>                             c = s.charAt(i++);
>                             if(Character.isDigit(c))
>                               nanos.append(c);
>                         }
>                         if(i>=s.length()) {
>                             break;
>                         }
>                     } while (Character.isDigit(c));
>
>                     // If there wasn't at least 6 digits we should add some zeros
>                     // to make up the 6 digits we tell java to expect.
>                     for (int j = i; j < 27; j++)
>                         resultSet.sbuf.append('0');
>                 }
>                 else
>                 {
>                     // No fractional seconds, lets add some.
>                     resultSet.sbuf.append(".000000");
>                 }
>
>                 // prepend the GMT part and then add the remaining bit of
>                 // the string.
>                 resultSet.sbuf.append(" GMT");
>                 resultSet.sbuf.append(c);
>                 resultSet.sbuf.append(s.substring(i, s.length()));
>
>                 // Lastly, if the tz part doesn't specify the :MM part then
>                 // we add ":00" for java.
>                 if (s.length() - i < 5)
>                     resultSet.sbuf.append(":00");
>                 // we'll use this dateformat string to parse the result.
>                 df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS z");
>             }
>             else if (s.length() == 19)
>             {
>                 // No tz or fractional second info.
>                 // I'm not sure if it is
>                 // possible to have a string in this format, as pg
>                 // should give us tz qualified timestamps back, but it was
>                 // in the old code, so I'm handling it for now.
>                 df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
>             }
>             else
>             {
>                 // We must just have a date. This case is
>                 // needed if this method is called on a date
>                 // column
>                 df = new SimpleDateFormat("yyyy-MM-dd");
>             }
>
>             try
>             {
>                 // All that's left is to parse the string and return the ts.
>                 Timestamp t = new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
>                 if(nanos.length()>0) {
>                  Integer k = Integer.valueOf(nanos.toString());
>                  t.setNanos(k.intValue());
>                 }
>                 return t;
>             }
>             catch (ParseException e)
>             {
>                 throw new PSQLException("postgresql.res.badtimestamp", new Integer(e.getErrorOffset()), s);
>             }
>         }
>     }
> }
>
>
>
> ------------------------------------------------------------------------
>
>
> ------------------------------------------------------------------------
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html



pgsql-jdbc by date:

Previous
From: Auri Mason
Date:
Subject: Re: getColumns() - workaround
Next
From: Auri Mason
Date:
Subject: Re: getColumns() - workaround