Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/hsqldb/jdbcResultSet.java


1   /* Copyrights and Licenses
2    *
3    * This product includes Hypersonic SQL.
4    * Originally developed by Thomas Mueller and the Hypersonic SQL Group. 
5    *
6    * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. 
7    * Redistribution and use in source and binary forms, with or without modification, are permitted
8    * provided that the following conditions are met: 
9    *     -  Redistributions of source code must retain the above copyright notice, this list of conditions
10   *         and the following disclaimer. 
11   *     -  Redistributions in binary form must reproduce the above copyright notice, this list of
12   *         conditions and the following disclaimer in the documentation and/or other materials
13   *         provided with the distribution. 
14   *     -  All advertising materials mentioning features or use of this software must display the
15   *        following acknowledgment: "This product includes Hypersonic SQL." 
16   *     -  Products derived from this software may not be called "Hypersonic SQL" nor may
17   *        "Hypersonic SQL" appear in their names without prior written permission of the
18   *         Hypersonic SQL Group. 
19   *     -  Redistributions of any form whatsoever must retain the following acknowledgment: "This
20   *          product includes Hypersonic SQL." 
21   * This software is provided "as is" and any expressed or implied warranties, including, but
22   * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23   * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24   * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25   * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26   * or business interruption). However caused any on any theory of liability, whether in contract,
27   * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this
28   * software, even if advised of the possibility of such damage. 
29   * This software consists of voluntary contributions made by many individuals on behalf of the
30   * Hypersonic SQL Group.
31   *
32   *
33   * For work added by the HSQL Development Group:
34   *
35   * Copyright (c) 2001-2002, The HSQL Development Group
36   * All rights reserved.
37   *
38   * Redistribution and use in source and binary forms, with or without
39   * modification, are permitted provided that the following conditions are met:
40   *
41   * Redistributions of source code must retain the above copyright notice, this
42   * list of conditions and the following disclaimer, including earlier
43   * license statements (above) and comply with all above license conditions.
44   *
45   * Redistributions in binary form must reproduce the above copyright notice,
46   * this list of conditions and the following disclaimer in the documentation
47   * and/or other materials provided with the distribution, including earlier
48   * license statements (above) and comply with all above license conditions.
49   *
50   * Neither the name of the HSQL Development Group nor the names of its
51   * contributors may be used to endorse or promote products derived from this
52   * software without specific prior written permission.
53   *
54   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57   * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
58   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
59   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
60   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65   */
66  
67  
68  package org.hsqldb;
69  
70  import java.io.ByteArrayInputStream;
71  import java.io.InputStream;
72  import java.io.Reader;
73  import java.io.StringReader;
74  import java.math.BigDecimal;
75  import java.sql.*;     // for Array, Blob, Clob, Ref
76  import java.sql.ResultSet;
77  import java.sql.ResultSetMetaData;
78  import java.sql.SQLException;
79  import java.sql.Statement;
80  import java.sql.Time;
81  import java.sql.Timestamp;
82  import java.sql.Types;
83  import java.sql.SQLWarning;
84  import java.util.*;    // for Map
85  import java.util.Calendar;
86  import org.hsqldb.lib.AsciiStringInputStream;
87  import org.hsqldb.lib.StringInputStream;
88  
89  // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
90  // JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
91  // SCROLL_INSENSITIVE and FORWARD_ONLY types for ResultSet are now supported
92  // fredt@users 20020315 - patch 497714 by lakuhns@users - scrollable ResultSet
93  // all absolute and relative positioning methods defined
94  // boucherb@users 20020409 - added "throws SQLException" to all methods where
95  // it was missing here but specified in the java.sql.ResultSet and
96  // java.sql.ResultSetMetaData interfaces, updated generic documentation to
97  // JDK 1.4, and added JDBC3 methods and docs
98  // boucherb@users and fredt@users 20020409/20020505 extensive review and update
99  // of docs and behaviour to comply with previous and latest java.sql specification
100 // tony_lai@users 20020820 - patch 595073 by tlai@users - duplicated exception msg
101 
102 /**
103  * Implements both the <CODE>java.sql.ResultSet</CODE> and
104  * <CODE>java.sql.ResultSetMetaData</CODE> interfaces. <p>
105  *
106  * <span class="ReleaseSpecificDocumentation">
107  * In short: <p>
108  *
109  * <UL>
110  * <LI>A <code>ResultSet</code> object is essentially--but not limited to
111  *    being--a table of data representing a database result set, which
112  *    is usually generated by executing a statement that queries the
113  *    database.</LI>
114  * <LI>A <CODE>ResultSetMetaData</CODE> object is one that can be used to
115  *    get information about the types and properties of the columns in a
116  *    <code>ResultSet</code> object.</LI>
117  * </UL>
118  * <p>
119  *
120  * The following is composed of three sections:
121  * <OL>
122  * <LI>The generic overview for <CODE>ResultSet</CODE>.</LI>
123  * <LI>The generic overview for <CODE>ResultSetMetaData</CODE>.</LI>
124  * <LI>A discussion of some HSQLDB-specific concerns.</LI>
125  * </OL>
126  * </span> <p>
127  * <!-- end Release-specific documentation -->
128  *
129  * <!-- start java.sql.ResultSet generaic documentation -->
130  * <B>From <CODE>ResultSet</CODE>:</B><p>
131  *
132  * A table of data representing a database result set, which
133  * is usually generated by executing a statement that queries the database.
134  *
135  * <P>A <code>ResultSet</code> object  maintains a cursor pointing
136  * to its current row of data.  Initially the cursor is positioned
137  * before the first row. The <code>next</code> method moves the
138  * cursor to the next row, and because it returns <code>false</code>
139  * when there are no more rows in the <code>ResultSet</code> object,
140  * it can be used in a <code>while</code> loop to iterate through
141  * the result set.
142  * <P>
143  * A default <code>ResultSet</code> object is not updatable and
144  * has a cursor that moves forward only.  Thus, you can
145  * iterate through it only once and only from the first row to the
146  * last row. It is possible to
147  * produce <code>ResultSet</code> objects that are scrollable and/or
148  * updatable.  The following code fragment, in which <code>con</code>
149  * is a valid <code>Connection</code> object, illustrates how to make
150  * a result set that is scrollable and insensitive to updates by others,
151  * and that is updatable. See <code>ResultSet</code> fields for other
152  * options.
153  * <PRE>
154  *
155  * Statement stmt = con.createStatement(
156  *                            ResultSet.TYPE_SCROLL_INSENSITIVE,
157  *                            ResultSet.CONCUR_UPDATABLE);
158  * ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
159  * // rs will be scrollable, will not show changes made by others,
160  * // and will be updatable
161  *
162  * </PRE>
163  * The <code>ResultSet</code> interface provides
164  * <i>getter</i> methods (<code>getBoolean</code>, <code>getLong</code>,
165  * and so on) for retrieving column values from the current row.
166  * Values can be retrieved using either the index number of the
167  * column or the name of the column.  In general, using the
168  * column index will be more efficient.  Columns are numbered from 1.
169  * For maximum portability, result set columns within each row should be
170  * read in left-to-right order, and each column should be read only once.
171  *
172  * <P>For the getter methods, a JDBC driver attempts
173  * to convert the underlying data to the Java type specified in the
174  * getter method and returns a suitable Java value.  The JDBC specification
175  * has a table showing the allowable mappings from SQL types to Java types
176  * that can be used by the <code>ResultSet</code> getter methods.
177  * <P>
178  * <P>Column names used as input to getter methods are case
179  * insensitive.  When a getter method is called  with
180  * a column name and several columns have the same name,
181  * the value of the first matching column will be returned.
182  * The column name option is
183  * designed to be used when column names are used in the SQL
184  * query that generated the result set.
185  * For columns that are NOT explicitly named in the query, it
186  * is best to use column numbers. If column names are used, there is
187  * no way for the programmer to guarantee that they actually refer to
188  * the intended columns.
189  * <P>
190  * A set of updater methods were added to this interface
191  * in the JDBC 2.0 API (Java<sup><font size=-2>TM</font></sup> 2 SDK,
192  * Standard Edition, version 1.2). The comments regarding parameters
193  * to the getter methods also apply to parameters to the
194  * updater methods.
195  * <P>
196  * The updater methods may be used in two ways:
197  * <ol>
198  * <LI>to update a column value in the current row.  In a scrollable
199  * <code>ResultSet</code> object, the cursor can be moved backwards
200  * and forwards, to an absolute position, or to a position
201  * relative to the current row.
202  * The following code fragment updates the <code>NAME</code> column
203  * in the fifth row of the <code>ResultSet</code> object
204  * <code>rs</code> and then uses the method <code>updateRow</code>
205  * to update the data source table from which <code>rs</code> was
206  * derived.
207  * <PRE>
208  *
209  * rs.absolute(5); // moves the cursor to the fifth row of rs
210  * rs.updateString("NAME", "AINSWORTH"); // updates the
211  * // <code>NAME</code> column of row 5 to be <code>AINSWORTH</code>
212  * rs.updateRow(); // updates the row in the data source
213  *
214  * </PRE>
215  * <LI>to insert column values into the insert row.  An updatable
216  * <code>ResultSet</code> object has a special row associated with
217  * it that serves as a staging area for building a row to be inserted.
218  * The following code fragment moves the cursor to the insert row, builds
219  * a three-column row, and inserts it into <code>rs</code> and into
220  * the data source table using the method <code>insertRow</code>.
221  * <PRE>
222  *
223  * rs.moveToInsertRow(); // moves cursor to the insert row
224  * rs.updateString(1, "AINSWORTH"); // updates the
225  * // first column of the insert row to be <code>AINSWORTH</code>
226  * rs.updateInt(2,35); // updates the second column to be <code>35</code>
227  * rs.updateBoolean(3, true); // updates the third row to <code>true</code>
228  * rs.insertRow();
229  * rs.moveToCurrentRow();
230  *
231  * </PRE>
232  * </ol>
233  * <P>A <code>ResultSet</code> object is automatically closed when the
234  * <code>Statement</code> object that
235  * generated it is closed, re-executed, or used
236  * to retrieve the next result from a sequence of multiple results.
237  *
238  * <P>The number, types and properties of a <code>ResultSet</code>
239  * object's columns are provided by the <code>ResulSetMetaData</code>
240  * object returned by the <code>ResultSet.getMetaData</code> method. <p>
241  * <!-- end java.sql.ResultSet generic documentation -->
242  *
243  * <!-- start java.sql.ResultSetMetaData generic documentation-->
244  * <B>From <CODE>ResultSetMetaData</CODE>:</B><p>
245  *
246  * An object that can be used to get information about the types
247  * and properties of the columns in a <code>ResultSet</code> object.
248  * The following code fragment creates the <code>ResultSet</code>
249  * object rs, creates the <code>ResultSetMetaData</code> object rsmd,
250  * and uses rsmd
251  * to find out how many columns rs has and whether the first column in rs
252  * can be used in a <code>WHERE</code> clause.
253  * <PRE>
254  *
255  * ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
256  * ResultSetMetaData rsmd = rs.getMetaData();
257  * int numberOfColumns = rsmd.getColumnCount();
258  * boolean b = rsmd.isSearchable(1);
259  *
260  * </PRE>
261  * <!-- end generic documentation -->
262  *
263  * <!-- start release-specific documentation -->
264  * <span class="ReleaseSpecificDocumentation">
265  * <B>HSQLDB-Specific Information:</B> <p>
266  *
267  * As stated above, <CODE>jdbcResultSet</CODE> implements both the
268  * <CODE>ResultSet</CODE> and <CODE>ResultSetMetaData</CODE> interfaces.
269  * However, to gain access to the interface methods of
270  * <CODE>ResultSetMetaData</CODE> in a driver independent way, the
271  * traditional call to the {@link #getMetaData getMetaData} method should
272  * be used, rather than casting objects known to be of type
273  * <CODE>jdbcResultSet</CODE> to type <CODE>ResultSetMetaData</CODE>. <p>
274  *
275  * A <code>ResultSet</code> object generated by HSQLDB is, as is standard
276  * JDBC behavior, by default of <code>ResultSet.TYPE_FORWARD_ONLY</code>
277  * and does not allow the use of absolute and relative positioning
278  * methods.  However, starting with 1.7.0, if a statement is created
279  * with:<p>
280  *
281  * <code class="JavaCodeExample">
282  * Statement stmt createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
283  *                                ResultSet.CONCUR_READ_ONLY);
284  * </code> <p>
285  *
286  * then the <CODE>ResultSet</CODE> objects it produces support
287  * using all of  the absolute and relative positioning methods of JDBC2
288  * to set the position of the current row, for example:<p>
289  *
290  * <code class="JavaCodeExample">
291  * rs.absolute(5);<br>
292  * String fifthRowValue = rs.getString(1);<br>
293  * rs.relative(4);<br>
294  * String ninthRowValue = rs.getString(1);<br>
295  * </code>
296  * <p>
297  *
298  * Note: An HSQLDB <code>ResultSet</code> object persists, even after its
299  * connection is closed.  This is regardless of the operational mode of
300  * the {@link Database Database} from which it came.  That is, they
301  * persist whether originating from a <CODE>Server</CODE>,
302  * <CODE>WebServer</CODE> or in-process mode <CODE>Database.</CODE>
303  * <p>
304  *
305  * Up to and including HSQLDB 1.7.0, there is no support for any of
306  * the methods introduced in JDBC 2 relating to updateable result sets.
307  * These methods include all updateXXX methods, as well as the
308  * {@link #insertRow}, {@link #updateRow}, {@link #deleteRow},
309  * {@link #moveToInsertRow} (and so on) methods.  A call to any such
310  * unsupported method will simply result in throwing a
311  * <CODE>SQLException</CODE> which states that the function is not
312  * supported.  It is not anticipated that HSQLDB-native support for
313  * updateable <CODE>ResultSet</CODE> objects will be introduced in the
314  * HSQLDB 1.7.x series.  Such features <I>may</I> be part of the
315  * HSQLDB 2.x series, but no decisions have been made at this point.<p>
316  *
317  * <b>JRE 1.1.x Notes:</b> <p>
318  *
319  * In general, JDBC 2 support requires Java 1.2 and above, and JDBC 3 requires
320  * Java 1.4 and above. In HSQLDB, support for methods introduced in different
321  * versions of JDBC depends on the JDK version used for compiling and building
322  * HSQLDB.<p>
323  *
324  * Since 1.7.0, it is possible to build the product so that
325  * all JDBC 2 methods can be called while executing under the version 1.1.x
326  * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
327  * However, some of these method calls require <code>int</code> values that
328  * are defined only in the JDBC 2 or greater version of the
329  * <a href="http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSet.html">
330  * <CODE>ResultSet</CODE></a> interface.  For this reason, when the
331  * product is compiled under JDK 1.1.x, these values are defined in
332  * here, in this class. <p>
333  *
334  * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
335  * JDBC2-only <CODE>ResultSet</CODE> values can be achieved by referring
336  * to them in parameter specifications and return value comparisons,
337  * respectively, as follows: <p>
338  *
339  * <CODE class="JavaCodeExample">
340  * jdbcResultSet.FETCH_FORWARD<br>
341  * jdbcResultSet.TYPE_FORWARD_ONLY<br>
342  * jdbcResultSet.TYPE_SCROLL_INSENSITIVE<br>
343  * jdbcResultSet.CONCUR_READ_ONLY<br>
344  * </CODE> <p>
345  *
346  * However, please note that code written in such a manner will not be
347  * compatible for use with other JDBC 2 drivers, since they expect and use
348  * <code>ResultSet</code>, rather than <code>jdbcResultSet</code>.  Also
349  * note, this feature is offered solely as a convenience to developers
350  * who must work under JDK 1.1.x due to operating constraints, yet wish to
351  * use some of the more advanced features available under the JDBC 2
352  * specification.<p>
353  *
354  * <b>ResultSetMetaData Implementation Notes:</b> <p>
355  *
356  * HSQLDB supports a subset of <code>ResultSetMetaData</code> interface.
357  * The JDBC specification for <code>ResultSetMetaData</code> is in part very
358  * vague. Several methods are exclusively for columns that are database
359  * table columns. There is a complete lack of specification on how these
360  * methods are supposed to distinguish between updatable and non-updatable
361  * <code>ResultSet</code> objects or between columns that are database
362  * table columns and those that are results of calculations or functions.
363  * This causes potential incompatibility between interpretations of the
364  * specifications in different JDBC drivers.<p>
365  *
366  * As such, <code>DatabaseMetadata</code> reporting will be enhanced
367  * in future 1.7.x and greater versions, but enhancements to reporting
368  * <code>ResultSetMetaData</code> have to be considered carefully as they
369  * impose a performance penalty on all <code>ResultSet</code> objects
370  * returned from HSQLDB, whether or not the <code>ResultSetMetaData</code>
371  * methods are used.<p>
372  *
373  * (fredt@users) <br>
374  * (boucherb@users)<p>
375  *
376  * </span>
377  * @see jdbcStatement#executeQuery
378  * @see jdbcStatement#getResultSet
379  * @see <a href=
380  * "http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSetMetaData.html">
381  * <CODE>ResultSetMetaData</CODE></a>
382  */
383 public class jdbcResultSet implements ResultSet, ResultSetMetaData {
384 
385 // fredt@users 20020320 - patch 497714 by lakuhns@users - scrollable ResultSet
386 // variable values in different states
387 // Condition definitions
388 //                  bInit  iCurrentRow  nCurrent  nCurrent.next
389 //                  -----  -----------  --------  -------------
390 // beforeFirst      false       0         N/A          N/A
391 // first            true        1        !null    next or null
392 // last             true    last row #   !null        null
393 // afterLast        true        0        !null         N/A
394     //------------------------ Private Attributes --------------------------
395 /*
396  * Future Development Information for Developers and Contributors<p>
397  * Providing a
398  * full and robust implementation guaranteeing consistently accurate
399  * results and behaviour depends upon introducing several new engine
400  * features for which the internals of the product currently have no
401  * infrastructure: <p>
402  *
403  * <OL>
404  * <LI>a unique rowid for each row in the database which lasts the life
405  *  of a row, independent of any updates made to that row</LI>
406  * <LI>the ability to explicitly lock either the tables or the
407  *  individual rows of an updateable result, for the duration that
408  *  the result is open</LI>
409  * <LI>the ability to choose between transactions supporting repeatable
410  *  reads, committed reads, and uncommitted reads
411  * <LI>the ability to map an updated result row's columns back to
412  *  specific updateable objects on the database.<p>
413  *
414  *  <B>Note:</B> Typically, it is easy to do this mapping if all the
415  *  rows of a result consist of columns from a single table.  And it
416  *  is especially easy if the result's columns are a superset of the
417  *  primary key columns of that table.  The ability to
418  *  update a result consisting of any combintation of join, union,
419  *  intersect, difference and grouping operations, however, is much more
420  *  complex to implement and often impossible, especially under
421  *  grouping and non-natural joins.  Also, it is not even guaranteed
422  *  that the columns of a result map back to *any* updateable object
423  *  on the database, for instance in the cases where the
424  *  result's column values are general expressions or the result
425  *  comes from a stored procedure where the data may not even come,
426  *  directly or indirectly, from updateable database objects such as
427  *  columns in table rows.
428  * </OL>
429  *
430  * For developers working under a JDBC3 environment,
431  * it is gently recommended to take a look at Sun's early access
432  * <a href="http://developer.java.sun.com/developer/earlyAccess/crs/">
433  * <CODE>RowSet</CODE></a> implementation, as this can be used to add
434  * JDBC driver independent scrollablility and updateability.
435  * However, as a driver independent implementation, it obviously cannot
436  * guarantee to use the traditional table and/or row locking features
437  * that many DBMS make available to ensure the success of all
438  * valid updates against updateable results sets.  As such, performing
439  * updates through Sun's early access <CODE>RowSet</CODE> implementation
440  * may not always succeed, even when it is generally expected that they
441  * should.  This is because the condition used to find the original row
442  * on the database to update (which, for a driver independent
443  * implementation, would have to be equality on all columns values of
444  * the originally retrieved row) can become invalid if another
445  * transaction modifies or deletes that row on the database at some
446  * point between the time the row was last retrieved or refreshed in
447  * the RowSet and the time the RowSet attempts to make its next
448  * update to that row.  Also, any driver independent implementation
449  * of RowSet is still dependent on each driver guaranteeing that its
450  * <CODE>ResultSet</CODE> objects return completely accurate
451  * <CODE>ResultSetMetaData</CODE> that fulfills all of the
452  * JDBC <CODE>ResultSetMetaData</CODE> contracts under all circumstances.
453  * However, up to and including 1.7.1, HSQLDB does not make such guarantees
454  * under all conditions. See the discussion at {@link #getMetaData}.
455  * (boucherb@users)<p>
456 */
457 
458     /**
459      * The internal representation.  Basically, a linked list of records,
460      * each containing an Object[] payload representing the data for a row,
461      * plus some metadata.
462      */
463     private Result rResult;
464 
465     /**
466      * The record containing the data for the row, if any,
467      * currently positioned on.
468      */
469     private Record nCurrent;
470 
471     /**
472      * The offset of the row, if any, currently positioned on.
473      */
474     private int iCurrentRow;
475 
476     /**
477      * If a result of updating the database, then this is the number of rows
478      * updated.
479      */
480     private int iUpdateCount;
481 
482     /**
483      * Is current row before the first row?
484      */
485     private boolean bInit;    // false if before first row
486 
487     /**
488      * How many columns does this <code>ResultSet</code> have?
489      */
490     private int iColumnCount;
491 
492     /**
493      * Did the last getXXX method encounter a null value? <p>
494      *
495      * This is important for methods that return primitive values, since
496      * there is no other way to check for this condition in those cases.
497      */
498     private boolean bWasNull;
499 
500 // fredt@users 20020222 - patch 489917 by jytou@users - made optional
501 // see setGetColumnName in package private internal implementation
502 // methods section
503 
504     /**
505      * Does {@link #getColumnName(int) getColumnName} return the
506      * column name (true) or label (false)?
507      */
508     private boolean getColumnName = true;
509 
510     /**
511      * if false, various unsupported ResultSetMetaData methods return the
512      * true/false values they used to return in version 1.61.
513      * if true they throw an SQLException
514      */
515     private boolean strictMetaData = false;
516 
517     /**
518      * Properties for the connectin
519      *
520      */
521     private HsqlProperties connProperties;
522 
523     //------------------------ Package Attributes --------------------------
524 
525     /**
526      * The Statement that generated this result.
527      */
528     Statement sqlStatement;
529 
530     /**
531      * The direction of this result.
532      */
533     int rsType = TYPE_FORWARD_ONLY;
534 
535     /**
536      * <!-- start generic documentation -->
537      * Moves the cursor down one row from its current position.
538      * A <code>ResultSet</code> cursor is initially positioned
539      * before the first row; the first call to the method
540      * <code>next</code> makes the first row the current row; the
541      * second call makes the second row the current row, and so on.
542      *
543      * <P>If an input stream is open for the current row, a call
544      * to the method <code>next</code> will
545      * implicitly close it. A <code>ResultSet</code> object's
546      * warning chain is cleared when a new row is read. <p>
547      *
548      * <!-- end generic documentation -->
549      *
550      * <!-- start release-specific documentation -->
551      * <span class="ReleaseSpecificDocumentation">
552      * </span>
553      * <!-- end release-specific documentation -->
554      *
555      *
556      * @return <code>true</code> if the new current row is valid;
557      * <code>false</code> if there are no more rows
558      * @exception SQLException if a database access error occurs
559      */
560     public boolean next() throws SQLException {
561 
562         bWasNull = false;
563 
564         // Have an empty resultset so exit with false
565         if (rResult == null) {
566             return false;
567         }
568 
569         if (rResult.rRoot == null) {
570             return false;
571         }
572 
573         if (!bInit) {
574 
575             // The resultset has not been traversed, so set the cursor
576             // to the first row (1)
577             nCurrent    = rResult.rRoot;
578             bInit       = true;
579             iCurrentRow = 1;
580         } else {
581 
582             // The resultset has been traversed, if afterLast, retrun false
583             if (nCurrent == null) {
584                 return false;
585             }
586 
587             // On a valid row so go to next
588             nCurrent = nCurrent.next;
589 
590             iCurrentRow++;
591         }
592 
593         // finally test to see if we are in an afterLast situation
594         if (nCurrent == null) {
595 
596             // Yes, set the current row to 0 and exit with false
597             iCurrentRow = 0;
598 
599             return false;
600         } else {
601 
602             // Not afterLast, so success
603             return true;
604         }
605     }
606 
607     /**
608      * <!-- start generic documentation -->
609      * Releases this <code>ResultSet</code> object's database and
610      * JDBC resources immediately instead of waiting for
611      * this to happen when it is automatically closed.
612      *
613      * <P><B>Note:</B> A <code>ResultSet</code> object
614      * is automatically closed by the
615      * <code>Statement</code> object that generated it when
616      * that <code>Statement</code> object is closed,
617      * re-executed, or is used to retrieve the next result from a
618      * sequence of multiple results. A <code>ResultSet</code> object
619      * is also automatically closed when it is garbage collected. <p>
620      * <!-- end generic documentation -->
621      *
622      * <!-- start release-specific documentation -->
623      * <span class="ReleaseSpecificDocumentation">
624      * </span>
625      * <!-- end release-specific documentation -->
626      *
627      * @exception SQLException if a database access error occurs
628      */
629     public void close() throws SQLException {
630         iUpdateCount = -1;
631         rResult      = null;
632     }
633 
634     /**
635      * <!-- start generic documentation -->
636      * Reports whether
637      * the last column read had a value of SQL <code>NULL</code>.
638      * Note that you must first call one of the getter methods
639      * on a column to try to read its value and then call
640      * the method <code>wasNull</code> to see if the value read was
641      * SQL <code>NULL</code>. <p>
642      * <!-- end generic documentation -->
643      *
644      * <!-- start release-specific documentation -->
645      * <span class="ReleaseSpecificDocumentation">
646      * </span>
647      * <!-- end release-specific documentation -->
648      *
649      * @return <code>true</code> if the last column value read was SQL
650      *     <code>NULL</code> and <code>false</code> otherwise
651      * @exception SQLException if a database access error occurs
652      */
653     public boolean wasNull() throws SQLException {
654         return bWasNull;
655     }
656 
657     //======================================================================
658     // Methods for accessing results by column index
659     //======================================================================
660 
661     /**
662      * <!-- start generic documentation -->
663      * Retrieves the value of the designated column in the current row
664      * of this <code>ResultSet</code> object as
665      * a <code>String</code> in the Java programming language. <p>
666      * <!-- end generic documentation -->
667      *
668      * <!-- start release-specific documentation -->
669      * <span class="ReleaseSpecificDocumentation">
670      * </span>
671      * <!-- end release-specific documentation -->
672      *
673      * @param columnIndex the first column is 1, the second is 2, ...
674      * @return the column value; if the value is SQL <code>NULL</code>, the
675      * value returned is <code>null</code>
676      * @exception SQLException if a database access error occurs
677      */
678     public String getString(int columnIndex) throws SQLException {
679 
680         checkAvailable();
681 
682         Object o;
683 
684         try {
685             o = nCurrent.data[--columnIndex];
686         } catch (ArrayIndexOutOfBoundsException e) {
687             throw Trace.error(Trace.COLUMN_NOT_FOUND, ++columnIndex);
688         }
689 
690         // use checknull because getColumnInType is not used
691         checkNull(o);
692 
693         return o == null ? null
694                          : o.toString();
695     }
696 
697     /**
698      * <!-- start generic documentation -->
699      * Retrieves the value of the designated column in the current row
700      * of this <code>ResultSet</code> object as
701      * a <code>boolean</code> in the Java programming language. <p>
702      * <!-- end generic documentation -->
703      *
704      * <!-- start release-specific documentation -->
705      * <span class="ReleaseSpecificDocumentation">
706      * </span>
707      * <!-- end release-specific documentation -->
708      *
709      * @param columnIndex the first column is 1, the second is 2, ...
710      * @return the column value; if the value is SQL <code>NULL</code>, the
711      * value returned is <code>false</code>
712      * @exception SQLException if a database access error occurs
713      */
714     public boolean getBoolean(int columnIndex) throws SQLException {
715 
716         Object o = getColumnInType(columnIndex, Types.BIT);
717 
718         return o == null ? false
719                          : ((Boolean) o).booleanValue();
720     }
721 
722     /**
723      * <!-- start generic documentation -->
724      * Retrieves the value of the designated column in the current row
725      * of this <code>ResultSet</code> object as
726      * a <code>byte</code> in the Java programming language. <p>
727      * <!-- end generic documentation -->
728      *
729      * <!-- start release-specific documentation -->
730      * <span class="ReleaseSpecificDocumentation">
731      * </span>
732      * <!-- end release-specific documentation -->
733      *
734      * @param columnIndex the first column is 1, the second is 2, ...
735      * @return the column value; if the value is SQL <code>NULL</code>, the
736      * value returned is <code>0</code>
737      * @exception SQLException if a database access error occurs
738      */
739     public byte getByte(int columnIndex) throws SQLException {
740 
741         Object o = getColumnInType(columnIndex, Types.SMALLINT);
742 
743         return o == null ? 0
744                          : ((Number) o).byteValue();
745     }
746 
747     /**
748      * <!-- start generic documentation -->
749      * Retrieves the value of the designated column in the current row
750      * of this <code>ResultSet</code> object as
751      * a <code>short</code> in the Java programming language. <p>
752      * <!-- end generic documentation -->
753      *
754      * <!-- start release-specific documentation -->
755      * <span class="ReleaseSpecificDocumentation">
756      * </span>
757      * <!-- end release-specific documentation -->
758      *
759      * @param columnIndex the first column is 1, the second is 2, ...
760      * @return the column value; if the value is SQL <code>NULL</code>, the
761      * value returned is <code>0</code>
762      * @exception SQLException if a database access error occurs
763      */
764     public short getShort(int columnIndex) throws SQLException {
765 
766         Object o = getColumnInType(columnIndex, Types.SMALLINT);
767 
768         return o == null ? 0
769                          : ((Number) o).shortValue();
770     }
771 
772     /**
773      * <!-- start generic documentation -->
774      * Retrieves the value of the designated column in the current row
775      * of this <code>ResultSet</code> object as
776      * an <code>int</code> in the Java programming language. <p>
777      * <!-- end generic documentation -->
778      *
779      * <!-- start release-specific documentation -->
780      * <span class="ReleaseSpecificDocumentation">
781      * </span>
782      * <!-- end release-specific documentation -->
783      *
784      * @param columnIndex the first column is 1, the second is 2, ...
785      * @return the column value; if the value is SQL <code>NULL</code>, the
786      * value returned is <code>0</code>
787      * @exception SQLException if a database access error occurs
788      */
789     public int getInt(int columnIndex) throws SQLException {
790 
791         Object o = getColumnInType(columnIndex, Types.INTEGER);
792 
793         return o == null ? 0
794                          : ((Number) o).intValue();
795     }
796 
797     /**
798      * <!-- start generic documentation -->
799      * Retrieves the value of the designated column in the current row
800      * of this <code>ResultSet</code> object as
801      * a <code>long</code> in the Java programming language. <p>
802      * <!-- end generic documentation -->
803      *
804      * <!-- start release-specific documentation -->
805      * <span class="ReleaseSpecificDocumentation">
806      * </span>
807      * <!-- end release-specific documentation -->
808      *
809      * @param columnIndex the first column is 1, the second is 2, ...
810      * @return the column value; if the value is SQL <code>NULL</code>, the
811      * value returned is <code>0</code>
812      * @exception SQLException if a database access error occurs
813      */
814     public long getLong(int columnIndex) throws SQLException {
815 
816         Object o = getColumnInType(columnIndex, Types.BIGINT);
817 
818         return o == null ? 0
819                          : ((Number) o).longValue();
820     }
821 
822     /**
823      * <!-- start generic documentation -->
824      * Retrieves the value of the designated column in the current row
825      * of this <code>ResultSet</code> object as
826      * a <code>float</code> in the Java programming language. <p>
827      * <!-- end generic documentation -->
828      *
829      * <!-- start release-specific documentation -->
830      * <span class="ReleaseSpecificDocumentation">
831      * </span>
832      * <!-- end release-specific documentation -->
833      *
834      * @param columnIndex the first column is 1, the second is 2, ...
835      * @return the column value; if the value is SQL <code>NULL</code>, the
836      * value returned is <code>0</code>
837      * @exception SQLException if a database access error occurs
838      */
839     public float getFloat(int columnIndex) throws SQLException {
840 
841         Object o = getColumnInType(columnIndex, Types.REAL);
842 
843         return o == null ? (float) 0.0
844                          : ((Number) o).floatValue();
845     }
846 
847     /**
848      * <!-- start generic documentation -->
849      * Retrieves the value of the designated column in the current row
850      * of this <code>ResultSet</code> object as
851      * a <code>double</code> in the Java programming language. <p>
852      * <!-- end generic documentation -->
853      *
854      * <!-- start release-specific documentation -->
855      * <span class="ReleaseSpecificDocumentation">
856      * </span>
857      * <!-- end release-specific documentation -->
858      *
859      * @param columnIndex the first column is 1, the second is 2, ...
860      * @return the column value; if the value is SQL <code>NULL</code>, the
861      * value returned is <code>0</code>
862      * @exception SQLException if a database access error occurs
863      */
864     public double getDouble(int columnIndex) throws SQLException {
865 
866         Object o = getColumnInType(columnIndex, Types.DOUBLE);
867 
868         return o == null ? 0.0
869                          : ((Number) o).doubleValue();
870     }
871 
872     /**
873      * <!-- start generic documentation -->
874      * Retrieves the value of the designated column in the current row
875      * of this <code>ResultSet</code> object as
876      * a <code>java.sql.BigDecimal</code> in the Java programming language.<p>
877      * <!-- end generic documentation -->
878      *
879      * <!-- start release-specific documentation -->
880      * <span class="ReleaseSpecificDocumentation">
881      * <b>HSQLDB-Specific Information:</b> <p>
882      *
883      * Beginning with 1.7.0, HSQLDB converts the result and sets the scale
884      * with BigDecimal.ROUND_HALF_DOWN<p>
885      *
886      * </span>
887      * <!-- end release-specific documentation -->
888      *
889      * @param columnIndex the first column is 1, the second is 2, ...
890      * @param scale the number of digits to the right of the decimal point
891      * @return the column value; if the value is SQL <code>NULL</code>, the
892      * value returned is <code>null</code>
893      * @exception SQLException if a database access error occurs
894      * @deprecated
895      */
896     public BigDecimal getBigDecimal(int columnIndex,
897                                     int scale) throws SQLException {
898 
899         // boucherb@users 20020502 - added conversion
900         BigDecimal bd = (BigDecimal) getColumnInType(columnIndex,
901             Types.DECIMAL);
902 
903         if (scale < 0) {
904             throw Trace.error(Trace.INVALID_JDBC_ARGUMENT);
905         }
906 
907         if (bd != null) {
908             bd.setScale(scale, BigDecimal.ROUND_HALF_DOWN);
909         }
910 
911         return bd;
912     }
913 
914     /**
915      * <!-- start generic documentation -->
916      * Retrieves the value of the designated column in the current row
917      * of this <code>ResultSet</code> object as
918      * a <code>byte</code> array in the Java programming language.
919      * The bytes represent the raw values returned by the driver. <p>
920      * <!-- end generic documentation -->
921      *
922      * <!-- start release-specific documentation -->
923      * <span class="ReleaseSpecificDocumentation">
924      * <b>HSQLDB-Specific Information:</b> <p>
925      *
926      * Up to and including 1.7.1, HSQLDB returns correct values for columns
927      * of type <CODE>BINARY</CODE>, <CODE>CHAR</CODE> and their variations.
928      * For other types, it returns the <CODE>byte[]</CODE> for the
929      * <CODE>String</CODE> representation of the value. <p>
930      *
931      * </span>
932      * <!-- end release-specific documentation -->
933      *
934      * @param columnIndex the first column is 1, the second is 2, ...
935      * @return the column value; if the value is SQL <code>NULL</code>, the
936      * value returned is <code>null</code>
937      * @exception SQLException if a database access error occurs
938      */
939     public byte[] getBytes(int columnIndex) throws SQLException {
940 
941         Object x = getObject(columnIndex);
942 
943         if (x == null) {
944             return null;
945         }
946 
947         if (x instanceof byte[]) {
948             return (byte[]) x;
949         }
950 
951         if (x instanceof java.lang.String) {
952             return ((String) x).getBytes();
953         }
954 
955         x = getColumnInType(--columnIndex, Types.BINARY);
956 
957         return (byte[]) x;
958     }
959 
960     /**
961      * <!-- start generic documentation -->
962      * Retrieves the value of the designated column in the current row
963      * of this <code>ResultSet</code> object as a
964      * <code>java.sql.Date</code> object in the Java programming language.<p>
965      * <!-- end generic documentation -->
966      *
967      * <!-- start release-specific documentation -->
968      * <span class="ReleaseSpecificDocumentation">
969      * </span>
970      * <!-- end release-specific documentation -->
971      *
972      * @param columnIndex the first column is 1, the second is 2, ...
973      * @return the column value; if the value is SQL <code>NULL</code>, the
974      * value returned is <code>null</code>
975      * @exception SQLException if a database access error occurs
976      */
977     public java.sql.Date getDate(int columnIndex) throws SQLException {
978         return (java.sql.Date) getColumnInType(columnIndex, Types.DATE);
979     }
980 
981     /**
982      * <!-- start generic documentation -->
983      * Retrieves the value of the designated column in the current row
984      * of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
985      * object in the Java programming language. <p>
986      * <!-- end generic documentation -->
987      *
988      * <!-- start release-specific documentation -->
989      * <span class="ReleaseSpecificDocumentation">
990      * </span>
991      * <!-- end release-specific documentation -->
992      *
993      * @param columnIndex the first column is 1, the second is 2, ...
994      * @return the column value; if the value is SQL <code>NULL</code>, the
995      * value returned is <code>null</code>
996      * @exception SQLException if a database access error occurs
997      */
998     public java.sql.Time getTime(int columnIndex) throws SQLException {
999         return (Time) getColumnInType(columnIndex, Types.TIME);
1000    }
1001
1002    /**
1003     * <!-- start generic documentation -->
1004     * Retrieves the value of the designated column in the current row
1005     * of this <code>ResultSet</code> object as
1006     * a <code>java.sql.Timestamp</code> object in the Java programming
1007     * language. <p>
1008     * <!-- end generic documentation -->
1009     *
1010     * <!-- start release-specific documentation -->
1011     * <span class="ReleaseSpecificDocumentation">
1012     * </span>
1013     * <!-- end release-specific documentation -->
1014     *
1015     * @param columnIndex the first column is 1, the second is 2, ...
1016     * @return the column value; if the value is SQL <code>NULL</code>, the
1017     * value returned is <code>null</code>
1018     * @exception SQLException if a database access error occurs
1019     */
1020    public java.sql.Timestamp getTimestamp(int columnIndex)
1021    throws SQLException {
1022        return (Timestamp) getColumnInType(columnIndex, Types.TIMESTAMP);
1023    }
1024
1025    /**
1026     * <!-- start generic documentation -->
1027     * Retrieves the value of the designated column in the current row
1028     * of this <code>ResultSet</code> object as
1029     * a stream of ASCII characters. The value can then be read in chunks
1030     * from the stream. This method is particularly
1031     * suitable for retrieving large <char>LONGVARCHAR</char> values.
1032     * The JDBC driver will
1033     * do any necessary conversion from the database format into ASCII.
1034     *
1035     * <P><B>Note:</B> All the data in the returned stream must be
1036     * read prior to getting the value of any other column. The next
1037     * call to a getter method implicitly closes the stream.  Also, a
1038     * stream may return <code>0</code> when the method
1039     * <code>InputStream.available</code>
1040     * is called whether there is data available or not. <p>
1041     * <!-- end generic documentation -->
1042     *
1043     * <!-- start release-specific documentation -->
1044     * <span class="ReleaseSpecificDocumentation">
1045     * <b>HSQLDB-Specific Information:</b> <p>
1046     *
1047     * The limitation noted above does not apply to HSQLDB.<p>
1048     *
1049     * Up to and including 1.6.1, getAsciiStream was identical to
1050     * getUnicodeStream and both simply returned a byte stream
1051     * constructed from the raw {@link #getBytes(int) getBytes}
1052     * representation.
1053     *
1054     * Starting with 1.7.0, this has been updated to comply with the
1055     * java.sql specification.
1056     *
1057     * When the column is of type CHAR and its variations, it requires no
1058     * conversion since it is represented internally already as
1059     * Java Strings. When the column is not of type CHAR and its variations,
1060     * the returned stream is based on a conversion to the
1061     * Java <CODE>String</CODE> representation of the value. In either case,
1062     * the obtained stream is always equivalent to a stream of the low order
1063     * bytes from the value's String representation. <p>
1064     *
1065     * HSQLDB SQL <CODE>CHAR</CODE> and its variations are all Unicode strings
1066     * internally, so the recommended alternatives to this method are
1067     * {@link #getString(int) getString},
1068     * {@link #getUnicodeStream(int) getUnicodeStream} (<b>deprecated</b>)
1069     * and new to 1.7.0: {@link #getCharacterStream(int) getCharacterStream}
1070     * (now prefered over the deprecated getUnicodeStream alternative). <p>
1071     *
1072     * </span>
1073     * <!-- end release-specific documentation -->
1074     *
1075     * @param columnIndex the first column is 1, the second is 2, ...
1076     * @return a Java input stream that delivers the database column value
1077     * as a stream of one-byte ASCII characters;
1078     * if the value is SQL <code>NULL</code>, the
1079     * value returned is <code>null</code>
1080     * @exception SQLException if a database access error occurs
1081     */
1082    public java.io.InputStream getAsciiStream(int columnIndex)
1083    throws SQLException {
1084
1085        String s = getString(columnIndex);
1086
1087        if (s == null) {
1088            return null;
1089        }
1090
1091        return new AsciiStringInputStream(s);
1092    }
1093
1094    /**
1095     * <!-- start generic documentation -->
1096     * Retrieves the value of the designated column in the current row
1097     * of this <code>ResultSet</code> object as
1098     * as a stream of two-byte Unicode characters. The first byte is
1099     * the high byte; the second byte is the low byte.
1100     *
1101     * The value can then be read in chunks from the
1102     * stream. This method is particularly
1103     * suitable for retrieving large <code>LONGVARCHAR</code>values.  The
1104     * JDBC driver will do any necessary conversion from the database
1105     * format into Unicode.
1106     *
1107     * <P><B>Note:</B> All the data in the returned stream must be
1108     * read prior to getting the value of any other column. The next
1109     * call to a getter method implicitly closes the stream.
1110     * Also, a stream may return <code>0</code> when the method
1111     * <code>InputStream.available</code>
1112     * is called, whether there is data available or not. <p>
1113     * <!-- end generic documentation -->
1114     *
1115     * <!-- start release-specific documentation -->
1116     * <span class="ReleaseSpecificDocumentation">
1117     * <b>HSQLDB-Specific Information:</b> <p>
1118     *
1119     * The limitation noted above does not apply to HSQLDB.<p>
1120     *
1121     * Up to and including 1.6.1, getUnicodeStream (and getAsciiStream)
1122     * both simply returned a byte stream constructed from the
1123     * raw {@link #getBytes(int) getBytes} representation.
1124     *
1125     * Starting with 1.7.0, this has been corrected to comply with the
1126     * java.sql specification.
1127     *
1128     * When the column is of type CHAR and its variations, it requires no
1129     * conversion since it is represented internally already as
1130     * Java Strings. When the column is not of type CHAR and its variations,
1131     * the returned stream is based on a conversion to the
1132     * Java <CODE>String</CODE> representation of the value. In either case,
1133     * the obtained stream is always equivalent to a stream of
1134     * bytes from the value's String representation, with high-byte first.<p>
1135     *
1136     * </span>
1137     * <!-- end release-specific documentation -->
1138     *
1139     * @param columnIndex the first column is 1, the second is 2, ...
1140     * @return a Java input stream that delivers the database column value
1141     *   as a stream of two-byte Unicode characters;
1142     *   if the value is SQL <code>NULL</code>, the value returned is
1143     *   <code>null</code>
1144     * @exception SQLException if a database access error occurs
1145     * @deprecated use <code>getCharacterStream</code> in place of
1146     *        <code>getUnicodeStream</code>
1147     */
1148    public java.io.InputStream getUnicodeStream(int columnIndex)
1149    throws SQLException {
1150
1151        String s = getString(columnIndex);
1152
1153        if (s == null) {
1154            return null;
1155        }
1156
1157        return new StringInputStream(s);
1158    }
1159
1160    /**
1161     * <!-- start generic documentation -->
1162     * Retrieves the value of the designated column in the current row
1163     * of this <code>ResultSet</code> object as a binary stream of
1164     * uninterpreted bytes. The value can then be read in chunks from the
1165     * stream. This method is particularly
1166     * suitable for retrieving large <code>LONGVARBINARY</code> values.
1167     *
1168     * <P><B>Note:</B> All the data in the returned stream must be
1169     * read prior to getting the value of any other column. The next
1170     * call to a getter method implicitly closes the stream.  Also, a
1171     * stream may return <code>0</code> when the method
1172     * <code>InputStream.available</code>
1173     * is called whether there is data available or not. <p>
1174     * <!-- end generic documentation -->
1175     *
1176     * <!-- start release-specific documentation -->
1177     * <span class="ReleaseSpecificDocumentation">
1178     * </span>
1179     * <!-- end release-specific documentation -->
1180     *
1181     * @param columnIndex the first column is 1, the second is 2, ...
1182     * @return a Java input stream that delivers the database column value
1183     *     as a stream of uninterpreted bytes;
1184     *     if the value is SQL <code>NULL</code>, the value returned is
1185     *     <code>null</code>
1186     * @exception SQLException if a database access error occurs
1187     */
1188
1189// fredt@users 20020215 - patch 485704 by boucherb@users
1190    public java.io.InputStream getBinaryStream(int columnIndex)
1191    throws SQLException {
1192
1193        byte[] b = getBytes(columnIndex);
1194
1195        return wasNull() ? null
1196                         : new ByteArrayInputStream(b);
1197
1198        // or new ByteArrayInputStream(new byte[0]) : ...
1199    }
1200
1201    //======================================================================
1202    // Methods for accessing results by column name
1203    //======================================================================
1204
1205    /**
1206     * <!-- start generic documentation -->
1207     * Retrieves the value of the designated column in the current row
1208     * of this <code>ResultSet</code> object as
1209     * a <code>String</code> in the Java programming language. <p>
1210     * <!-- end generic documentation -->
1211     *
1212     * <!-- start release-specific documentation -->
1213     * <span class="ReleaseSpecificDocumentation">
1214     * </span>
1215     * <!-- end release-specific documentation -->
1216     *
1217     * @param columnName the SQL name of the column
1218     * @return the column value; if the value is SQL <code>NULL</code>, the
1219     * value returned is <code>null</code>
1220     * @exception SQLException if a database access error occurs
1221     */
1222    public String getString(String columnName) throws SQLException {
1223        return getString(findColumn(columnName));
1224    }
1225
1226    /**
1227     * <!-- start generic documentation -->
1228     * Retrieves the value of the designated column in the current row
1229     * of this <code>ResultSet</code> object as
1230     * a <code>boolean</code> in the Java programming language. <p>
1231     * <!-- end generic documentation -->
1232     *
1233     * <!-- start release-specific documentation -->
1234     * <span class="ReleaseSpecificDocumentation">
1235     * </span>
1236     * <!-- end release-specific documentation -->
1237     *
1238     * @param columnName the SQL name of the column
1239     * @return the column value; if the value is SQL <code>NULL</code>, the
1240     * value returned is <code>false</code>
1241     * @exception SQLException if a database access error occurs
1242     */
1243    public boolean getBoolean(String columnName) throws SQLException {
1244        return getBoolean(findColumn(columnName));
1245    }
1246
1247    /**
1248     * <!-- start generic documentation -->
1249     * Retrieves the value of the designated column in the current row
1250     * of this <code>ResultSet</code> object as
1251     * a <code>byte</code> in the Java programming language. <p>
1252     * <!-- end generic documentation -->
1253     *
1254     * <!-- start release-specific documentation -->
1255     * <span class="ReleaseSpecificDocumentation">
1256     * </span>
1257     * <!-- end release-specific documentation -->
1258     *
1259     * @param columnName the SQL name of the column
1260     * @return the column value; if the value is SQL <code>NULL</code>, the
1261     * value returned is <code>0</code>
1262     * @exception SQLException if a database access error occurs
1263     */
1264    public byte getByte(String columnName) throws SQLException {
1265        return getByte(findColumn(columnName));
1266    }
1267
1268    /**
1269     * <!-- start generic documentation -->
1270     * Retrieves the value of the designated column in the current row
1271     * of this <code>ResultSet</code> object as
1272     * a <code>short</code> in the Java programming language. <p>
1273     * <!-- end generic documentation -->
1274     *
1275     * <!-- start release-specific documentation -->
1276     * <span class="ReleaseSpecificDocumentation">
1277     * </span>
1278     * <!-- end release-specific documentation -->
1279     *
1280     * @param columnName the SQL name of the column
1281     * @return the column value; if the value is SQL <code>NULL</code>, the
1282     * value returned is <code>0</code>
1283     * @exception SQLException if a database access error occurs
1284     */
1285    public short getShort(String columnName) throws SQLException {
1286        return getShort(findColumn(columnName));
1287    }
1288
1289    /**
1290     * <!-- start generic documentation -->
1291     * Retrieves the value of the designated column in the current row
1292     * of this <code>ResultSet</code> object as
1293     * an <code>int</code> in the Java programming language. <p>
1294     * <!-- end generic documentation -->
1295     *
1296     * <!-- start release-specific documentation -->
1297     * <span class="ReleaseSpecificDocumentation">
1298     * </span>
1299     * <!-- end release-specific documentation -->
1300     *
1301     * @param columnName the SQL name of the column
1302     * @return the column value; if the value is SQL <code>NULL</code>, the
1303     * value returned is <code>0</code>
1304     * @exception SQLException if a database access error occurs
1305     */
1306    public int getInt(String columnName) throws SQLException {
1307        return getInt(findColumn(columnName));
1308    }
1309
1310    /**
1311     * <!-- start generic documentation -->
1312     * Retrieves the value of the designated column in the current row
1313     * of this <code>ResultSet</code> object as
1314     * a <code>long</code> in the Java programming language. <p>
1315     * <!-- end generic documentation -->
1316     *
1317     * <!-- start release-specific documentation -->
1318     * <span class="ReleaseSpecificDocumentation">
1319     * </span>
1320     * <!-- end release-specific documentation -->
1321     *
1322     * @param columnName the SQL name of the column
1323     * @return the column value; if the value is SQL <code>NULL</code>, the
1324     * value returned is <code>0</code>
1325     * @exception SQLException if a database access error occurs
1326     */
1327    public long getLong(String columnName) throws SQLException {
1328        return getLong(findColumn(columnName));
1329    }
1330
1331    /**
1332     * <!-- start generic documentation -->
1333     * Retrieves the value of the designated column in the current row
1334     * of this <code>ResultSet</code> object as
1335     * a <code>float</code> in the Java programming language. <p>
1336     * <!-- end generic documentation -->
1337     *
1338     * <!-- start release-specific documentation -->
1339     * <span class="ReleaseSpecificDocumentation">
1340     * </span>
1341     * <!-- end release-specific documentation -->
1342     *
1343     * @param columnName the SQL name of the column
1344     * @return the column value; if the value is SQL <code>NULL</code>, the
1345     * value returned is <code>0</code>
1346     * @exception SQLException if a database access error occurs
1347     */
1348    public float getFloat(String columnName) throws SQLException {
1349        return getFloat(findColumn(columnName));
1350    }
1351
1352    /**
1353     * <!-- start generic documentation -->
1354     * Retrieves the value of the designated column in the current row
1355     * of this <code>ResultSet</code> object as
1356     * a <code>double</code> in the Java programming language. <p>
1357     * <!-- end generic documentation -->
1358     *
1359     * <!-- start release-specific documentation -->
1360     * <span class="ReleaseSpecificDocumentation">
1361     * </span>
1362     * <!-- end release-specific documentation -->
1363     *
1364     * @param columnName the SQL name of the column
1365     * @return the column value; if the value is SQL <code>NULL</code>, the
1366     * value returned is <code>0</code>
1367     * @exception SQLException if a database access error occurs
1368     */
1369    public double getDouble(String columnName) throws SQLException {
1370        return getDouble(findColumn(columnName));
1371    }
1372
1373    /**
1374     * <!-- start generic documentation -->
1375     * Retrieves the value of the designated column in the current row
1376     * of this <code>ResultSet</code> object as a
1377     * <code>java.math.BigDecimal</code> in the Java programming language.<p>
1378     * <!-- end generic documentation -->
1379     *
1380     * <!-- start release-specific documentation -->
1381     * <span class="ReleaseSpecificDocumentation">
1382     * <b>HSQLDB-Specific Information:</b> <p>
1383     *
1384     * Up to and including 1.7.1, HSQLDB ignores the scale parameter. <p>
1385     *
1386     * </span>
1387     * <!-- end release-specific documentation -->
1388     *
1389     * @param columnName the SQL name of the column
1390     * @param scale the number of digits to the right of the decimal point
1391     * @return the column value; if the value is SQL <code>NULL</code>, the
1392     * value returned is <code>null</code>
1393     * @exception SQLException if a database access error occurs
1394     * @deprecated
1395     */
1396    public BigDecimal getBigDecimal(String columnName,
1397                                    int scale) throws SQLException {
1398        return getBigDecimal(findColumn(columnName), scale);
1399    }
1400
1401    /**
1402     * <!-- start generic documentation -->
1403     * Retrieves the value of the designated column in the current row
1404     * of this <code>ResultSet</code> object as
1405     * a <code>byte</code> array in the Java programming language.
1406     * The bytes represent the raw values returned by the driver. <p>
1407     * <!-- end generic documentation -->
1408     *
1409     * <!-- start release-specific documentation -->
1410     * <span class="ReleaseSpecificDocumentation">
1411     * </span>
1412     * <!-- end release-specific documentation -->
1413     *
1414     * @param columnName the SQL name of the column
1415     * @return the column value; if the value is SQL <code>NULL</code>, the
1416     * value returned is <code>null</code>
1417     * @exception SQLException if a database access error occurs
1418     */
1419    public byte[] getBytes(String columnName) throws SQLException {
1420        return getBytes(findColumn(columnName));
1421    }
1422
1423    /**
1424     * <!-- start generic documentation -->
1425     * Retrieves the value of the designated column in the current row
1426     * of this <code>ResultSet</code> object as a
1427     * <code>java.sql.Date</code> object in the Java programming language.<p>
1428     * <!-- end generic documentation -->
1429     *
1430     * <!-- start release-specific documentation -->
1431     * <span class="ReleaseSpecificDocumentation">
1432     * </span>
1433     * <!-- end release-specific documentation -->
1434     *
1435     * @param columnName the SQL name of the column
1436     * @return the column value; if the value is SQL <code>NULL</code>, the
1437     * value returned is <code>null</code>
1438     * @exception SQLException if a database access error occurs
1439     */
1440    public java.sql.Date getDate(String columnName) throws SQLException {
1441        return getDate(findColumn(columnName));
1442    }
1443
1444    /**
1445     * <!-- start generic documentation -->
1446     * Retrieves the value of the designated column in the current row
1447     * of this <code>ResultSet</code> object as a <code>java.sql.Time</code>
1448     * object in the Java programming language. <p>
1449     * <!-- end generic documentation -->
1450     *
1451     * <!-- start release-specific documentation -->
1452     * <span class="ReleaseSpecificDocumentation">
1453     * </span>
1454     * <!-- end release-specific documentation -->
1455     *
1456     * @param columnName the SQL name of the column
1457     * @return the column value;
1458     * if the value is SQL <code>NULL</code>,
1459     * the value returned is <code>null</code>
1460     * @exception SQLException if a database access error occurs
1461     */
1462    public java.sql.Time getTime(String columnName) throws SQLException {
1463        return getTime(findColumn(columnName));
1464    }
1465
1466    /**
1467     * <!-- start generic documentation -->
1468     * Retrieves the value of the designated column in the current row
1469     * of this <code>ResultSet</code> object as
1470     * a <code>java.sql.Timestamp</code> object. <p>
1471     * <!-- end generic documentation -->
1472     *
1473     * <!-- start release-specific documentation -->
1474     * <span class="ReleaseSpecificDocumentation">
1475     * </span>
1476     * <!-- end release-specific documentation -->
1477     *
1478     * @param columnName the SQL name of the column
1479     * @return the column value; if the value is SQL <code>NULL</code>, the
1480     * value returned is <code>null</code>
1481     * @exception SQLException if a database access error occurs
1482     */
1483    public java.sql.Timestamp getTimestamp(String columnName)
1484    throws SQLException {
1485        return getTimestamp(findColumn(columnName));
1486    }
1487
1488    /**
1489     * <!-- start generic documentation -->
1490     * Retrieves the value of the designated column in the current row
1491     * of this <code>ResultSet</code> object as a stream of
1492     * ASCII characters. The value can then be read in chunks from the
1493     * stream. This method is particularly
1494     * suitable for retrieving large <code>LONGVARCHAR</code> values.
1495     * The JDBC driver will
1496     * do any necessary conversion from the database format into ASCII.
1497     *
1498     * <P><B>Note:</B> All the data in the returned stream must be
1499     * read prior to getting the value of any other column. The next
1500     * call to a getter method implicitly closes the stream. Also, a
1501     * stream may return <code>0</code> when the method <code>available</code>
1502     * is called whether there is data available or not. <p>
1503     * <!-- end generic documentation -->
1504     *
1505     * <!-- start release-specific documentation -->
1506     * <span class="ReleaseSpecificDocumentation">