~ubuntu-branches/ubuntu/oneiric/mysql-connector-java/oneiric

« back to all changes in this revision

Viewing changes to src/com/mysql/jdbc/ResultSet.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2007-11-30 10:34:13 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071130103413-mxm4lpfrr4fnjbuj
Tags: 5.1.5+dfsg-1
* New upstream release. Closes: #450718.
* Add Homepage field to debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 Copyright (C) 2002-2004 MySQL AB
3
 
 
4
 
 This program is free software; you can redistribute it and/or modify
5
 
 it under the terms of version 2 of the GNU General Public License as
6
 
 published by the Free Software Foundation.
7
 
 
8
 
 There are special exceptions to the terms and conditions of the GPL
9
 
 as it is applied to this software. View the full text of the
10
 
 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
11
 
 software distribution.
12
 
 
13
 
 This program is distributed in the hope that it will be useful,
14
 
 but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 GNU General Public License for more details.
17
 
 
18
 
 You should have received a copy of the GNU General Public License
19
 
 along with this program; if not, write to the Free Software
20
 
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 
 
22
 
 
23
 
 
24
 
 */
25
 
package com.mysql.jdbc;
26
 
 
27
 
import com.mysql.jdbc.profiler.ProfileEventSink;
28
 
import com.mysql.jdbc.profiler.ProfilerEvent;
29
 
 
30
 
import java.io.ByteArrayInputStream;
31
 
import java.io.IOException;
32
 
import java.io.InputStream;
33
 
import java.io.ObjectInputStream;
34
 
import java.io.StringReader;
35
 
import java.io.UnsupportedEncodingException;
36
 
 
37
 
import java.math.BigDecimal;
38
 
import java.math.BigInteger;
39
 
 
40
 
import java.net.MalformedURLException;
41
 
import java.net.URL;
42
 
 
43
 
import java.sql.Array;
44
 
import java.sql.DataTruncation;
45
 
import java.sql.Date;
46
 
import java.sql.Ref;
47
 
import java.sql.SQLException;
48
 
import java.sql.SQLWarning;
49
 
import java.sql.Time;
50
 
import java.sql.Timestamp;
51
 
import java.sql.Types;
52
 
 
53
 
import java.util.Calendar;
54
 
import java.util.GregorianCalendar;
55
 
import java.util.HashMap;
56
 
import java.util.Locale;
57
 
import java.util.Map;
58
 
import java.util.StringTokenizer;
59
 
import java.util.TimeZone;
60
 
 
61
 
/**
62
 
 * A ResultSet provides access to a table of data generated by executing a
63
 
 * Statement. The table rows are retrieved in sequence. Within a row its column
64
 
 * values can be accessed in any order.
65
 
 * 
66
 
 * <P>
67
 
 * A ResultSet maintains a cursor pointing to its current row of data. Initially
68
 
 * the cursor is positioned before the first row. The 'next' method moves the
69
 
 * cursor to the next row.
70
 
 * </p>
71
 
 * 
72
 
 * <P>
73
 
 * The getXXX methods retrieve column values for the current row. You can
74
 
 * retrieve values either using the index number of the column, or by using the
75
 
 * name of the column. In general using the column index will be more efficient.
76
 
 * Columns are numbered from 1.
77
 
 * </p>
78
 
 * 
79
 
 * <P>
80
 
 * For maximum portability, ResultSet columns within each row should be read in
81
 
 * left-to-right order and each column should be read only once.
82
 
 * </p>
83
 
 * 
84
 
 * <P>
85
 
 * For the getXXX methods, the JDBC driver attempts to convert the underlying
86
 
 * data to the specified Java type and returns a suitable Java value. See the
87
 
 * JDBC specification for allowable mappings from SQL types to Java types with
88
 
 * the ResultSet getXXX methods.
89
 
 * </p>
90
 
 * 
91
 
 * <P>
92
 
 * Column names used as input to getXXX methods are case insenstive. When
93
 
 * performing a getXXX using a column name, if several columns have the same
94
 
 * name, then the value of the first matching column will be returned. The
95
 
 * column name option is designed to be used when column names are used in the
96
 
 * SQL Query. For columns that are NOT explicitly named in the query, it is best
97
 
 * to use column numbers. If column names were used there is no way for the
98
 
 * programmer to guarentee that they actually refer to the intended columns.
99
 
 * </p>
100
 
 * 
101
 
 * <P>
102
 
 * A ResultSet is automatically closed by the Statement that generated it when
103
 
 * that Statement is closed, re-executed, or is used to retrieve the next result
104
 
 * from a sequence of multiple results.
105
 
 * </p>
106
 
 * 
107
 
 * <P>
108
 
 * The number, types and properties of a ResultSet's columns are provided by the
109
 
 * ResultSetMetaData object returned by the getMetaData method.
110
 
 * </p>
111
 
 * 
112
 
 * @author Mark Matthews
113
 
 * @version $Id: ResultSet.java 5900 2006-10-18 21:33:06Z mmatthews $
114
 
 * 
115
 
 * @see ResultSetMetaData
116
 
 * @see java.sql.ResultSet
117
 
 */
118
 
public class ResultSet implements java.sql.ResultSet {
119
 
 
120
 
        /**
121
 
         * Epsillon between Float.MIN_VALUE and the double representation of said value.
122
 
         */
123
 
    protected static final double MIN_DIFF_PREC = Float.parseFloat(Float.toString(Float.MIN_VALUE))
124
 
        - Double.parseDouble(Float.toString(Float.MIN_VALUE));
125
 
    
126
 
    /**
127
 
         * Epsillon between Float.MAX_VALUE and the double representation of said value.
128
 
         */
129
 
    protected static final double MAX_DIFF_PREC = Float.parseFloat(Float.toString(Float.MAX_VALUE))
130
 
        - Double.parseDouble(Float.toString(Float.MAX_VALUE));
131
 
    
132
 
        /** Counter used to generate IDs for profiling. */
133
 
        protected static int resultCounter = 1;
134
 
 
135
 
        /**
136
 
         * Converts the given value as a java long, to an 'unsigned' long, using the
137
 
         * java.math.BigInteger class.
138
 
         */
139
 
        protected static BigInteger convertLongToUlong(long longVal) {
140
 
                byte[] asBytes = new byte[8];
141
 
                asBytes[7] = (byte) (longVal & 0xff);
142
 
                asBytes[6] = (byte) (longVal >>> 8);
143
 
                asBytes[5] = (byte) (longVal >>> 16);
144
 
                asBytes[4] = (byte) (longVal >>> 24);
145
 
                asBytes[3] = (byte) (longVal >>> 32);
146
 
                asBytes[2] = (byte) (longVal >>> 40);
147
 
                asBytes[1] = (byte) (longVal >>> 48);
148
 
                asBytes[0] = (byte) (longVal >>> 56);
149
 
 
150
 
                return new BigInteger(1, asBytes);
151
 
        }
152
 
 
153
 
        /** The catalog that was in use when we were created */
154
 
        protected String catalog = null;
155
 
 
156
 
        /** Map column names (and all of their permutations) to column indices */
157
 
        protected Map columnNameToIndex = null;
158
 
 
159
 
        /** Keep track of columns accessed */
160
 
        protected boolean[] columnUsed = null;
161
 
 
162
 
        /** The Connection instance that created us */
163
 
        protected com.mysql.jdbc.Connection connection; // The connection that
164
 
                                                                                                        // created us
165
 
 
166
 
        protected long connectionId = 0;
167
 
        
168
 
        /** The current row #, -1 == before start of result set */
169
 
        protected int currentRow = -1; // Cursor to current row;
170
 
 
171
 
        private TimeZone defaultTimeZone;
172
 
 
173
 
        /** Are we in the middle of doing updates to the current row? */
174
 
        protected boolean doingUpdates = false;
175
 
 
176
 
        protected ProfileEventSink eventSink = null;
177
 
 
178
 
        private Calendar fastDateCal = null;
179
 
 
180
 
        /** The direction to fetch rows (always FETCH_FORWARD) */
181
 
        protected int fetchDirection = FETCH_FORWARD;
182
 
 
183
 
        /** The number of rows to fetch in one go... */
184
 
        protected int fetchSize = 0;
185
 
 
186
 
        /** The fields for this result set */
187
 
        protected Field[] fields; // The fields
188
 
 
189
 
        /**
190
 
         * First character of the query that created this result set...Used to
191
 
         * determine whether or not to parse server info messages in certain
192
 
         * circumstances.
193
 
         */
194
 
        protected char firstCharOfQuery;
195
 
 
196
 
        /** Map of fully-specified column names to column indices */
197
 
        protected Map fullColumnNameToIndex = null;
198
 
 
199
 
        protected boolean hasBuiltIndexMapping = false;
200
 
 
201
 
        /**
202
 
         * Is the data stored as strings (default) or natively (which is the case
203
 
         * with results from PrepStmts)
204
 
         */
205
 
        protected boolean isBinaryEncoded = false;
206
 
 
207
 
        /** Has this result set been closed? */
208
 
        protected boolean isClosed = false;
209
 
 
210
 
        protected ResultSet nextResultSet = null;
211
 
 
212
 
        /** Are we on the insert row? */
213
 
        protected boolean onInsertRow = false;
214
 
 
215
 
        /** The statement that created us */
216
 
        protected com.mysql.jdbc.Statement owningStatement;
217
 
 
218
 
        /**
219
 
         * StackTrace generated where ResultSet was created... used when profiling
220
 
         */
221
 
        protected Throwable pointOfOrigin;
222
 
 
223
 
        /** Are we tracking items for profileSql? */
224
 
        protected boolean profileSql = false;
225
 
 
226
 
        /**
227
 
         * Do we actually contain rows, or just information about
228
 
         * UPDATE/INSERT/DELETE?
229
 
         */
230
 
        protected boolean reallyResult = false;
231
 
 
232
 
        /** The id (used when profiling) to identify us */
233
 
        protected int resultId;
234
 
 
235
 
        /** Are we read-only or updatable? */
236
 
        protected int resultSetConcurrency = 0;
237
 
 
238
 
        /** Are we scroll-sensitive/insensitive? */
239
 
        protected int resultSetType = 0;
240
 
 
241
 
        /** The actual rows */
242
 
        protected RowData rowData; // The results
243
 
 
244
 
        /**
245
 
         * Any info message from the server that was created while generating this
246
 
         * result set (if 'info parsing' is enabled for the connection).
247
 
         */
248
 
        protected String serverInfo = null;
249
 
 
250
 
        private PreparedStatement statementUsedForFetchingRows;
251
 
 
252
 
        /** Pointer to current row data */
253
 
        protected Object[] thisRow = null; // Values for current row
254
 
 
255
 
        // These are longs for
256
 
        // recent versions of the MySQL server.
257
 
        //
258
 
        // They get reduced to ints via the JDBC API,
259
 
        // but can be retrieved through a MySQLStatement
260
 
        // in their entirety.
261
 
        //
262
 
 
263
 
        /** How many rows were affected by UPDATE/INSERT/DELETE? */
264
 
        protected long updateCount;
265
 
 
266
 
        /** Value generated for AUTO_INCREMENT columns */
267
 
        protected long updateId = -1;
268
 
 
269
 
        private boolean useStrictFloatingPoint = false;
270
 
 
271
 
        protected boolean useUsageAdvisor = false;
272
 
 
273
 
        /** The warning chain */
274
 
        protected java.sql.SQLWarning warningChain = null;
275
 
 
276
 
        /** Did the previous value retrieval find a NULL? */
277
 
        protected boolean wasNullFlag = false;
278
 
 
279
 
        protected java.sql.Statement wrapperStatement;
280
 
 
281
 
        protected boolean retainOwningStatement;
282
 
 
283
 
        protected Calendar gmtCalendar = null;
284
 
 
285
 
        /**
286
 
         * Create a result set for an executeUpdate statement.
287
 
         * 
288
 
         * @param updateCount
289
 
         *            the number of rows affected by the update
290
 
         * @param updateID
291
 
         *            the autoincrement value (if any)
292
 
         * @param conn
293
 
         *            DOCUMENT ME!
294
 
         * @param creatorStmt
295
 
         *            DOCUMENT ME!
296
 
         */
297
 
        public ResultSet(long updateCount, long updateID, Connection conn,
298
 
                        Statement creatorStmt) {
299
 
                this.updateCount = updateCount;
300
 
                this.updateId = updateID;
301
 
                this.reallyResult = false;
302
 
                this.fields = new Field[0];
303
 
 
304
 
                this.connection = conn;
305
 
                this.owningStatement = creatorStmt;
306
 
                
307
 
                this.retainOwningStatement = false;
308
 
                
309
 
                if (this.connection != null) {
310
 
                        this.retainOwningStatement = 
311
 
                                this.connection.getRetainStatementAfterResultSetClose();
312
 
                        
313
 
                        this.connectionId = this.connection.getId();
314
 
                }
315
 
        }
316
 
 
317
 
        /**
318
 
         * Creates a new ResultSet object.
319
 
         * 
320
 
         * @param catalog
321
 
         *            the database in use when we were created
322
 
         * @param fields
323
 
         *            an array of Field objects (basically, the ResultSet MetaData)
324
 
         * @param tuples
325
 
         *            actual row data
326
 
         * @param conn
327
 
         *            the Connection that created us.
328
 
         * @param creatorStmt
329
 
         *            DOCUMENT ME!
330
 
         * 
331
 
         * @throws SQLException
332
 
         *             if an error occurs
333
 
         */
334
 
        public ResultSet(String catalog, Field[] fields, RowData tuples,
335
 
                        Connection conn, Statement creatorStmt) throws SQLException {
336
 
                this.connection = conn;
337
 
                
338
 
                this.fastDateCal = new GregorianCalendar(Locale.US);
339
 
                this.fastDateCal.setTimeZone(this.getDefaultTimeZone());
340
 
                
341
 
                if (this.connection != null) {
342
 
                        this.useStrictFloatingPoint = this.connection
343
 
                                        .getStrictFloatingPoint();
344
 
                        this.setDefaultTimeZone(this.connection.getDefaultTimeZone());
345
 
                        this.connectionId = this.connection.getId();
346
 
                }
347
 
 
348
 
                this.owningStatement = creatorStmt;
349
 
 
350
 
                this.catalog = catalog;
351
 
                this.profileSql = this.connection.getProfileSql();
352
 
 
353
 
                this.fields = fields;
354
 
                this.rowData = tuples;
355
 
                this.updateCount = this.rowData.size();
356
 
 
357
 
                if (Driver.DEBUG) {
358
 
                        System.out.println(Messages.getString("ResultSet.Retrieved__1")
359
 
                                        + this.updateCount + " rows"); //$NON-NLS-1$
360
 
                }
361
 
 
362
 
                this.reallyResult = true;
363
 
 
364
 
                // Check for no results
365
 
                if (this.rowData.size() > 0) {
366
 
                        if (this.updateCount == 1) {
367
 
                                if (this.thisRow == null) {
368
 
                                        this.rowData.close(); // empty result set
369
 
                                        this.updateCount = -1;
370
 
                                }
371
 
                        }
372
 
                } else {
373
 
                        this.thisRow = null;
374
 
                }
375
 
 
376
 
                this.rowData.setOwner(this);
377
 
 
378
 
                if (this.profileSql || this.connection.getUseUsageAdvisor()) {
379
 
                        this.columnUsed = new boolean[this.fields.length];
380
 
                        this.pointOfOrigin = new Throwable();
381
 
                        this.resultId = resultCounter++;
382
 
                        this.useUsageAdvisor = this.connection.getUseUsageAdvisor();
383
 
                        this.eventSink = ProfileEventSink.getInstance(this.connection);
384
 
                }
385
 
 
386
 
                if (this.connection.getGatherPerformanceMetrics()) {
387
 
                        this.connection.incrementNumberOfResultSetsCreated();
388
 
 
389
 
                        Map tableNamesMap = new HashMap();
390
 
 
391
 
                        for (int i = 0; i < this.fields.length; i++) {
392
 
                                Field f = this.fields[i];
393
 
 
394
 
                                String tableName = f.getOriginalTableName();
395
 
 
396
 
                                if (tableName == null) {
397
 
                                        tableName = f.getTableName();
398
 
                                }
399
 
 
400
 
                                if (tableName != null) {
401
 
                                        if (this.connection.lowerCaseTableNames()) {
402
 
                                                tableName = tableName.toLowerCase(); // on windows, table
403
 
                                                // names are not case-sens.
404
 
                                        }
405
 
 
406
 
                                        tableNamesMap.put(tableName, null);
407
 
                                }
408
 
                        }
409
 
 
410
 
                        this.connection.reportNumberOfTablesAccessed(tableNamesMap.size());
411
 
                }
412
 
                
413
 
                this.retainOwningStatement = false;
414
 
                
415
 
                if (this.connection != null) {
416
 
                        retainOwningStatement = 
417
 
                                this.connection.getRetainStatementAfterResultSetClose();
418
 
                }
419
 
        }
420
 
 
421
 
        /**
422
 
         * JDBC 2.0
423
 
         * 
424
 
         * <p>
425
 
         * Move to an absolute row number in the result set.
426
 
         * </p>
427
 
         * 
428
 
         * <p>
429
 
         * If row is positive, moves to an absolute row with respect to the
430
 
         * beginning of the result set. The first row is row 1, the second is row 2,
431
 
         * etc.
432
 
         * </p>
433
 
         * 
434
 
         * <p>
435
 
         * If row is negative, moves to an absolute row position with respect to the
436
 
         * end of result set. For example, calling absolute(-1) positions the cursor
437
 
         * on the last row, absolute(-2) indicates the next-to-last row, etc.
438
 
         * </p>
439
 
         * 
440
 
         * <p>
441
 
         * An attempt to position the cursor beyond the first/last row in the result
442
 
         * set, leaves the cursor before/after the first/last row, respectively.
443
 
         * </p>
444
 
         * 
445
 
         * <p>
446
 
         * Note: Calling absolute(1) is the same as calling first(). Calling
447
 
         * absolute(-1) is the same as calling last().
448
 
         * </p>
449
 
         * 
450
 
         * @param row
451
 
         *            the row number to move to
452
 
         * 
453
 
         * @return true if on the result set, false if off.
454
 
         * 
455
 
         * @exception SQLException
456
 
         *                if a database-access error occurs, or row is 0, or result
457
 
         *                set type is TYPE_FORWARD_ONLY.
458
 
         */
459
 
        public boolean absolute(int row) throws SQLException {
460
 
                checkClosed();
461
 
 
462
 
                boolean b;
463
 
 
464
 
                if (this.rowData.size() == 0) {
465
 
                        b = false;
466
 
                } else {
467
 
                        if (row == 0) {
468
 
                                throw SQLError.createSQLException(
469
 
                                                Messages
470
 
                                                                .getString("ResultSet.Cannot_absolute_position_to_row_0_110"), //$NON-NLS-1$
471
 
                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
472
 
                        }
473
 
 
474
 
                        if (this.onInsertRow) {
475
 
                                this.onInsertRow = false;
476
 
                        }
477
 
 
478
 
                        if (this.doingUpdates) {
479
 
                                this.doingUpdates = false;
480
 
                        }
481
 
 
482
 
                        if (row == 1) {
483
 
                                b = first();
484
 
                        } else if (row == -1) {
485
 
                                b = last();
486
 
                        } else if (row > this.rowData.size()) {
487
 
                                afterLast();
488
 
                                b = false;
489
 
                        } else {
490
 
                                if (row < 0) {
491
 
                                        // adjust to reflect after end of result set
492
 
                                        int newRowPosition = this.rowData.size() + row + 1;
493
 
 
494
 
                                        if (newRowPosition <= 0) {
495
 
                                                beforeFirst();
496
 
                                                b = false;
497
 
                                        } else {
498
 
                                                b = absolute(newRowPosition);
499
 
                                        }
500
 
                                } else {
501
 
                                        row--; // adjust for index difference
502
 
                                        this.rowData.setCurrentRow(row);
503
 
                                        this.thisRow = this.rowData.getAt(row);
504
 
                                        b = true;
505
 
                                }
506
 
                        }
507
 
                }
508
 
 
509
 
                return b;
510
 
        }
511
 
 
512
 
        /**
513
 
         * JDBC 2.0
514
 
         * 
515
 
         * <p>
516
 
         * Moves to the end of the result set, just after the last row. Has no
517
 
         * effect if the result set contains no rows.
518
 
         * </p>
519
 
         * 
520
 
         * @exception SQLException
521
 
         *                if a database-access error occurs, or result set type is
522
 
         *                TYPE_FORWARD_ONLY.
523
 
         */
524
 
        public void afterLast() throws SQLException {
525
 
                checkClosed();
526
 
 
527
 
                if (this.onInsertRow) {
528
 
                        this.onInsertRow = false;
529
 
                }
530
 
 
531
 
                if (this.doingUpdates) {
532
 
                        this.doingUpdates = false;
533
 
                }
534
 
 
535
 
                if (this.rowData.size() != 0) {
536
 
                        this.rowData.afterLast();
537
 
                        this.thisRow = null;
538
 
                }
539
 
        }
540
 
 
541
 
        /**
542
 
         * JDBC 2.0
543
 
         * 
544
 
         * <p>
545
 
         * Moves to the front of the result set, just before the first row. Has no
546
 
         * effect if the result set contains no rows.
547
 
         * </p>
548
 
         * 
549
 
         * @exception SQLException
550
 
         *                if a database-access error occurs, or result set type is
551
 
         *                TYPE_FORWARD_ONLY
552
 
         */
553
 
        public void beforeFirst() throws SQLException {
554
 
                checkClosed();
555
 
 
556
 
                if (this.onInsertRow) {
557
 
                        this.onInsertRow = false;
558
 
                }
559
 
 
560
 
                if (this.doingUpdates) {
561
 
                        this.doingUpdates = false;
562
 
                }
563
 
 
564
 
                if (this.rowData.size() == 0) {
565
 
                        return;
566
 
                }
567
 
 
568
 
                this.rowData.beforeFirst();
569
 
                this.thisRow = null;
570
 
        }
571
 
 
572
 
        // ---------------------------------------------------------------------
573
 
        // Traversal/Positioning
574
 
        // ---------------------------------------------------------------------
575
 
 
576
 
        /**
577
 
         * Builds a hash between column names and their indices for fast retrieval.
578
 
         */
579
 
        protected void buildIndexMapping() throws SQLException {
580
 
                int numFields = this.fields.length;
581
 
                this.columnNameToIndex = new HashMap(numFields);
582
 
                this.fullColumnNameToIndex = new HashMap(numFields);
583
 
 
584
 
                // We do this in reverse order, so that the 'first' column
585
 
                // with a given name ends up as the final mapping in the
586
 
                // hashtable...
587
 
                //
588
 
                // Quoting the JDBC Spec:
589
 
                //
590
 
                // "Column names used as input to getter
591
 
                // methods are case insensitive. When a getter method is called with a
592
 
                // column
593
 
                // name and several columns have the same name, the value of the first
594
 
                // matching column will be returned. "
595
 
                //
596
 
                for (int i = numFields - 1; i >= 0; i--) {
597
 
                        Integer index = new Integer(i);
598
 
                        String columnName = this.fields[i].getName();
599
 
                        String fullColumnName = this.fields[i].getFullName();
600
 
 
601
 
                        if (columnName != null) {
602
 
                                this.columnNameToIndex.put(columnName, index);
603
 
                                this.columnNameToIndex.put(columnName.toUpperCase(), index);
604
 
                                this.columnNameToIndex.put(columnName.toLowerCase(), index);
605
 
                        }
606
 
 
607
 
                        if (fullColumnName != null) {
608
 
                                this.fullColumnNameToIndex.put(fullColumnName, index);
609
 
                                this.fullColumnNameToIndex.put(fullColumnName.toUpperCase(),
610
 
                                                index);
611
 
                                this.fullColumnNameToIndex.put(fullColumnName.toLowerCase(),
612
 
                                                index);
613
 
                        }
614
 
                }
615
 
 
616
 
                // set the flag to prevent rebuilding...
617
 
                this.hasBuiltIndexMapping = true;
618
 
        }
619
 
 
620
 
        /**
621
 
         * JDBC 2.0 The cancelRowUpdates() method may be called after calling an
622
 
         * updateXXX() method(s) and before calling updateRow() to rollback the
623
 
         * updates made to a row. If no updates have been made or updateRow() has
624
 
         * already been called, then this method has no effect.
625
 
         * 
626
 
         * @exception SQLException
627
 
         *                if a database-access error occurs, or if called when on
628
 
         *                the insert row.
629
 
         * @throws NotUpdatable
630
 
         *             DOCUMENT ME!
631
 
         */
632
 
        public void cancelRowUpdates() throws SQLException {
633
 
                throw new NotUpdatable();
634
 
        }
635
 
 
636
 
        /**
637
 
         * Ensures that the result set is not closed
638
 
         * 
639
 
         * @throws SQLException
640
 
         *             if the result set is closed
641
 
         */
642
 
        protected final void checkClosed() throws SQLException {
643
 
                if (this.isClosed) {
644
 
                        throw SQLError.createSQLException(
645
 
                                        Messages
646
 
                                                        .getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$
647
 
                                        SQLError.SQL_STATE_GENERAL_ERROR);
648
 
                }
649
 
        }
650
 
 
651
 
        /**
652
 
         * Checks if columnIndex is within the number of columns in this result set.
653
 
         * 
654
 
         * @param columnIndex
655
 
         *            the index to check
656
 
         * 
657
 
         * @throws SQLException
658
 
         *             if the index is out of bounds
659
 
         */
660
 
        protected final void checkColumnBounds(int columnIndex) throws SQLException {
661
 
                if ((columnIndex < 1) || (columnIndex > this.fields.length)) {
662
 
                        throw SQLError.createSQLException(Messages.getString(
663
 
                                        "ResultSet.Column_Index_out_of_range", new Object[] {
664
 
                                                        new Integer(columnIndex),
665
 
                                                        new Integer(this.fields.length) }),
666
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
667
 
                }
668
 
 
669
 
                if (this.profileSql || this.useUsageAdvisor) {
670
 
                        this.columnUsed[columnIndex - 1] = true;
671
 
                }
672
 
        }
673
 
 
674
 
        /**
675
 
         * Ensures that the cursor is positioned on a valid row and that the result
676
 
         * set is not closed
677
 
         * 
678
 
         * @throws SQLException
679
 
         *             if the result set is not in a valid state for traversal
680
 
         */
681
 
        protected void checkRowPos() throws SQLException {
682
 
                checkClosed();
683
 
 
684
 
                if (!this.rowData.isDynamic() && (this.rowData.size() == 0)) {
685
 
                        throw SQLError.createSQLException(
686
 
                                        Messages
687
 
                                                        .getString("ResultSet.Illegal_operation_on_empty_result_set"),
688
 
                                        SQLError.SQL_STATE_GENERAL_ERROR);
689
 
                }
690
 
 
691
 
                if (this.rowData.isBeforeFirst()) {
692
 
                        throw SQLError.createSQLException(Messages
693
 
                                        .getString("ResultSet.Before_start_of_result_set_146"),
694
 
                                        SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
695
 
                }
696
 
 
697
 
                if (this.rowData.isAfterLast()) {
698
 
                        throw SQLError.createSQLException(Messages
699
 
                                        .getString("ResultSet.After_end_of_result_set_148"),
700
 
                                        SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
701
 
                }
702
 
        }
703
 
 
704
 
        /**
705
 
         * We can't do this ourselves, otherwise the contract for
706
 
         * Statement.getMoreResults() won't work correctly.
707
 
         */
708
 
        protected void clearNextResult() {
709
 
                this.nextResultSet = null;
710
 
        }
711
 
 
712
 
        /**
713
 
         * After this call, getWarnings returns null until a new warning is reported
714
 
         * for this ResultSet
715
 
         * 
716
 
         * @exception SQLException
717
 
         *                if a database access error occurs
718
 
         */
719
 
        public void clearWarnings() throws SQLException {
720
 
                this.warningChain = null;
721
 
        }
722
 
 
723
 
        /**
724
 
         * In some cases, it is desirable to immediately release a ResultSet
725
 
         * database and JDBC resources instead of waiting for this to happen when it
726
 
         * is automatically closed. The close method provides this immediate
727
 
         * release.
728
 
         * 
729
 
         * <p>
730
 
         * <B>Note:</B> A ResultSet is automatically closed by the Statement the
731
 
         * Statement that generated it when that Statement is closed, re-executed,
732
 
         * or is used to retrieve the next result from a sequence of multiple
733
 
         * results. A ResultSet is also automatically closed when it is garbage
734
 
         * collected.
735
 
         * </p>
736
 
         * 
737
 
         * @exception SQLException
738
 
         *                if a database access error occurs
739
 
         */
740
 
        public void close() throws SQLException {
741
 
                realClose(true);
742
 
        }
743
 
 
744
 
        /**
745
 
         * @return
746
 
         */
747
 
        private int convertToZeroWithEmptyCheck() throws SQLException {
748
 
                if (this.connection.getEmptyStringsConvertToZero()) {
749
 
                        return 0;
750
 
                }
751
 
 
752
 
                throw SQLError.createSQLException("Can't convert empty string ('') to numeric",
753
 
                                SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
754
 
        }
755
 
        
756
 
        private String convertToZeroLiteralStringWithEmptyCheck()
757
 
                throws SQLException {
758
 
                
759
 
                if (this.connection.getEmptyStringsConvertToZero()) {
760
 
                        return "0";
761
 
                }
762
 
 
763
 
                throw SQLError.createSQLException("Can't convert empty string ('') to numeric",
764
 
                                SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
765
 
        }
766
 
 
767
 
        //
768
 
        // Note, row data is linked between these two result sets
769
 
        //
770
 
        protected final ResultSet copy() throws SQLException {
771
 
                ResultSet rs = new ResultSet(this.catalog, this.fields, this.rowData,
772
 
                                this.connection, this.owningStatement);
773
 
 
774
 
                return rs;
775
 
        }
776
 
 
777
 
        protected void redefineFieldsForDBMD(Field[] f) {
778
 
                this.fields = f;
779
 
                
780
 
                for (int i = 0; i < this.fields.length; i++) {
781
 
                        this.fields[i].setUseOldNameMetadata(true);
782
 
                }
783
 
        }
784
 
 
785
 
        /**
786
 
         * JDBC 2.0 Delete the current row from the result set and the underlying
787
 
         * database. Cannot be called when on the insert row.
788
 
         * 
789
 
         * @exception SQLException
790
 
         *                if a database-access error occurs, or if called when on
791
 
         *                the insert row.
792
 
         * @throws NotUpdatable
793
 
         *             DOCUMENT ME!
794
 
         */
795
 
        public void deleteRow() throws SQLException {
796
 
                throw new NotUpdatable();
797
 
        }
798
 
 
799
 
        /**
800
 
         * @param columnIndex
801
 
         * @param stringVal
802
 
         * @param mysqlType
803
 
         * @return
804
 
         * @throws SQLException
805
 
         */
806
 
        private String extractStringFromNativeColumn(int columnIndex, int mysqlType)
807
 
                        throws SQLException {
808
 
                int columnIndexMinusOne = columnIndex - 1;
809
 
 
810
 
                this.wasNullFlag = false;
811
 
                
812
 
                if (this.thisRow[columnIndexMinusOne] instanceof String) {
813
 
                        return (String) this.thisRow[columnIndexMinusOne];
814
 
                }
815
 
 
816
 
                if (this.thisRow[columnIndexMinusOne] == null) {
817
 
                        this.wasNullFlag = true;
818
 
                        
819
 
                        return null;
820
 
                }
821
 
 
822
 
                this.wasNullFlag = false;
823
 
                
824
 
                String stringVal = null;
825
 
 
826
 
                if ((this.connection != null) && this.connection.getUseUnicode()) {
827
 
                        try {
828
 
                                String encoding = this.fields[columnIndexMinusOne]
829
 
                                                .getCharacterSet();
830
 
 
831
 
                                if (encoding == null) {
832
 
                                        stringVal = new String(
833
 
                                                        (byte[]) this.thisRow[columnIndexMinusOne]);
834
 
                                } else {
835
 
                                        SingleByteCharsetConverter converter = this.connection
836
 
                                                        .getCharsetConverter(encoding);
837
 
 
838
 
                                        if (converter != null) {
839
 
                                                stringVal = converter
840
 
                                                                .toString((byte[]) this.thisRow[columnIndexMinusOne]);
841
 
                                        } else {
842
 
                                                stringVal = new String(
843
 
                                                                (byte[]) this.thisRow[columnIndexMinusOne],
844
 
                                                                encoding);
845
 
                                        }
846
 
                                }
847
 
                        } catch (java.io.UnsupportedEncodingException E) {
848
 
                                throw SQLError.createSQLException(
849
 
                                                Messages
850
 
                                                                .getString("ResultSet.Unsupported_character_encoding____138") //$NON-NLS-1$
851
 
                                                                + this.connection.getEncoding() + "'.", "0S100");
852
 
                        }
853
 
                } else {
854
 
                        stringVal = StringUtils
855
 
                                        .toAsciiString((byte[]) this.thisRow[columnIndexMinusOne]);
856
 
                }
857
 
                
858
 
                return stringVal;
859
 
        }
860
 
 
861
 
        private Date fastDateCreate(Calendar cal, int year, int month,
862
 
                        int day) {
863
 
                if (cal == null) {
864
 
                        cal = this.fastDateCal;
865
 
                }
866
 
 
867
 
                boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes();
868
 
                                                
869
 
                return TimeUtil.fastDateCreate(useGmtMillis,
870
 
                                useGmtMillis ? getGmtCalendar() : null,
871
 
                                cal, year, month, day);
872
 
        }
873
 
 
874
 
        private Time fastTimeCreate(Calendar cal, int hour,
875
 
                        int minute, int second) throws SQLException {
876
 
                if (cal == null) {
877
 
                        cal = this.fastDateCal;
878
 
                }
879
 
 
880
 
                return TimeUtil.fastTimeCreate(cal, hour, minute, second);
881
 
        }
882
 
 
883
 
        private Timestamp fastTimestampCreate(Calendar cal, int year,
884
 
                        int month, int day, int hour, int minute, int seconds,
885
 
                        int secondsPart) {
886
 
                if (cal == null) {
887
 
                        cal = this.fastDateCal;
888
 
                }
889
 
 
890
 
                boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes();
891
 
                
892
 
                return TimeUtil.fastTimestampCreate(useGmtMillis,
893
 
                                useGmtMillis ? getGmtCalendar() : null,
894
 
                                cal, year, month, day, hour,
895
 
                                minute, seconds, secondsPart);
896
 
        }
897
 
 
898
 
        /*
899
 
        /**
900
 
         * Required by JDBC spec
901
 
         */
902
 
        /*
903
 
        protected void finalize() throws Throwable {
904
 
                if (!this.isClosed) {
905
 
                        realClose(false);
906
 
                }
907
 
        }
908
 
        */
909
 
 
910
 
        // --------------------------JDBC 2.0-----------------------------------
911
 
        // ---------------------------------------------------------------------
912
 
        // Getter's and Setter's
913
 
        // ---------------------------------------------------------------------
914
 
 
915
 
 
916
 
        /**
917
 
         * Map a ResultSet column name to a ResultSet column index
918
 
         * 
919
 
         * @param columnName
920
 
         *            the name of the column
921
 
         * 
922
 
         * @return the column index
923
 
         * 
924
 
         * @exception SQLException
925
 
         *                if a database access error occurs
926
 
         */
927
 
        public synchronized int findColumn(String columnName) throws SQLException {
928
 
                Integer index;
929
 
 
930
 
                if (!this.hasBuiltIndexMapping) {
931
 
                        buildIndexMapping();
932
 
                }
933
 
 
934
 
                index = (Integer) this.columnNameToIndex.get(columnName);
935
 
 
936
 
                if (index == null) {
937
 
                        index = (Integer) this.fullColumnNameToIndex.get(columnName);
938
 
                }
939
 
 
940
 
                if (index != null) {
941
 
                        return index.intValue() + 1;
942
 
                }
943
 
 
944
 
                // Try this inefficient way, now
945
 
 
946
 
                for (int i = 0; i < this.fields.length; i++) {
947
 
                        if (this.fields[i].getName().equalsIgnoreCase(columnName)) {
948
 
                                return i + 1;
949
 
                        } else if (this.fields[i].getFullName()
950
 
                                        .equalsIgnoreCase(columnName)) {
951
 
                                return i + 1;
952
 
                        }
953
 
                }
954
 
 
955
 
                throw SQLError.createSQLException(Messages.getString("ResultSet.Column____112")
956
 
                                + columnName
957
 
                                + Messages.getString("ResultSet.___not_found._113"), //$NON-NLS-1$ //$NON-NLS-2$
958
 
                                SQLError.SQL_STATE_COLUMN_NOT_FOUND);
959
 
        }
960
 
 
961
 
        /**
962
 
         * JDBC 2.0
963
 
         * 
964
 
         * <p>
965
 
         * Moves to the first row in the result set.
966
 
         * </p>
967
 
         * 
968
 
         * @return true if on a valid row, false if no rows in the result set.
969
 
         * 
970
 
         * @exception SQLException
971
 
         *                if a database-access error occurs, or result set type is
972
 
         *                TYPE_FORWARD_ONLY.
973
 
         */
974
 
        public boolean first() throws SQLException {
975
 
                checkClosed();
976
 
 
977
 
                if (this.rowData.isEmpty()) {
978
 
                        return false;
979
 
                }
980
 
 
981
 
                if (this.onInsertRow) {
982
 
                        this.onInsertRow = false;
983
 
                }
984
 
 
985
 
                if (this.doingUpdates) {
986
 
                        this.doingUpdates = false;
987
 
                }
988
 
 
989
 
                this.rowData.beforeFirst();
990
 
                this.thisRow = this.rowData.next();
991
 
 
992
 
                return true;
993
 
        }
994
 
 
995
 
        /**
996
 
         * JDBC 2.0 Get an array column.
997
 
         * 
998
 
         * @param i
999
 
         *            the first column is 1, the second is 2, ...
1000
 
         * 
1001
 
         * @return an object representing an SQL array
1002
 
         * 
1003
 
         * @throws SQLException
1004
 
         *             if a database error occurs
1005
 
         * @throws NotImplemented
1006
 
         *             DOCUMENT ME!
1007
 
         */
1008
 
        public java.sql.Array getArray(int i) throws SQLException {
1009
 
                checkColumnBounds(i);
1010
 
                
1011
 
                throw new NotImplemented();
1012
 
        }
1013
 
 
1014
 
        /**
1015
 
         * JDBC 2.0 Get an array column.
1016
 
         * 
1017
 
         * @param colName
1018
 
         *            the column name
1019
 
         * 
1020
 
         * @return an object representing an SQL array
1021
 
         * 
1022
 
         * @throws SQLException
1023
 
         *             if a database error occurs
1024
 
         * @throws NotImplemented
1025
 
         *             DOCUMENT ME!
1026
 
         */
1027
 
        public java.sql.Array getArray(String colName) throws SQLException {
1028
 
                return getArray(findColumn(colName));
1029
 
        }
1030
 
 
1031
 
        /**
1032
 
         * A column value can be retrieved as a stream of ASCII characters and then
1033
 
         * read in chunks from the stream. This method is particulary suitable for
1034
 
         * retrieving large LONGVARCHAR values. The JDBC driver will do any
1035
 
         * necessary conversion from the database format into ASCII.
1036
 
         * 
1037
 
         * <p>
1038
 
         * <B>Note:</B> All the data in the returned stream must be read prior to
1039
 
         * getting the value of any other column. The next call to a get method
1040
 
         * implicitly closes the stream. Also, a stream may return 0 for available()
1041
 
         * whether there is data available or not.
1042
 
         * </p>
1043
 
         * 
1044
 
         * @param columnIndex
1045
 
         *            the first column is 1, the second is 2, ...
1046
 
         * 
1047
 
         * @return a Java InputStream that delivers the database column value as a
1048
 
         *         stream of one byte ASCII characters. If the value is SQL NULL
1049
 
         *         then the result is null
1050
 
         * 
1051
 
         * @exception SQLException
1052
 
         *                if a database access error occurs
1053
 
         * 
1054
 
         * @see getBinaryStream
1055
 
         */
1056
 
        public InputStream getAsciiStream(int columnIndex) throws SQLException {
1057
 
                checkRowPos();
1058
 
 
1059
 
                if (!this.isBinaryEncoded) {
1060
 
                        return getBinaryStream(columnIndex);
1061
 
                }
1062
 
 
1063
 
                return getNativeBinaryStream(columnIndex);
1064
 
        }
1065
 
 
1066
 
        /**
1067
 
         * DOCUMENT ME!
1068
 
         * 
1069
 
         * @param columnName
1070
 
         *            DOCUMENT ME!
1071
 
         * 
1072
 
         * @return DOCUMENT ME!
1073
 
         * 
1074
 
         * @throws SQLException
1075
 
         *             DOCUMENT ME!
1076
 
         */
1077
 
        public InputStream getAsciiStream(String columnName) throws SQLException {
1078
 
                return getAsciiStream(findColumn(columnName));
1079
 
        }
1080
 
 
1081
 
        /**
1082
 
         * JDBC 2.0 Get the value of a column in the current row as a
1083
 
         * java.math.BigDecimal object.
1084
 
         * 
1085
 
         * @param columnIndex
1086
 
         *            the first column is 1, the second is 2, ...
1087
 
         * 
1088
 
         * @return the column value (full precision); if the value is SQL NULL, the
1089
 
         *         result is null
1090
 
         * 
1091
 
         * @exception SQLException
1092
 
         *                if a database-access error occurs.
1093
 
         */
1094
 
        public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
1095
 
                if (!this.isBinaryEncoded) {
1096
 
                        String stringVal = getString(columnIndex);
1097
 
                        BigDecimal val;
1098
 
 
1099
 
                        if (stringVal != null) {
1100
 
                                if (stringVal.length() == 0) {
1101
 
                                        
1102
 
                                        val = new BigDecimal(
1103
 
                                                        convertToZeroLiteralStringWithEmptyCheck());
1104
 
 
1105
 
                                        return val;
1106
 
                                }
1107
 
 
1108
 
                                try {
1109
 
                                        val = new BigDecimal(stringVal);
1110
 
 
1111
 
                                        return val;
1112
 
                                } catch (NumberFormatException ex) {
1113
 
                                        throw SQLError.createSQLException(Messages
1114
 
                                                        .getString("ResultSet.Bad_format_for_BigDecimal",
1115
 
                                                                        new Object[] { stringVal,
1116
 
                                                                                        new Integer(columnIndex) }),
1117
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1118
 
                                }
1119
 
                        }
1120
 
 
1121
 
                        return null;
1122
 
                }
1123
 
 
1124
 
                return getNativeBigDecimal(columnIndex);
1125
 
        }
1126
 
 
1127
 
        /**
1128
 
         * Get the value of a column in the current row as a java.math.BigDecimal
1129
 
         * object
1130
 
         * 
1131
 
         * @param columnIndex
1132
 
         *            the first column is 1, the second is 2...
1133
 
         * @param scale
1134
 
         *            the number of digits to the right of the decimal
1135
 
         * 
1136
 
         * @return the column value; if the value is SQL NULL, null
1137
 
         * 
1138
 
         * @exception SQLException
1139
 
         *                if a database access error occurs
1140
 
         * 
1141
 
         * @deprecated
1142
 
         */
1143
 
        public BigDecimal getBigDecimal(int columnIndex, int scale)
1144
 
                        throws SQLException {
1145
 
                if (!this.isBinaryEncoded) {
1146
 
                        String stringVal = getString(columnIndex);
1147
 
                        BigDecimal val;
1148
 
 
1149
 
                        if (stringVal != null) {
1150
 
                                if (stringVal.length() == 0) {
1151
 
                                        val = new BigDecimal(
1152
 
                                                        convertToZeroLiteralStringWithEmptyCheck());
1153
 
 
1154
 
                                        try {
1155
 
                                                return val.setScale(scale);
1156
 
                                        } catch (ArithmeticException ex) {
1157
 
                                                try {
1158
 
                                                        return val
1159
 
                                                                        .setScale(scale, BigDecimal.ROUND_HALF_UP);
1160
 
                                                } catch (ArithmeticException arEx) {
1161
 
                                                        throw SQLError.createSQLException(
1162
 
                                                                        Messages
1163
 
                                                                                        .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$
1164
 
                                                                                        + stringVal
1165
 
                                                                                        + Messages
1166
 
                                                                                                        .getString("ResultSet.___in_column__125")
1167
 
                                                                                        + columnIndex
1168
 
                                                                                        + "(" //$NON-NLS-1$
1169
 
                                                                                        + this.fields[columnIndex - 1]
1170
 
                                                                                        + ").",
1171
 
                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
1172
 
                                                }
1173
 
                                        }
1174
 
                                }
1175
 
 
1176
 
                                try {
1177
 
                                        val = new BigDecimal(stringVal);
1178
 
                                } catch (NumberFormatException ex) {
1179
 
                                        if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
1180
 
                                                long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
1181
 
 
1182
 
                                                val = new BigDecimal(valueAsLong);
1183
 
                                        } else {
1184
 
                                                throw SQLError.createSQLException(Messages
1185
 
                                                        .getString("ResultSet.Bad_format_for_BigDecimal",
1186
 
                                                                        new Object[] { new Integer(columnIndex),
1187
 
                                                                                        stringVal }),
1188
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1189
 
                                                }
1190
 
                                }
1191
 
 
1192
 
                                try {
1193
 
                                        return val.setScale(scale);
1194
 
                                } catch (ArithmeticException ex) {
1195
 
                                        try {
1196
 
                                                return val.setScale(scale, BigDecimal.ROUND_HALF_UP);
1197
 
                                        } catch (ArithmeticException arithEx) {
1198
 
                                                throw SQLError.createSQLException(Messages.getString(
1199
 
                                                                "ResultSet.Bad_format_for_BigDecimal",
1200
 
                                                                new Object[] { new Integer(columnIndex),
1201
 
                                                                                stringVal }),
1202
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1203
 
                                        }
1204
 
                                }
1205
 
                        }
1206
 
 
1207
 
                        return null;
1208
 
                }
1209
 
 
1210
 
                return getNativeBigDecimal(columnIndex, scale);
1211
 
        }
1212
 
 
1213
 
        /**
1214
 
         * JDBC 2.0 Get the value of a column in the current row as a
1215
 
         * java.math.BigDecimal object.
1216
 
         * 
1217
 
         * @param columnName
1218
 
         *            the name of the column to retrieve the value from
1219
 
         * 
1220
 
         * @return the BigDecimal value in the column
1221
 
         * 
1222
 
         * @throws SQLException
1223
 
         *             if an error occurs
1224
 
         */
1225
 
        public BigDecimal getBigDecimal(String columnName) throws SQLException {
1226
 
                return getBigDecimal(findColumn(columnName));
1227
 
        }
1228
 
 
1229
 
        /**
1230
 
         * DOCUMENT ME!
1231
 
         * 
1232
 
         * @param columnName
1233
 
         *            DOCUMENT ME!
1234
 
         * @param scale
1235
 
         *            DOCUMENT ME!
1236
 
         * 
1237
 
         * @return DOCUMENT ME!
1238
 
         * 
1239
 
         * @throws SQLException
1240
 
         *             DOCUMENT ME!
1241
 
         * 
1242
 
         * @deprecated
1243
 
         */
1244
 
        public BigDecimal getBigDecimal(String columnName, int scale)
1245
 
                        throws SQLException {
1246
 
                return getBigDecimal(findColumn(columnName), scale);
1247
 
        }
1248
 
 
1249
 
        private final BigDecimal getBigDecimalFromString(String stringVal,
1250
 
                        int columnIndex, int scale) throws SQLException {
1251
 
                BigDecimal bdVal;
1252
 
 
1253
 
                if (stringVal != null) {
1254
 
                        if (stringVal.length() == 0) {
1255
 
                                bdVal = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck());
1256
 
 
1257
 
                                try {
1258
 
                                        return bdVal.setScale(scale);
1259
 
                                } catch (ArithmeticException ex) {
1260
 
                                        try {
1261
 
                                                return bdVal.setScale(scale, BigDecimal.ROUND_HALF_UP);
1262
 
                                        } catch (ArithmeticException arEx) {
1263
 
                                                throw new SQLException(Messages
1264
 
                                                                .getString("ResultSet.Bad_format_for_BigDecimal",
1265
 
                                                                                new Object[] { stringVal,
1266
 
                                                                                                new Integer(columnIndex) }),
1267
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1268
 
                                        }
1269
 
                                }
1270
 
                        }
1271
 
 
1272
 
                        try {
1273
 
                                try {
1274
 
                                        return new BigDecimal(stringVal).setScale(scale);
1275
 
                                } catch (ArithmeticException ex) {
1276
 
                                        try {
1277
 
                                                return new BigDecimal(stringVal).setScale(scale,
1278
 
                                                                BigDecimal.ROUND_HALF_UP);
1279
 
                                        } catch (ArithmeticException arEx) {
1280
 
                                                throw new SQLException(Messages
1281
 
                                                                .getString("ResultSet.Bad_format_for_BigDecimal",
1282
 
                                                                                new Object[] { stringVal,
1283
 
                                                                                                new Integer(columnIndex) }),
1284
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1285
 
                                        }
1286
 
                                }
1287
 
                        } catch (NumberFormatException ex) {
1288
 
                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
1289
 
                                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
1290
 
 
1291
 
                                        try {
1292
 
                                                return new BigDecimal(valueAsLong).setScale(scale);
1293
 
                                        } catch (ArithmeticException arEx1) {
1294
 
                                                try {
1295
 
                                                        return new BigDecimal(valueAsLong).setScale(scale,
1296
 
                                                                        BigDecimal.ROUND_HALF_UP);
1297
 
                                                } catch (ArithmeticException arEx2) {
1298
 
                                                        throw new SQLException(Messages
1299
 
                                                                        .getString("ResultSet.Bad_format_for_BigDecimal",
1300
 
                                                                                        new Object[] { stringVal,
1301
 
                                                                                                        new Integer(columnIndex) }),
1302
 
                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1303
 
                                                }
1304
 
                                        }
1305
 
                                }
1306
 
                                
1307
 
                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TINY &&
1308
 
                                                this.connection.getTinyInt1isBit() && this.fields[columnIndex - 1].getLength() == 1) {
1309
 
                                        return new BigDecimal(stringVal.equalsIgnoreCase("true") ? 1 : 0).setScale(scale);
1310
 
                                }
1311
 
                                
1312
 
                                throw new SQLException(Messages
1313
 
                                                .getString("ResultSet.Bad_format_for_BigDecimal",
1314
 
                                                                new Object[] { stringVal,
1315
 
                                                                                new Integer(columnIndex) }),
1316
 
                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1317
 
                        }
1318
 
                }
1319
 
                
1320
 
                return null;
1321
 
        }
1322
 
 
1323
 
        /**
1324
 
         * A column value can also be retrieved as a binary stream. This method is
1325
 
         * suitable for retrieving LONGVARBINARY values.
1326
 
         * 
1327
 
         * @param columnIndex
1328
 
         *            the first column is 1, the second is 2...
1329
 
         * 
1330
 
         * @return a Java InputStream that delivers the database column value as a
1331
 
         *         stream of bytes. If the value is SQL NULL, then the result is
1332
 
         *         null
1333
 
         * 
1334
 
         * @exception SQLException
1335
 
         *                if a database access error occurs
1336
 
         * 
1337
 
         * @see getAsciiStream
1338
 
         * @see getUnicodeStream
1339
 
         */
1340
 
        public InputStream getBinaryStream(int columnIndex) throws SQLException {
1341
 
                checkRowPos();
1342
 
 
1343
 
                if (!this.isBinaryEncoded) {
1344
 
                        byte[] b = getBytes(columnIndex);
1345
 
 
1346
 
                        if (b != null) {
1347
 
                                return new ByteArrayInputStream(b);
1348
 
                        }
1349
 
 
1350
 
                        return null;
1351
 
                }
1352
 
 
1353
 
                return getNativeBinaryStream(columnIndex);
1354
 
        }
1355
 
 
1356
 
        /**
1357
 
         * DOCUMENT ME!
1358
 
         * 
1359
 
         * @param columnName
1360
 
         *            DOCUMENT ME!
1361
 
         * 
1362
 
         * @return DOCUMENT ME!
1363
 
         * 
1364
 
         * @throws SQLException
1365
 
         *             DOCUMENT ME!
1366
 
         */
1367
 
        public InputStream getBinaryStream(String columnName) throws SQLException {
1368
 
                return getBinaryStream(findColumn(columnName));
1369
 
        }
1370
 
 
1371
 
        /**
1372
 
         * JDBC 2.0 Get a BLOB column.
1373
 
         * 
1374
 
         * @param columnIndex
1375
 
         *            the first column is 1, the second is 2, ...
1376
 
         * 
1377
 
         * @return an object representing a BLOB
1378
 
         * 
1379
 
         * @throws SQLException
1380
 
         *             if an error occurs.
1381
 
         */
1382
 
        public java.sql.Blob getBlob(int columnIndex) throws SQLException {
1383
 
                if (!this.isBinaryEncoded) {
1384
 
                        checkRowPos();
1385
 
 
1386
 
                        checkColumnBounds(columnIndex);
1387
 
                        
1388
 
                        if ((columnIndex < 1) || (columnIndex > this.fields.length)) {
1389
 
                                throw SQLError.createSQLException(Messages.getString(
1390
 
                                                "ResultSet.Column_Index_out_of_range", new Object[] {
1391
 
                                                                new Integer(columnIndex),
1392
 
                                                                new Integer(this.fields.length) }),
1393
 
                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1394
 
                        }
1395
 
 
1396
 
                        try {
1397
 
                                if (this.thisRow[columnIndex - 1] == null) {
1398
 
                                        this.wasNullFlag = true;
1399
 
                                } else {
1400
 
                                        this.wasNullFlag = false;
1401
 
                                }
1402
 
                        } catch (NullPointerException ex) {
1403
 
                                this.wasNullFlag = true;
1404
 
                        }
1405
 
 
1406
 
                        if (this.wasNullFlag) {
1407
 
                                return null;
1408
 
                        }
1409
 
 
1410
 
                        if (!this.connection.getEmulateLocators()) {
1411
 
                                return new Blob((byte[]) this.thisRow[columnIndex - 1]);
1412
 
                        }
1413
 
 
1414
 
                        return new BlobFromLocator(this, columnIndex);
1415
 
                }
1416
 
 
1417
 
                return getNativeBlob(columnIndex);
1418
 
        }
1419
 
 
1420
 
        /**
1421
 
         * JDBC 2.0 Get a BLOB column.
1422
 
         * 
1423
 
         * @param colName
1424
 
         *            the column name
1425
 
         * 
1426
 
         * @return an object representing a BLOB
1427
 
         * 
1428
 
         * @throws SQLException
1429
 
         *             if an error occurs.
1430
 
         */
1431
 
        public java.sql.Blob getBlob(String colName) throws SQLException {
1432
 
                return getBlob(findColumn(colName));
1433
 
        }
1434
 
 
1435
 
        /**
1436
 
         * Get the value of a column in the current row as a Java boolean
1437
 
         * 
1438
 
         * @param columnIndex
1439
 
         *            the first column is 1, the second is 2...
1440
 
         * 
1441
 
         * @return the column value, false for SQL NULL
1442
 
         * 
1443
 
         * @exception SQLException
1444
 
         *                if a database access error occurs
1445
 
         */
1446
 
        public boolean getBoolean(int columnIndex) throws SQLException {
1447
 
                
1448
 
                checkColumnBounds(columnIndex);
1449
 
 
1450
 
                //
1451
 
                // MySQL 5.0 and newer have an actual BIT type,
1452
 
                // so we need to check for that here...
1453
 
                //
1454
 
 
1455
 
                int columnIndexMinusOne = columnIndex - 1;
1456
 
 
1457
 
                Field field = this.fields[columnIndexMinusOne];
1458
 
 
1459
 
                if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
1460
 
                        return byteArrayToBoolean(columnIndexMinusOne);
1461
 
                }
1462
 
 
1463
 
                this.wasNullFlag = false;
1464
 
                
1465
 
                int sqlType = field.getSQLType();
1466
 
                
1467
 
                switch (sqlType) {
1468
 
                case Types.BIT:
1469
 
                case Types.BOOLEAN:
1470
 
                case Types.TINYINT:
1471
 
                case Types.SMALLINT:
1472
 
                case Types.INTEGER:
1473
 
                case Types.BIGINT:
1474
 
                case Types.DECIMAL:
1475
 
                case Types.NUMERIC:
1476
 
                case Types.REAL:
1477
 
                case Types.FLOAT:
1478
 
                case Types.DOUBLE:
1479
 
                        long boolVal = getLong(columnIndex, false);
1480
 
 
1481
 
                        return (boolVal == -1 || boolVal > 0);
1482
 
                default:
1483
 
                        if (this.connection.getPedantic()) {
1484
 
                                // Table B-6 from JDBC spec
1485
 
                                switch (sqlType) {
1486
 
                                case Types.BINARY:
1487
 
                                case Types.VARBINARY:
1488
 
                                case Types.LONGVARBINARY:
1489
 
                                case Types.DATE:
1490
 
                                case Types.TIME:
1491
 
                                case Types.TIMESTAMP:
1492
 
                                case Types.CLOB:
1493
 
                                case Types.BLOB:
1494
 
                                case Types.ARRAY:
1495
 
                                case Types.REF:
1496
 
                                case Types.DATALINK:
1497
 
                                case Types.STRUCT:
1498
 
                                case Types.JAVA_OBJECT:
1499
 
                                        throw SQLError.createSQLException("Required type conversion not allowed",
1500
 
                                                        SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
1501
 
                                }
1502
 
                        }
1503
 
                
1504
 
                        if (sqlType == Types.BINARY ||
1505
 
                                sqlType == Types.VARBINARY ||
1506
 
                                sqlType == Types.LONGVARBINARY ||
1507
 
                                sqlType == Types.BLOB) {
1508
 
                                return byteArrayToBoolean(columnIndexMinusOne);
1509
 
                        }
1510
 
                        
1511
 
                        if (this.useUsageAdvisor) {
1512
 
                                issueConversionViaParsingWarning("getBoolean()", columnIndex,
1513
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
1514
 
                                                new int[] {
1515
 
                                                                MysqlDefs.FIELD_TYPE_BIT,
1516
 
                                                                MysqlDefs.FIELD_TYPE_DOUBLE,
1517
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
1518
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
1519
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
1520
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
1521
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
1522
 
                        }
1523
 
                
1524
 
                        String stringVal = getString(columnIndex);
1525
 
 
1526
 
                        return getBooleanFromString(stringVal, columnIndex);
1527
 
                }
1528
 
        }
1529
 
 
1530
 
        private boolean byteArrayToBoolean(int columnIndexMinusOne) {
1531
 
                if (this.thisRow[columnIndexMinusOne] == null) {
1532
 
                        this.wasNullFlag = true;
1533
 
 
1534
 
                        return false;
1535
 
                }
1536
 
 
1537
 
                this.wasNullFlag = false;
1538
 
 
1539
 
                if (((byte[]) this.thisRow[columnIndexMinusOne]).length == 0) {
1540
 
                        return false;
1541
 
                }
1542
 
 
1543
 
                byte boolVal = ((byte[]) this.thisRow[columnIndexMinusOne])[0];
1544
 
 
1545
 
                return (boolVal == -1 || boolVal > 0);
1546
 
        }
1547
 
 
1548
 
        /**
1549
 
         * DOCUMENT ME!
1550
 
         * 
1551
 
         * @param columnName
1552
 
         *            DOCUMENT ME!
1553
 
         * 
1554
 
         * @return DOCUMENT ME!
1555
 
         * 
1556
 
         * @throws SQLException
1557
 
         *             DOCUMENT ME!
1558
 
         */
1559
 
        public boolean getBoolean(String columnName) throws SQLException {
1560
 
                return getBoolean(findColumn(columnName));
1561
 
        }
1562
 
 
1563
 
        private final boolean getBooleanFromString(String stringVal, int columnIndex)
1564
 
                        throws SQLException {
1565
 
                if ((stringVal != null) && (stringVal.length() > 0)) {
1566
 
                        int c = Character.toLowerCase(stringVal.charAt(0));
1567
 
 
1568
 
                        return ((c == 't') || (c == 'y') || (c == '1') || stringVal
1569
 
                                        .equals("-1"));
1570
 
                }
1571
 
 
1572
 
                return false;
1573
 
        }
1574
 
 
1575
 
        /**
1576
 
         * Get the value of a column in the current row as a Java byte.
1577
 
         * 
1578
 
         * @param columnIndex
1579
 
         *            the first column is 1, the second is 2,...
1580
 
         * 
1581
 
         * @return the column value; 0 if SQL NULL
1582
 
         * 
1583
 
         * @exception SQLException
1584
 
         *                if a database access error occurs
1585
 
         */
1586
 
        public byte getByte(int columnIndex) throws SQLException {
1587
 
                if (!this.isBinaryEncoded) {
1588
 
                        String stringVal = getString(columnIndex);
1589
 
 
1590
 
                        if (this.wasNullFlag || (stringVal == null)) {
1591
 
                                return 0;
1592
 
                        }
1593
 
 
1594
 
                        return getByteFromString(stringVal, columnIndex);
1595
 
                }
1596
 
 
1597
 
                return getNativeByte(columnIndex);
1598
 
        }
1599
 
 
1600
 
        /**
1601
 
         * DOCUMENT ME!
1602
 
         * 
1603
 
         * @param columnName
1604
 
         *            DOCUMENT ME!
1605
 
         * 
1606
 
         * @return DOCUMENT ME!
1607
 
         * 
1608
 
         * @throws SQLException
1609
 
         *             DOCUMENT ME!
1610
 
         */
1611
 
        public byte getByte(String columnName) throws SQLException {
1612
 
                return getByte(findColumn(columnName));
1613
 
        }
1614
 
 
1615
 
        private final byte getByteFromString(String stringVal, int columnIndex)
1616
 
                        throws SQLException {
1617
 
 
1618
 
                if (stringVal != null && stringVal.length() == 0) {
1619
 
                        return (byte) convertToZeroWithEmptyCheck();
1620
 
                }
1621
 
 
1622
 
                //
1623
 
                // JDK-6 doesn't like trailing whitespace
1624
 
                //
1625
 
                // Note this isn't a performance issue, other
1626
 
                // than the iteration over the string, as String.trim()
1627
 
                // will return a new string only if whitespace is present
1628
 
                //
1629
 
                
1630
 
                stringVal = stringVal.trim(); 
1631
 
                
1632
 
                try {
1633
 
                        int decimalIndex = stringVal.indexOf(".");
1634
 
 
1635
 
                        
1636
 
                        if (decimalIndex != -1) {
1637
 
                                double valueAsDouble = Double.parseDouble(stringVal);
1638
 
 
1639
 
                                if (this.connection.getJdbcCompliantTruncationForReads()) {
1640
 
                                        if (valueAsDouble < Byte.MIN_VALUE
1641
 
                                                        || valueAsDouble > Byte.MAX_VALUE) {
1642
 
                                                throwRangeException(stringVal, columnIndex,
1643
 
                                                                Types.TINYINT);
1644
 
                                        }
1645
 
                                }
1646
 
 
1647
 
                                return (byte) valueAsDouble;
1648
 
                        }
1649
 
 
1650
 
                        long valueAsLong = Long.parseLong(stringVal);
1651
 
 
1652
 
                        if (this.connection.getJdbcCompliantTruncationForReads()) {
1653
 
                                if (valueAsLong < Byte.MIN_VALUE
1654
 
                                                || valueAsLong > Byte.MAX_VALUE) {
1655
 
                                        throwRangeException(String.valueOf(valueAsLong),
1656
 
                                                        columnIndex, Types.TINYINT);
1657
 
                                }
1658
 
                        }
1659
 
 
1660
 
                        return (byte) valueAsLong;
1661
 
                } catch (NumberFormatException NFE) {
1662
 
                        throw SQLError.createSQLException(
1663
 
                                        Messages.getString("ResultSet.Value____173")
1664
 
                                                        + stringVal //$NON-NLS-1$
1665
 
                                                        + Messages
1666
 
                                                                        .getString("ResultSet.___is_out_of_range_[-127,127]_174"),
1667
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1668
 
                }
1669
 
        }
1670
 
 
1671
 
        /**
1672
 
         * Get the value of a column in the current row as a Java byte array.
1673
 
         * 
1674
 
         * <p>
1675
 
         * <b>Be warned</b> If the blob is huge, then you may run out of memory.
1676
 
         * </p>
1677
 
         * 
1678
 
         * @param columnIndex
1679
 
         *            the first column is 1, the second is 2, ...
1680
 
         * 
1681
 
         * @return the column value; if the value is SQL NULL, the result is null
1682
 
         * 
1683
 
         * @exception SQLException
1684
 
         *                if a database access error occurs
1685
 
         */
1686
 
        public byte[] getBytes(int columnIndex) throws SQLException {
1687
 
                return getBytes(columnIndex, false);
1688
 
        }
1689
 
 
1690
 
        protected byte[] getBytes(int columnIndex, boolean noConversion)
1691
 
                        throws SQLException {
1692
 
                if (!this.isBinaryEncoded) {
1693
 
                        checkRowPos();
1694
 
                        
1695
 
                        checkColumnBounds(columnIndex);
1696
 
                        
1697
 
                        try {
1698
 
                                if (this.thisRow[columnIndex - 1] == null) {
1699
 
                                        this.wasNullFlag = true;
1700
 
                                } else {
1701
 
                                        this.wasNullFlag = false;
1702
 
                                }
1703
 
                        } catch (NullPointerException E) {
1704
 
                                this.wasNullFlag = true;
1705
 
                        } catch (ArrayIndexOutOfBoundsException aioobEx) {
1706
 
                                throw SQLError.createSQLException(Messages.getString(
1707
 
                                                "ResultSet.Column_Index_out_of_range", new Object[] {
1708
 
                                                                new Integer(columnIndex),
1709
 
                                                                new Integer(this.fields.length) }),
1710
 
                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1711
 
                        }
1712
 
 
1713
 
                        if (this.wasNullFlag) {
1714
 
                                return null;
1715
 
                        }
1716
 
 
1717
 
                        return (byte[]) this.thisRow[columnIndex - 1];
1718
 
                }
1719
 
 
1720
 
                return getNativeBytes(columnIndex, noConversion);
1721
 
        }
1722
 
 
1723
 
        /**
1724
 
         * DOCUMENT ME!
1725
 
         * 
1726
 
         * @param columnName
1727
 
         *            DOCUMENT ME!
1728
 
         * 
1729
 
         * @return DOCUMENT ME!
1730
 
         * 
1731
 
         * @throws SQLException
1732
 
         *             DOCUMENT ME!
1733
 
         */
1734
 
        public byte[] getBytes(String columnName) throws SQLException {
1735
 
                return getBytes(findColumn(columnName));
1736
 
        }
1737
 
 
1738
 
        private final byte[] getBytesFromString(String stringVal, int columnIndex)
1739
 
                        throws SQLException {
1740
 
                if (stringVal != null) {
1741
 
                        return StringUtils.getBytes(stringVal, this.connection
1742
 
                                        .getEncoding(), this.connection
1743
 
                                        .getServerCharacterEncoding(), this.connection
1744
 
                                        .parserKnowsUnicode(),
1745
 
                                        this.connection);
1746
 
                }
1747
 
 
1748
 
                return null;
1749
 
        }
1750
 
 
1751
 
        /**
1752
 
         * Optimization to only use one calendar per-session, or calculate it for
1753
 
         * each call, depending on user configuration
1754
 
         */
1755
 
        private Calendar getCalendarInstanceForSessionOrNew() {
1756
 
                if (this.connection != null) {
1757
 
                        return this.connection.getCalendarInstanceForSessionOrNew();
1758
 
                } else {
1759
 
                        // punt, no connection around
1760
 
                        return new GregorianCalendar();
1761
 
                }
1762
 
        }
1763
 
 
1764
 
        /**
1765
 
         * JDBC 2.0
1766
 
         * 
1767
 
         * <p>
1768
 
         * Get the value of a column in the current row as a java.io.Reader.
1769
 
         * </p>
1770
 
         * 
1771
 
         * @param columnIndex
1772
 
         *            the column to get the value from
1773
 
         * 
1774
 
         * @return the value in the column as a java.io.Reader.
1775
 
         * 
1776
 
         * @throws SQLException
1777
 
         *             if an error occurs
1778
 
         */
1779
 
        public java.io.Reader getCharacterStream(int columnIndex)
1780
 
                        throws SQLException {
1781
 
                if (!this.isBinaryEncoded) {
1782
 
                        String asString = getStringForClob(columnIndex);
1783
 
 
1784
 
                        if (asString == null) {
1785
 
                                return null;
1786
 
                        }
1787
 
 
1788
 
                        return new StringReader(asString);
1789
 
                }
1790
 
 
1791
 
                return getNativeCharacterStream(columnIndex);
1792
 
        }
1793
 
 
1794
 
        /**
1795
 
         * JDBC 2.0
1796
 
         * 
1797
 
         * <p>
1798
 
         * Get the value of a column in the current row as a java.io.Reader.
1799
 
         * </p>
1800
 
         * 
1801
 
         * @param columnName
1802
 
         *            the column name to retrieve the value from
1803
 
         * 
1804
 
         * @return the value as a java.io.Reader
1805
 
         * 
1806
 
         * @throws SQLException
1807
 
         *             if an error occurs
1808
 
         */
1809
 
        public java.io.Reader getCharacterStream(String columnName)
1810
 
                        throws SQLException {
1811
 
                return getCharacterStream(findColumn(columnName));
1812
 
        }
1813
 
 
1814
 
        private final java.io.Reader getCharacterStreamFromString(String stringVal,
1815
 
                        int columnIndex) throws SQLException {
1816
 
                if (stringVal != null) {
1817
 
                        return new StringReader(stringVal);
1818
 
                }
1819
 
 
1820
 
                return null;
1821
 
        }
1822
 
 
1823
 
        /**
1824
 
         * JDBC 2.0 Get a CLOB column.
1825
 
         * 
1826
 
         * @param i
1827
 
         *            the first column is 1, the second is 2, ...
1828
 
         * 
1829
 
         * @return an object representing a CLOB
1830
 
         * 
1831
 
         * @throws SQLException
1832
 
         *             if an error occurs
1833
 
         */
1834
 
        public java.sql.Clob getClob(int i) throws SQLException {
1835
 
                if (!this.isBinaryEncoded) {
1836
 
                        String asString = getStringForClob(i);
1837
 
                        
1838
 
                        if (asString == null) {
1839
 
                                return null;
1840
 
                        }
1841
 
 
1842
 
                        return new com.mysql.jdbc.Clob(asString);
1843
 
                }
1844
 
 
1845
 
                return getNativeClob(i);
1846
 
        }
1847
 
 
1848
 
        /**
1849
 
         * JDBC 2.0 Get a CLOB column.
1850
 
         * 
1851
 
         * @param colName
1852
 
         *            the column name
1853
 
         * 
1854
 
         * @return an object representing a CLOB
1855
 
         * 
1856
 
         * @throws SQLException
1857
 
         *             if an error occurs
1858
 
         */
1859
 
        public java.sql.Clob getClob(String colName) throws SQLException {
1860
 
                return getClob(findColumn(colName));
1861
 
        }
1862
 
 
1863
 
        private final java.sql.Clob getClobFromString(String stringVal,
1864
 
                        int columnIndex) throws SQLException {
1865
 
                return new com.mysql.jdbc.Clob(stringVal);
1866
 
        }
1867
 
 
1868
 
        /**
1869
 
         * JDBC 2.0 Return the concurrency of this result set. The concurrency used
1870
 
         * is determined by the statement that created the result set.
1871
 
         * 
1872
 
         * @return the concurrency type, CONCUR_READ_ONLY, etc.
1873
 
         * 
1874
 
         * @throws SQLException
1875
 
         *             if a database-access error occurs
1876
 
         */
1877
 
        public int getConcurrency() throws SQLException {
1878
 
                return (CONCUR_READ_ONLY);
1879
 
        }
1880
 
 
1881
 
        /**
1882
 
         * Get the name of the SQL cursor used by this ResultSet
1883
 
         * 
1884
 
         * <p>
1885
 
         * In SQL, a result table is retrieved though a cursor that is named. The
1886
 
         * current row of a result can be updated or deleted using a positioned
1887
 
         * update/delete statement that references the cursor name.
1888
 
         * </p>
1889
 
         * 
1890
 
         * <p>
1891
 
         * JDBC supports this SQL feature by providing the name of the SQL cursor
1892
 
         * used by a ResultSet. The current row of a ResulSet is also the current
1893
 
         * row of this SQL cursor.
1894
 
         * </p>
1895
 
         * 
1896
 
         * <p>
1897
 
         * <B>Note:</B> If positioned update is not supported, a SQLException is
1898
 
         * thrown.
1899
 
         * </p>
1900
 
         * 
1901
 
         * @return the ResultSet's SQL cursor name.
1902
 
         * 
1903
 
         * @exception SQLException
1904
 
         *                if a database access error occurs
1905
 
         */
1906
 
        public String getCursorName() throws SQLException {
1907
 
                throw SQLError.createSQLException(Messages
1908
 
                                .getString("ResultSet.Positioned_Update_not_supported"),
1909
 
                                SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); //$NON-NLS-1$
1910
 
        }
1911
 
 
1912
 
        /**
1913
 
         * Get the value of a column in the current row as a java.sql.Date object
1914
 
         * 
1915
 
         * @param columnIndex
1916
 
         *            the first column is 1, the second is 2...
1917
 
         * 
1918
 
         * @return the column value; null if SQL NULL
1919
 
         * 
1920
 
         * @exception java.sql.SQLException
1921
 
         *                if a database access error occurs
1922
 
         */
1923
 
        public java.sql.Date getDate(int columnIndex) throws java.sql.SQLException {
1924
 
                return getDate(columnIndex, null);
1925
 
        }
1926
 
 
1927
 
        /**
1928
 
         * JDBC 2.0 Get the value of a column in the current row as a java.sql.Date
1929
 
         * object. Use the calendar to construct an appropriate millisecond value
1930
 
         * for the Date, if the underlying database doesn't store timezone
1931
 
         * information.
1932
 
         * 
1933
 
         * @param columnIndex
1934
 
         *            the first column is 1, the second is 2, ...
1935
 
         * @param cal
1936
 
         *            the calendar to use in constructing the date
1937
 
         * 
1938
 
         * @return the column value; if the value is SQL NULL, the result is null
1939
 
         * 
1940
 
         * @exception SQLException
1941
 
         *                if a database-access error occurs.
1942
 
         */
1943
 
        public java.sql.Date getDate(int columnIndex, Calendar cal)
1944
 
                        throws SQLException {
1945
 
                if (this.isBinaryEncoded) {
1946
 
                        return getNativeDate(columnIndex, (cal != null) ? cal.getTimeZone()
1947
 
                                        : this.getDefaultTimeZone());
1948
 
                }
1949
 
 
1950
 
                String stringVal = getStringInternal(columnIndex, false);
1951
 
 
1952
 
                if (stringVal == null) {
1953
 
                        return null;
1954
 
                }
1955
 
 
1956
 
                return getDateFromString(stringVal, columnIndex);
1957
 
        }
1958
 
 
1959
 
        /**
1960
 
         * DOCUMENT ME!
1961
 
         * 
1962
 
         * @param columnName
1963
 
         *            DOCUMENT ME!
1964
 
         * 
1965
 
         * @return DOCUMENT ME!
1966
 
         * 
1967
 
         * @throws java.sql.SQLException
1968
 
         *             DOCUMENT ME!
1969
 
         */
1970
 
        public java.sql.Date getDate(String columnName)
1971
 
                        throws java.sql.SQLException {
1972
 
                return getDate(findColumn(columnName));
1973
 
        }
1974
 
 
1975
 
        /**
1976
 
         * Get the value of a column in the current row as a java.sql.Date object.
1977
 
         * Use the calendar to construct an appropriate millisecond value for the
1978
 
         * Date, if the underlying database doesn't store timezone information.
1979
 
         * 
1980
 
         * @param columnName
1981
 
         *            is the SQL name of the column
1982
 
         * @param cal
1983
 
         *            the calendar to use in constructing the date
1984
 
         * 
1985
 
         * @return the column value; if the value is SQL NULL, the result is null
1986
 
         * 
1987
 
         * @exception SQLException
1988
 
         *                if a database-access error occurs.
1989
 
         */
1990
 
        public java.sql.Date getDate(String columnName, Calendar cal)
1991
 
                        throws SQLException {
1992
 
                return getDate(findColumn(columnName), cal);
1993
 
        }
1994
 
 
1995
 
        private final java.sql.Date getDateFromString(String stringVal,
1996
 
                        int columnIndex) throws SQLException {
1997
 
                int year = 0;
1998
 
                int month = 0;
1999
 
                int day = 0;
2000
 
 
2001
 
                try {
2002
 
                        this.wasNullFlag = false;
2003
 
 
2004
 
                        if (stringVal == null) {
2005
 
                                this.wasNullFlag = true;
2006
 
 
2007
 
                                return null;
2008
 
                        }
2009
 
                        
2010
 
                        //
2011
 
                        // JDK-6 doesn't like trailing whitespace
2012
 
                        //
2013
 
                        // Note this isn't a performance issue, other
2014
 
                        // than the iteration over the string, as String.trim()
2015
 
                        // will return a new string only if whitespace is present
2016
 
                        //
2017
 
                        
2018
 
                        stringVal = stringVal.trim();
2019
 
 
2020
 
                        if (stringVal.equals("0") || stringVal.equals("0000-00-00")
2021
 
                                        || stringVal.equals("0000-00-00 00:00:00")
2022
 
                                        || stringVal.equals("00000000000000")
2023
 
                                        || stringVal.equals("0")) {
2024
 
 
2025
 
                                if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
2026
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
2027
 
                                        this.wasNullFlag = true;
2028
 
 
2029
 
                                        return null;
2030
 
                                } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
2031
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
2032
 
                                        throw SQLError.createSQLException("Value '" + stringVal
2033
 
                                                        + "' can not be represented as java.sql.Date",
2034
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2035
 
                                }
2036
 
 
2037
 
                                // We're left with the case of 'round' to a date Java _can_
2038
 
                                // represent, which is '0001-01-01'.
2039
 
                                return fastDateCreate(null, 1, 1, 1);
2040
 
 
2041
 
                        } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
2042
 
                                // Convert from TIMESTAMP
2043
 
                                switch (stringVal.length()) {
2044
 
                                case 21:
2045
 
                                case 19: { // java.sql.Timestamp format
2046
 
                                        year = Integer.parseInt(stringVal.substring(0, 4));
2047
 
                                        month = Integer.parseInt(stringVal.substring(5, 7));
2048
 
                                        day = Integer.parseInt(stringVal.substring(8, 10));
2049
 
 
2050
 
                                        return fastDateCreate(null, year, month, day);
2051
 
                                }
2052
 
 
2053
 
                                case 14:
2054
 
                                case 8: {
2055
 
                                        year = Integer.parseInt(stringVal.substring(0, 4));
2056
 
                                        month = Integer.parseInt(stringVal.substring(4, 6));
2057
 
                                        day = Integer.parseInt(stringVal.substring(6, 8));
2058
 
 
2059
 
                                        return fastDateCreate(null, year, month, day);
2060
 
                                }
2061
 
 
2062
 
                                case 12:
2063
 
                                case 10:
2064
 
                                case 6: {
2065
 
                                        year = Integer.parseInt(stringVal.substring(0, 2));
2066
 
 
2067
 
                                        if (year <= 69) {
2068
 
                                                year = year + 100;
2069
 
                                        }
2070
 
 
2071
 
                                        month = Integer.parseInt(stringVal.substring(2, 4));
2072
 
                                        day = Integer.parseInt(stringVal.substring(4, 6));
2073
 
 
2074
 
                                        return fastDateCreate(null, year + 1900, month, day);
2075
 
                                }
2076
 
 
2077
 
                                case 4: {
2078
 
                                        year = Integer.parseInt(stringVal.substring(0, 4));
2079
 
 
2080
 
                                        if (year <= 69) {
2081
 
                                                year = year + 100;
2082
 
                                        }
2083
 
 
2084
 
                                        month = Integer.parseInt(stringVal.substring(2, 4));
2085
 
 
2086
 
                                        return fastDateCreate(null, year + 1900, month, 1);
2087
 
                                }
2088
 
 
2089
 
                                case 2: {
2090
 
                                        year = Integer.parseInt(stringVal.substring(0, 2));
2091
 
 
2092
 
                                        if (year <= 69) {
2093
 
                                                year = year + 100;
2094
 
                                        }
2095
 
 
2096
 
                                        return fastDateCreate(null, year + 1900, 1, 1);
2097
 
                                }
2098
 
 
2099
 
                                default:
2100
 
                                        throw SQLError.createSQLException(Messages.getString(
2101
 
                                                        "ResultSet.Bad_format_for_Date", new Object[] {
2102
 
                                                                        stringVal, new Integer(columnIndex) }),
2103
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2104
 
                                } /* endswitch */
2105
 
                        } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
2106
 
 
2107
 
                                if (stringVal.length() == 2 || stringVal.length() == 1) {
2108
 
                                        year = Integer.parseInt(stringVal);
2109
 
 
2110
 
                                        if (year <= 69) {
2111
 
                                                year = year + 100;
2112
 
                                        }
2113
 
 
2114
 
                                        year += 1900;
2115
 
                                } else {
2116
 
                                        year = Integer.parseInt(stringVal.substring(0, 4));
2117
 
                                }
2118
 
 
2119
 
                                return fastDateCreate(null, year, 1, 1);
2120
 
                        } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
2121
 
                                return fastDateCreate(null, 1970, 1, 1); // Return EPOCH
2122
 
                        } else {
2123
 
                                if (stringVal.length() < 10) {
2124
 
                                        throw SQLError.createSQLException(Messages.getString(
2125
 
                                                        "ResultSet.Bad_format_for_Date", new Object[] {
2126
 
                                                                        stringVal, new Integer(columnIndex) }),
2127
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2128
 
                                }
2129
 
 
2130
 
                                if (stringVal.length() != 18) {
2131
 
                                        year = Integer.parseInt(stringVal.substring(0, 4));
2132
 
                                        month = Integer.parseInt(stringVal.substring(5, 7));
2133
 
                                        day = Integer.parseInt(stringVal.substring(8, 10));
2134
 
                                } else {
2135
 
                                        // JDK-1.3 timestamp format, not real easy to parse positionally :p
2136
 
                                        StringTokenizer st = new StringTokenizer(stringVal, "- ");
2137
 
                                        
2138
 
                                        year = Integer.parseInt(st.nextToken());
2139
 
                                        month = Integer.parseInt(st.nextToken());
2140
 
                                        day = Integer.parseInt(st.nextToken());
2141
 
                                }
2142
 
                        }
2143
 
 
2144
 
                        return fastDateCreate(null, year, month, day);
2145
 
                } catch (SQLException sqlEx) {
2146
 
                        throw sqlEx; // don't re-wrap
2147
 
                } catch (Exception e) {
2148
 
                        throw SQLError.createSQLException(Messages.getString(
2149
 
                                        "ResultSet.Bad_format_for_Date", new Object[] { stringVal,
2150
 
                                                        new Integer(columnIndex) }),
2151
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2152
 
                }
2153
 
        }
2154
 
 
2155
 
        private TimeZone getDefaultTimeZone() {
2156
 
                // Worst case we allocate this twice and the other gets GC'd,
2157
 
                // however prevents deadlock
2158
 
                if (this.defaultTimeZone == null) {
2159
 
                        this.defaultTimeZone = TimeZone.getDefault();
2160
 
                }
2161
 
 
2162
 
                return this.defaultTimeZone;
2163
 
        }
2164
 
 
2165
 
        /**
2166
 
         * Get the value of a column in the current row as a Java double.
2167
 
         * 
2168
 
         * @param columnIndex
2169
 
         *            the first column is 1, the second is 2,...
2170
 
         * 
2171
 
         * @return the column value; 0 if SQL NULL
2172
 
         * 
2173
 
         * @exception SQLException
2174
 
         *                if a database access error occurs
2175
 
         */
2176
 
        public double getDouble(int columnIndex) throws SQLException {
2177
 
                if (!this.isBinaryEncoded) {
2178
 
                        return getDoubleInternal(columnIndex);
2179
 
                }
2180
 
 
2181
 
                return getNativeDouble(columnIndex);
2182
 
        }
2183
 
 
2184
 
        /**
2185
 
         * DOCUMENT ME!
2186
 
         * 
2187
 
         * @param columnName
2188
 
         *            DOCUMENT ME!
2189
 
         * 
2190
 
         * @return DOCUMENT ME!
2191
 
         * 
2192
 
         * @throws SQLException
2193
 
         *             DOCUMENT ME!
2194
 
         */
2195
 
        public double getDouble(String columnName) throws SQLException {
2196
 
                return getDouble(findColumn(columnName));
2197
 
        }
2198
 
 
2199
 
        private final double getDoubleFromString(String stringVal, int columnIndex)
2200
 
                        throws SQLException {
2201
 
                return getDoubleInternal(stringVal, columnIndex);
2202
 
        }
2203
 
 
2204
 
        /**
2205
 
         * Converts a string representation of a number to a double. Need a faster
2206
 
         * way to do this.
2207
 
         * 
2208
 
         * @param colIndex
2209
 
         *            the 1-based index of the column to retrieve a double from.
2210
 
         * 
2211
 
         * @return the double value represented by the string in buf
2212
 
         * 
2213
 
         * @throws SQLException
2214
 
         *             if an error occurs
2215
 
         */
2216
 
        protected double getDoubleInternal(int colIndex) throws SQLException {
2217
 
                return getDoubleInternal(getString(colIndex), colIndex);
2218
 
        }
2219
 
 
2220
 
        /**
2221
 
         * Converts a string representation of a number to a double. Need a faster
2222
 
         * way to do this.
2223
 
         * 
2224
 
         * @param stringVal
2225
 
         *            the double as a String
2226
 
         * @param colIndex
2227
 
         *            the 1-based index of the column to retrieve a double from.
2228
 
         * 
2229
 
         * @return the double value represented by the string in buf
2230
 
         * 
2231
 
         * @throws SQLException
2232
 
         *             if an error occurs
2233
 
         */
2234
 
        protected double getDoubleInternal(String stringVal, int colIndex)
2235
 
                        throws SQLException {
2236
 
                try {
2237
 
                        if ((stringVal == null)) {
2238
 
                                return 0;
2239
 
                        }
2240
 
 
2241
 
                        if (stringVal.length() == 0) {
2242
 
                                return convertToZeroWithEmptyCheck();
2243
 
                        }
2244
 
 
2245
 
                        double d = Double.parseDouble(stringVal);
2246
 
 
2247
 
                        if (this.useStrictFloatingPoint) {
2248
 
                                // Fix endpoint rounding precision loss in MySQL server
2249
 
                                if (d == 2.147483648E9) {
2250
 
                                        // Fix Odd end-point rounding on MySQL
2251
 
                                        d = 2.147483647E9;
2252
 
                                } else if (d == 1.0000000036275E-15) {
2253
 
                                        // Fix odd end-point rounding on MySQL
2254
 
                                        d = 1.0E-15;
2255
 
                                } else if (d == 9.999999869911E14) {
2256
 
                                        d = 9.99999999999999E14;
2257
 
                                } else if (d == 1.4012984643248E-45) {
2258
 
                                        d = 1.4E-45;
2259
 
                                } else if (d == 1.4013E-45) {
2260
 
                                        d = 1.4E-45;
2261
 
                                } else if (d == 3.4028234663853E37) {
2262
 
                                        d = 3.4028235E37;
2263
 
                                } else if (d == -2.14748E9) {
2264
 
                                        d = -2.147483648E9;
2265
 
                                } else if (d == 3.40282E37) {
2266
 
                                        d = 3.4028235E37;
2267
 
                                }
2268
 
                        }
2269
 
 
2270
 
                        return d;
2271
 
                } catch (NumberFormatException e) {
2272
 
                        if (this.fields[colIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2273
 
                                long valueAsLong = getNumericRepresentationOfSQLBitType(colIndex);
2274
 
                                
2275
 
                                return valueAsLong;
2276
 
                        }
2277
 
                        
2278
 
                        throw SQLError.createSQLException(Messages.getString(
2279
 
                                        "ResultSet.Bad_format_for_number", new Object[] {
2280
 
                                                        stringVal, new Integer(colIndex) }),
2281
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2282
 
                }
2283
 
        }
2284
 
 
2285
 
        /**
2286
 
         * JDBC 2.0 Returns the fetch direction for this result set.
2287
 
         * 
2288
 
         * @return the fetch direction for this result set.
2289
 
         * 
2290
 
         * @exception SQLException
2291
 
         *                if a database-access error occurs
2292
 
         */
2293
 
        public int getFetchDirection() throws SQLException {
2294
 
                return this.fetchDirection;
2295
 
        }
2296
 
 
2297
 
        /**
2298
 
         * JDBC 2.0 Return the fetch size for this result set.
2299
 
         * 
2300
 
         * @return the fetch size for this result set.
2301
 
         * 
2302
 
         * @exception SQLException
2303
 
         *                if a database-access error occurs
2304
 
         */
2305
 
        public int getFetchSize() throws SQLException {
2306
 
                return this.fetchSize;
2307
 
        }
2308
 
 
2309
 
        /**
2310
 
         * Returns the first character of the query that this result set was created
2311
 
         * from.
2312
 
         * 
2313
 
         * @return the first character of the query...uppercased
2314
 
         */
2315
 
        protected char getFirstCharOfQuery() {
2316
 
                return this.firstCharOfQuery;
2317
 
        }
2318
 
 
2319
 
        /**
2320
 
         * Get the value of a column in the current row as a Java float.
2321
 
         * 
2322
 
         * @param columnIndex
2323
 
         *            the first column is 1, the second is 2,...
2324
 
         * 
2325
 
         * @return the column value; 0 if SQL NULL
2326
 
         * 
2327
 
         * @exception SQLException
2328
 
         *                if a database access error occurs
2329
 
         */
2330
 
        public float getFloat(int columnIndex) throws SQLException {
2331
 
                if (!this.isBinaryEncoded) {
2332
 
                        String val = null;
2333
 
 
2334
 
                        val = getString(columnIndex);
2335
 
 
2336
 
                        return getFloatFromString(val, columnIndex);
2337
 
                }
2338
 
 
2339
 
                return getNativeFloat(columnIndex);
2340
 
        }
2341
 
 
2342
 
        /**
2343
 
         * DOCUMENT ME!
2344
 
         * 
2345
 
         * @param columnName
2346
 
         *            DOCUMENT ME!
2347
 
         * 
2348
 
         * @return DOCUMENT ME!
2349
 
         * 
2350
 
         * @throws SQLException
2351
 
         *             DOCUMENT ME!
2352
 
         */
2353
 
        public float getFloat(String columnName) throws SQLException {
2354
 
                return getFloat(findColumn(columnName));
2355
 
        }
2356
 
 
2357
 
        private final float getFloatFromString(String val, int columnIndex)
2358
 
                        throws SQLException {
2359
 
                try {
2360
 
                        if ((val != null)) {
2361
 
                                if (val.length() == 0) {
2362
 
                                        return convertToZeroWithEmptyCheck();
2363
 
                                }
2364
 
 
2365
 
                                float f = Float.parseFloat(val);
2366
 
 
2367
 
                                if (this.connection.getJdbcCompliantTruncationForReads()) {
2368
 
                                        if (f == Float.MIN_VALUE || f == Float.MAX_VALUE) {
2369
 
                                                double valAsDouble = Double.parseDouble(val);
2370
 
 
2371
 
                                                // Straight comparison is not reliable when at
2372
 
                                                // absolute endpoints of Float.MIN_VALUE or 
2373
 
                                                // Float.MAX_VALUE, so use epsillons with DOUBLEs
2374
 
 
2375
 
                                    if ((valAsDouble < Float.MIN_VALUE - MIN_DIFF_PREC)
2376
 
                                        || (valAsDouble > Float.MAX_VALUE - MAX_DIFF_PREC)) {
2377
 
                                      throwRangeException(String.valueOf(valAsDouble), columnIndex,
2378
 
                                          Types.FLOAT);
2379
 
                                    }
2380
 
                                        }
2381
 
                                }
2382
 
 
2383
 
                                return f;
2384
 
                        }
2385
 
 
2386
 
                        return 0; // for NULL
2387
 
                } catch (NumberFormatException nfe) {
2388
 
                        try {
2389
 
                                Double valueAsDouble = new Double(val);
2390
 
                                float valueAsFloat = valueAsDouble.floatValue();
2391
 
                                
2392
 
                                if (this.connection.getJdbcCompliantTruncationForReads()) {
2393
 
 
2394
 
                                        if (this.connection.getJdbcCompliantTruncationForReads() && 
2395
 
                                                        valueAsFloat == Float.NEGATIVE_INFINITY ||
2396
 
                                                        valueAsFloat == Float.POSITIVE_INFINITY) {
2397
 
                                                throwRangeException(valueAsDouble.toString(), 
2398
 
                                                                columnIndex, Types.FLOAT);
2399
 
                                        }
2400
 
                                }
2401
 
 
2402
 
                                return valueAsFloat;
2403
 
                        } catch (NumberFormatException newNfe) {
2404
 
                                ; // ignore, it's not a number
2405
 
                        }
2406
 
 
2407
 
                        throw SQLError.createSQLException(
2408
 
                                        Messages
2409
 
                                                        .getString("ResultSet.Invalid_value_for_getFloat()_-____200")
2410
 
                                                        + val //$NON-NLS-1$
2411
 
                                                        + Messages.getString("ResultSet.___in_column__201")
2412
 
                                                        + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2413
 
                }
2414
 
        }
2415
 
 
2416
 
        /**
2417
 
         * Get the value of a column in the current row as a Java int.
2418
 
         * 
2419
 
         * @param columnIndex
2420
 
         *            the first column is 1, the second is 2,...
2421
 
         * 
2422
 
         * @return the column value; 0 if SQL NULL
2423
 
         * 
2424
 
         * @exception SQLException
2425
 
         *                if a database access error occurs
2426
 
         */
2427
 
        public int getInt(int columnIndex) throws SQLException {
2428
 
                checkRowPos();
2429
 
                
2430
 
                if (!this.isBinaryEncoded) {
2431
 
                        if (this.connection.getUseFastIntParsing()) {
2432
 
                                checkColumnBounds(columnIndex);
2433
 
                                
2434
 
                                try {
2435
 
                                        if (this.thisRow[columnIndex - 1] == null) {
2436
 
                                                this.wasNullFlag = true;
2437
 
                                        } else {
2438
 
                                                this.wasNullFlag = false;
2439
 
                                        }
2440
 
                                } catch (NullPointerException E) {
2441
 
                                        this.wasNullFlag = true;
2442
 
                                } catch (ArrayIndexOutOfBoundsException aioobEx) {
2443
 
                                        throw SQLError.createSQLException(Messages.getString(
2444
 
                                                        "ResultSet.Column_Index_out_of_range",
2445
 
                                                        new Object[] { new Integer(columnIndex),
2446
 
                                                                        new Integer(this.fields.length) }),
2447
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2448
 
                                }
2449
 
 
2450
 
                                if (this.wasNullFlag) {
2451
 
                                        return 0;
2452
 
                                }
2453
 
 
2454
 
                                byte[] intAsBytes = (byte[]) this.thisRow[columnIndex - 1];
2455
 
 
2456
 
                                if (intAsBytes.length == 0) {
2457
 
                                        return convertToZeroWithEmptyCheck();
2458
 
                                }
2459
 
 
2460
 
                                boolean needsFullParse = false;
2461
 
 
2462
 
                                for (int i = 0; i < intAsBytes.length; i++) {
2463
 
                                        if (((char) intAsBytes[i] == 'e')
2464
 
                                                        || ((char) intAsBytes[i] == 'E')) {
2465
 
                                                needsFullParse = true;
2466
 
 
2467
 
                                                break;
2468
 
                                        }
2469
 
                                }
2470
 
 
2471
 
                                if (!needsFullParse) {
2472
 
                                        try {
2473
 
                                                return parseIntWithOverflowCheck(columnIndex,
2474
 
                                                                intAsBytes, null);
2475
 
                                        } catch (NumberFormatException nfe) {
2476
 
                                                try {
2477
 
 
2478
 
                                                        return parseIntAsDouble(columnIndex, new String(
2479
 
                                                                        intAsBytes));
2480
 
                                                } catch (NumberFormatException newNfe) {
2481
 
                                                        ; // ignore, it's not a number
2482
 
                                                }
2483
 
 
2484
 
                                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2485
 
                                                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
2486
 
                                                        
2487
 
                                                        if (this.connection.getJdbcCompliantTruncationForReads() &&
2488
 
                                                                        (valueAsLong < Integer.MIN_VALUE
2489
 
                                                                                        || valueAsLong > Integer.MAX_VALUE)) {
2490
 
                                                                throwRangeException(String.valueOf(valueAsLong), columnIndex,
2491
 
                                                                                Types.INTEGER);
2492
 
                                                        }
2493
 
                                                        
2494
 
                                                        return (int)valueAsLong;
2495
 
                                                }
2496
 
                                                
2497
 
                                                throw SQLError.createSQLException(
2498
 
                                                                Messages
2499
 
                                                                                .getString("ResultSet.Invalid_value_for_getInt()_-____74")
2500
 
                                                                                + new String(intAsBytes) //$NON-NLS-1$
2501
 
                                                                                + "'",
2502
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2503
 
                                        }
2504
 
                                }
2505
 
                        }
2506
 
 
2507
 
                        String val = null;
2508
 
 
2509
 
                        try {
2510
 
                                val = getString(columnIndex);
2511
 
 
2512
 
                                if ((val != null)) {
2513
 
                                        if (val.length() == 0) {
2514
 
                                                return convertToZeroWithEmptyCheck();
2515
 
                                        }
2516
 
 
2517
 
                                        if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
2518
 
                                                        && (val.indexOf(".") == -1)) {
2519
 
                                                return Integer.parseInt(val);
2520
 
                                        }
2521
 
 
2522
 
                                        // Convert floating point
2523
 
                                        return parseIntAsDouble(columnIndex, val);
2524
 
                                }
2525
 
 
2526
 
                                return 0;
2527
 
                        } catch (NumberFormatException nfe) {
2528
 
                                try {
2529
 
                                        return parseIntAsDouble(columnIndex, val);
2530
 
                                } catch (NumberFormatException newNfe) {
2531
 
                                        ; // ignore, it's not a number
2532
 
                                }
2533
 
 
2534
 
                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2535
 
                                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
2536
 
                                        
2537
 
                                        if (this.connection.getJdbcCompliantTruncationForReads() &&
2538
 
                                                        (valueAsLong < Integer.MIN_VALUE
2539
 
                                                                        || valueAsLong > Integer.MAX_VALUE)) {
2540
 
                                                throwRangeException(String.valueOf(valueAsLong), columnIndex,
2541
 
                                                                Types.INTEGER);
2542
 
                                        }
2543
 
                                        
2544
 
                                        return (int)valueAsLong;
2545
 
                                }
2546
 
                                
2547
 
                                throw SQLError.createSQLException(
2548
 
                                                Messages
2549
 
                                                                .getString("ResultSet.Invalid_value_for_getInt()_-____74")
2550
 
                                                                + val //$NON-NLS-1$
2551
 
                                                                + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2552
 
                        }
2553
 
                }
2554
 
 
2555
 
                return getNativeInt(columnIndex);
2556
 
        }
2557
 
 
2558
 
        /**
2559
 
         * DOCUMENT ME!
2560
 
         * 
2561
 
         * @param columnName
2562
 
         *            DOCUMENT ME!
2563
 
         * 
2564
 
         * @return DOCUMENT ME!
2565
 
         * 
2566
 
         * @throws SQLException
2567
 
         *             DOCUMENT ME!
2568
 
         */
2569
 
        public int getInt(String columnName) throws SQLException {
2570
 
                return getInt(findColumn(columnName));
2571
 
        }
2572
 
 
2573
 
        private final int getIntFromString(String val, int columnIndex)
2574
 
                        throws SQLException {
2575
 
                try {
2576
 
                        if ((val != null)) {
2577
 
 
2578
 
                                if (val.length() == 0) {
2579
 
                                        return convertToZeroWithEmptyCheck();
2580
 
                                }
2581
 
 
2582
 
                                if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
2583
 
                                                && (val.indexOf(".") == -1)) {
2584
 
                                        //
2585
 
                                        // JDK-6 doesn't like trailing whitespace
2586
 
                                        //
2587
 
                                        // Note this isn't a performance issue, other
2588
 
                                        // than the iteration over the string, as String.trim()
2589
 
                                        // will return a new string only if whitespace is present
2590
 
                                        //
2591
 
                                        
2592
 
                                        val = val.trim(); 
2593
 
                                        
2594
 
                                        int valueAsInt = Integer.parseInt(val);
2595
 
 
2596
 
                                        if (this.connection.getJdbcCompliantTruncationForReads()) {
2597
 
                                                if (valueAsInt == Integer.MIN_VALUE
2598
 
                                                                || valueAsInt == Integer.MAX_VALUE) {
2599
 
                                                        long valueAsLong = Long.parseLong(val);
2600
 
 
2601
 
                                                        if (valueAsLong < Integer.MIN_VALUE
2602
 
                                                                        || valueAsLong > Integer.MAX_VALUE) {
2603
 
                                                                throwRangeException(
2604
 
                                                                                String.valueOf(valueAsLong),
2605
 
                                                                                columnIndex, Types.INTEGER);
2606
 
                                                        }
2607
 
                                                }
2608
 
                                        }
2609
 
 
2610
 
                                        return valueAsInt;
2611
 
                                }
2612
 
 
2613
 
                                // Convert floating point
2614
 
 
2615
 
                                double valueAsDouble = Double.parseDouble(val);
2616
 
 
2617
 
                                if (this.connection.getJdbcCompliantTruncationForReads()) {
2618
 
                                        if (valueAsDouble < Integer.MIN_VALUE
2619
 
                                                        || valueAsDouble > Integer.MAX_VALUE) {
2620
 
                                                throwRangeException(String.valueOf(valueAsDouble),
2621
 
                                                                columnIndex, Types.INTEGER);
2622
 
                                        }
2623
 
                                }
2624
 
 
2625
 
                                return (int) valueAsDouble;
2626
 
                        }
2627
 
 
2628
 
                        return 0; // for NULL
2629
 
                } catch (NumberFormatException nfe) {
2630
 
                        try {
2631
 
                                double valueAsDouble = Double.parseDouble(val);
2632
 
 
2633
 
                                if (this.connection.getJdbcCompliantTruncationForReads()) {
2634
 
                                        if (valueAsDouble < Integer.MIN_VALUE
2635
 
                                                        || valueAsDouble > Integer.MAX_VALUE) {
2636
 
                                                throwRangeException(String.valueOf(valueAsDouble),
2637
 
                                                                columnIndex, Types.INTEGER);
2638
 
                                        }
2639
 
                                }
2640
 
 
2641
 
                                return (int) valueAsDouble;
2642
 
                        } catch (NumberFormatException newNfe) {
2643
 
                                ; // ignore, it's not a number
2644
 
                        }
2645
 
 
2646
 
                        throw SQLError.createSQLException(Messages
2647
 
                                        .getString("ResultSet.Invalid_value_for_getInt()_-____206")
2648
 
                                        + val //$NON-NLS-1$
2649
 
                                        + Messages.getString("ResultSet.___in_column__207")
2650
 
                                        + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2651
 
                }
2652
 
        }
2653
 
 
2654
 
        /**
2655
 
         * Get the value of a column in the current row as a Java long.
2656
 
         * 
2657
 
         * @param columnIndex
2658
 
         *            the first column is 1, the second is 2,...
2659
 
         * 
2660
 
         * @return the column value; 0 if SQL NULL
2661
 
         * 
2662
 
         * @exception SQLException
2663
 
         *                if a database access error occurs
2664
 
         */
2665
 
        public long getLong(int columnIndex) throws SQLException {
2666
 
                return getLong(columnIndex, true);
2667
 
        }
2668
 
        
2669
 
        private long getLong(int columnIndex, boolean overflowCheck) throws SQLException {
2670
 
                if (!this.isBinaryEncoded) {
2671
 
                        checkRowPos();
2672
 
                        
2673
 
                        if (this.connection.getUseFastIntParsing()) {
2674
 
                        
2675
 
                                checkColumnBounds(columnIndex);
2676
 
                                
2677
 
                                try {
2678
 
                                        if (this.thisRow[columnIndex - 1] == null) {
2679
 
                                                this.wasNullFlag = true;
2680
 
                                        } else {
2681
 
                                                this.wasNullFlag = false;
2682
 
                                        }
2683
 
                                } catch (NullPointerException E) {
2684
 
                                        this.wasNullFlag = true;
2685
 
                                } catch (ArrayIndexOutOfBoundsException aioobEx) {
2686
 
                                        throw SQLError.createSQLException(Messages.getString(
2687
 
                                                        "ResultSet.Column_Index_out_of_range",
2688
 
                                                        new Object[] { new Integer(columnIndex),
2689
 
                                                                        new Integer(this.fields.length) }),
2690
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2691
 
                                }
2692
 
 
2693
 
                                if (this.wasNullFlag) {
2694
 
                                        return 0;
2695
 
                                }
2696
 
 
2697
 
                                byte[] longAsBytes = (byte[]) this.thisRow[columnIndex - 1];
2698
 
 
2699
 
                                if (longAsBytes.length == 0) {
2700
 
                                        return convertToZeroWithEmptyCheck();
2701
 
                                }
2702
 
 
2703
 
                                boolean needsFullParse = false;
2704
 
 
2705
 
                                for (int i = 0; i < longAsBytes.length; i++) {
2706
 
                                        if (((char) longAsBytes[i] == 'e')
2707
 
                                                        || ((char) longAsBytes[i] == 'E')) {
2708
 
                                                needsFullParse = true;
2709
 
 
2710
 
                                                break;
2711
 
                                        }
2712
 
                                }
2713
 
 
2714
 
                                if (!needsFullParse) {
2715
 
                                        try {
2716
 
                                                return parseLongWithOverflowCheck(columnIndex,
2717
 
                                                                longAsBytes, null, overflowCheck);
2718
 
                                        } catch (NumberFormatException nfe) {
2719
 
                                                try {
2720
 
                                                        // To do: Warn of over/underflow???
2721
 
                                                        return parseLongAsDouble(columnIndex, new String(
2722
 
                                                                        longAsBytes));
2723
 
                                                } catch (NumberFormatException newNfe) {
2724
 
                                                        // ; // ignore, it's not a number
2725
 
                                                }
2726
 
 
2727
 
                                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2728
 
                                                        return getNumericRepresentationOfSQLBitType(columnIndex);
2729
 
                                                }
2730
 
                                                
2731
 
                                                throw SQLError.createSQLException(
2732
 
                                                                Messages
2733
 
                                                                                .getString("ResultSet.Invalid_value_for_getLong()_-____79")
2734
 
                                                                                + new String(longAsBytes) //$NON-NLS-1$
2735
 
                                                                                + "'",
2736
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2737
 
                                        }
2738
 
                                }
2739
 
                        }
2740
 
 
2741
 
                        String val = null;
2742
 
 
2743
 
                        try {
2744
 
                                val = getString(columnIndex);
2745
 
 
2746
 
                                if ((val != null)) {
2747
 
                                        if (val.length() == 0) {
2748
 
                                                return convertToZeroWithEmptyCheck();
2749
 
                                        }
2750
 
 
2751
 
                                        if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) {
2752
 
                                                return parseLongWithOverflowCheck(columnIndex, null,
2753
 
                                                                val, overflowCheck);
2754
 
                                        }
2755
 
 
2756
 
                                        // Convert floating point
2757
 
                                        return parseLongAsDouble(columnIndex, val);
2758
 
                                }
2759
 
 
2760
 
                                return 0; // for NULL
2761
 
                        } catch (NumberFormatException nfe) {
2762
 
                                try {
2763
 
                                        return parseLongAsDouble(columnIndex, val);
2764
 
                                } catch (NumberFormatException newNfe) {
2765
 
                                        // ; // ignore, it's not a number
2766
 
                                }
2767
 
 
2768
 
                                throw SQLError.createSQLException(
2769
 
                                                Messages
2770
 
                                                                .getString("ResultSet.Invalid_value_for_getLong()_-____79")
2771
 
                                                                + val //$NON-NLS-1$
2772
 
                                                                + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2773
 
                        }
2774
 
                }
2775
 
 
2776
 
                return getNativeLong(columnIndex, overflowCheck, true);
2777
 
        }
2778
 
 
2779
 
        /**
2780
 
         * DOCUMENT ME!
2781
 
         * 
2782
 
         * @param columnName
2783
 
         *            DOCUMENT ME!
2784
 
         * 
2785
 
         * @return DOCUMENT ME!
2786
 
         * 
2787
 
         * @throws SQLException
2788
 
         *             DOCUMENT ME!
2789
 
         */
2790
 
        public long getLong(String columnName) throws SQLException {
2791
 
                return getLong(findColumn(columnName));
2792
 
        }
2793
 
 
2794
 
        private final long getLongFromString(String val, int columnIndex)
2795
 
                        throws SQLException {
2796
 
                try {
2797
 
                        if ((val != null)) {
2798
 
 
2799
 
                                if (val.length() == 0) {
2800
 
                                        return convertToZeroWithEmptyCheck();
2801
 
                                }
2802
 
 
2803
 
                                if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) {
2804
 
                                        return parseLongWithOverflowCheck(columnIndex, null, val, true);
2805
 
                                }
2806
 
 
2807
 
                                // Convert floating point
2808
 
                                return parseLongAsDouble(columnIndex, val);
2809
 
                        }
2810
 
 
2811
 
                        return 0; // for NULL
2812
 
                } catch (NumberFormatException nfe) {
2813
 
                        try {
2814
 
                                // To do: Warn of over/underflow???
2815
 
                                return parseLongAsDouble(columnIndex, val);
2816
 
                        } catch (NumberFormatException newNfe) {
2817
 
                                ; // ignore, it's not a number
2818
 
                        }
2819
 
 
2820
 
                        throw SQLError.createSQLException(
2821
 
                                        Messages
2822
 
                                                        .getString("ResultSet.Invalid_value_for_getLong()_-____211")
2823
 
                                                        + val //$NON-NLS-1$
2824
 
                                                        + Messages.getString("ResultSet.___in_column__212")
2825
 
                                                        + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2826
 
                }
2827
 
        }
2828
 
 
2829
 
        /**
2830
 
         * The numbers, types and properties of a ResultSet's columns are provided
2831
 
         * by the getMetaData method
2832
 
         * 
2833
 
         * @return a description of the ResultSet's columns
2834
 
         * 
2835
 
         * @exception SQLException
2836
 
         *                if a database access error occurs
2837
 
         */
2838
 
        public java.sql.ResultSetMetaData getMetaData() throws SQLException {
2839
 
                checkClosed();
2840
 
 
2841
 
                return new com.mysql.jdbc.ResultSetMetaData(this.fields, 
2842
 
                                this.connection.getUseOldAliasMetadataBehavior());
2843
 
        }
2844
 
 
2845
 
        /**
2846
 
         * JDBC 2.0 Get an array column.
2847
 
         * 
2848
 
         * @param i
2849
 
         *            the first column is 1, the second is 2, ...
2850
 
         * 
2851
 
         * @return an object representing an SQL array
2852
 
         * 
2853
 
         * @throws SQLException
2854
 
         *             if a database error occurs
2855
 
         * @throws NotImplemented
2856
 
         *             DOCUMENT ME!
2857
 
         */
2858
 
        protected java.sql.Array getNativeArray(int i) throws SQLException {
2859
 
                throw new NotImplemented();
2860
 
        }
2861
 
 
2862
 
        /**
2863
 
         * A column value can be retrieved as a stream of ASCII characters and then
2864
 
         * read in chunks from the stream. This method is particulary suitable for
2865
 
         * retrieving large LONGVARCHAR values. The JDBC driver will do any
2866
 
         * necessary conversion from the database format into ASCII.
2867
 
         * 
2868
 
         * <p>
2869
 
         * <B>Note:</B> All the data in the returned stream must be read prior to
2870
 
         * getting the value of any other column. The next call to a get method
2871
 
         * implicitly closes the stream. Also, a stream may return 0 for available()
2872
 
         * whether there is data available or not.
2873
 
         * </p>
2874
 
         * 
2875
 
         * @param columnIndex
2876
 
         *            the first column is 1, the second is 2, ...
2877
 
         * 
2878
 
         * @return a Java InputStream that delivers the database column value as a
2879
 
         *         stream of one byte ASCII characters. If the value is SQL NULL
2880
 
         *         then the result is null
2881
 
         * 
2882
 
         * @exception SQLException
2883
 
         *                if a database access error occurs
2884
 
         * 
2885
 
         * @see getBinaryStream
2886
 
         */
2887
 
        protected InputStream getNativeAsciiStream(int columnIndex)
2888
 
                        throws SQLException {
2889
 
                checkRowPos();
2890
 
 
2891
 
                return getNativeBinaryStream(columnIndex);
2892
 
        }
2893
 
 
2894
 
        /**
2895
 
         * JDBC 2.0 Get the value of a column in the current row as a
2896
 
         * java.math.BigDecimal object.
2897
 
         * 
2898
 
         * @param columnIndex
2899
 
         *            the first column is 1, the second is 2, ...
2900
 
         * 
2901
 
         * @return the column value (full precision); if the value is SQL NULL, the
2902
 
         *         result is null
2903
 
         * 
2904
 
         * @exception SQLException
2905
 
         *                if a database-access error occurs.
2906
 
         */
2907
 
        protected BigDecimal getNativeBigDecimal(int columnIndex)
2908
 
                        throws SQLException {
2909
 
 
2910
 
                checkColumnBounds(columnIndex);
2911
 
                
2912
 
                int scale = this.fields[columnIndex - 1].getDecimals();
2913
 
                
2914
 
                return getNativeBigDecimal(columnIndex, scale);
2915
 
        }
2916
 
 
2917
 
        /**
2918
 
         * Get the value of a column in the current row as a java.math.BigDecimal
2919
 
         * object
2920
 
         * 
2921
 
         * @param columnIndex
2922
 
         *            the first column is 1, the second is 2...
2923
 
         * @param scale
2924
 
         *            the number of digits to the right of the decimal
2925
 
         * 
2926
 
         * @return the column value; if the value is SQL NULL, null
2927
 
         * 
2928
 
         * @exception SQLException
2929
 
         *                if a database access error occurs
2930
 
         */
2931
 
        protected BigDecimal getNativeBigDecimal(int columnIndex, int scale)
2932
 
                        throws SQLException {
2933
 
                checkColumnBounds(columnIndex);
2934
 
                
2935
 
                String stringVal = null;
2936
 
                
2937
 
                Field f = this.fields[columnIndex - 1];
2938
 
                
2939
 
                if (this.thisRow[columnIndex - 1] == null) {
2940
 
                        this.wasNullFlag = true;
2941
 
                        
2942
 
                        return null;
2943
 
                }
2944
 
                
2945
 
                this.wasNullFlag = false;
2946
 
                
2947
 
                switch (f.getSQLType()) {
2948
 
                        case Types.DECIMAL:
2949
 
                        case Types.NUMERIC:
2950
 
                                stringVal = StringUtils
2951
 
                                                .toAsciiString((byte[]) this.thisRow[columnIndex - 1]);
2952
 
                                break;
2953
 
                        default:
2954
 
                                stringVal = getNativeString(columnIndex);
2955
 
                }
2956
 
 
2957
 
                return getBigDecimalFromString(stringVal, columnIndex, scale);
2958
 
        }
2959
 
 
2960
 
        /**
2961
 
         * A column value can also be retrieved as a binary strea. This method is
2962
 
         * suitable for retrieving LONGVARBINARY values.
2963
 
         * 
2964
 
         * @param columnIndex
2965
 
         *            the first column is 1, the second is 2...
2966
 
         * 
2967
 
         * @return a Java InputStream that delivers the database column value as a
2968
 
         *         stream of bytes. If the value is SQL NULL, then the result is
2969
 
         *         null
2970
 
         * 
2971
 
         * @exception SQLException
2972
 
         *                if a database access error occurs
2973
 
         * 
2974
 
         * @see getAsciiStream
2975
 
         * @see getUnicodeStream
2976
 
         */
2977
 
        protected InputStream getNativeBinaryStream(int columnIndex)
2978
 
                        throws SQLException {
2979
 
                checkRowPos();
2980
 
 
2981
 
                byte[] b = getNativeBytes(columnIndex, false);
2982
 
 
2983
 
                if (b != null) {
2984
 
                        return new ByteArrayInputStream(b);
2985
 
                }
2986
 
 
2987
 
                return null;
2988
 
        }
2989
 
 
2990
 
        /**
2991
 
         * JDBC 2.0 Get a BLOB column.
2992
 
         * 
2993
 
         * @param columnIndex
2994
 
         *            the first column is 1, the second is 2, ...
2995
 
         * 
2996
 
         * @return an object representing a BLOB
2997
 
         * 
2998
 
         * @throws SQLException
2999
 
         *             if an error occurs.
3000
 
         */
3001
 
        protected java.sql.Blob getNativeBlob(int columnIndex) throws SQLException {
3002
 
                checkRowPos();
3003
 
 
3004
 
                checkColumnBounds(columnIndex);
3005
 
 
3006
 
                try {
3007
 
                        if (this.thisRow[columnIndex - 1] == null) {
3008
 
                                this.wasNullFlag = true;
3009
 
                        } else {
3010
 
                                this.wasNullFlag = false;
3011
 
                        }
3012
 
                } catch (NullPointerException ex) {
3013
 
                        this.wasNullFlag = true;
3014
 
                }
3015
 
 
3016
 
                if (this.wasNullFlag) {
3017
 
                        return null;
3018
 
                }
3019
 
 
3020
 
                int mysqlType = this.fields[columnIndex - 1].getMysqlType();
3021
 
 
3022
 
                byte[] dataAsBytes = null;
3023
 
 
3024
 
                switch (mysqlType) {
3025
 
                case MysqlDefs.FIELD_TYPE_TINY_BLOB:
3026
 
                case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
3027
 
                case MysqlDefs.FIELD_TYPE_LONG_BLOB:
3028
 
                case MysqlDefs.FIELD_TYPE_BLOB:
3029
 
                        dataAsBytes = (byte[]) this.thisRow[columnIndex - 1];
3030
 
 
3031
 
                default:
3032
 
                        dataAsBytes = getNativeBytes(columnIndex, false);
3033
 
                }
3034
 
 
3035
 
                if (!this.connection.getEmulateLocators()) {
3036
 
                        return new Blob(dataAsBytes);
3037
 
                }
3038
 
 
3039
 
                return new BlobFromLocator(this, columnIndex);
3040
 
        }
3041
 
 
3042
 
        /**
3043
 
         * Get the value of a column in the current row as a Java byte.
3044
 
         * 
3045
 
         * @param columnIndex
3046
 
         *            the first column is 1, the second is 2,...
3047
 
         * 
3048
 
         * @return the column value; 0 if SQL NULL
3049
 
         * 
3050
 
         * @exception SQLException
3051
 
         *                if a database access error occurs
3052
 
         */
3053
 
        protected byte getNativeByte(int columnIndex) throws SQLException {
3054
 
                return getNativeByte(columnIndex, true);
3055
 
        }
3056
 
        
3057
 
        protected byte getNativeByte(int columnIndex, boolean overflowCheck) throws SQLException {
3058
 
                checkRowPos();
3059
 
 
3060
 
                checkColumnBounds(columnIndex);
3061
 
 
3062
 
                if (this.thisRow[columnIndex - 1] == null) {
3063
 
                        this.wasNullFlag = true;
3064
 
 
3065
 
                        return 0;
3066
 
                }
3067
 
 
3068
 
                try {
3069
 
                        if (this.thisRow[columnIndex - 1] == null) {
3070
 
                                this.wasNullFlag = true;
3071
 
                        } else {
3072
 
                                this.wasNullFlag = false;
3073
 
                        }
3074
 
                } catch (NullPointerException E) {
3075
 
                        this.wasNullFlag = true;
3076
 
                }
3077
 
 
3078
 
                if (this.wasNullFlag) {
3079
 
                        return 0;
3080
 
                }
3081
 
 
3082
 
                columnIndex--;
3083
 
 
3084
 
                Field field = this.fields[columnIndex];
3085
 
 
3086
 
                switch (field.getMysqlType()) {
3087
 
                case MysqlDefs.FIELD_TYPE_BIT:
3088
 
                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3089
 
                        
3090
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3091
 
                                        (valueAsLong < Byte.MIN_VALUE
3092
 
                                                        || valueAsLong > Byte.MAX_VALUE)) {
3093
 
                                throwRangeException(String.valueOf(valueAsLong), columnIndex + 1,
3094
 
                                                Types.TINYINT);
3095
 
                        }
3096
 
                        
3097
 
                        return (byte)valueAsLong;
3098
 
                case MysqlDefs.FIELD_TYPE_TINY:
3099
 
                        byte valueAsByte = ((byte[]) this.thisRow[columnIndex])[0];
3100
 
                        
3101
 
                        if (!field.isUnsigned()) {
3102
 
                                return valueAsByte;
3103
 
                        }
3104
 
 
3105
 
                        short valueAsShort = (valueAsByte >= 0) ? 
3106
 
                                        valueAsByte : (short)(valueAsByte + (short)256);
3107
 
                        
3108
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3109
 
                                if (valueAsShort > Byte.MAX_VALUE) {
3110
 
                                        throwRangeException(String.valueOf(valueAsShort),
3111
 
                                                        columnIndex + 1, Types.TINYINT);
3112
 
                                }
3113
 
                        }
3114
 
                        
3115
 
                        return (byte)valueAsShort;
3116
 
 
3117
 
                case MysqlDefs.FIELD_TYPE_SHORT:
3118
 
                case MysqlDefs.FIELD_TYPE_YEAR:
3119
 
                        valueAsShort = getNativeShort(columnIndex + 1);
3120
 
 
3121
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3122
 
                                if (valueAsShort < Byte.MIN_VALUE
3123
 
                                                || valueAsShort > Byte.MAX_VALUE) {
3124
 
                                        throwRangeException(String.valueOf(valueAsShort),
3125
 
                                                        columnIndex + 1, Types.TINYINT);
3126
 
                                }
3127
 
                        }
3128
 
 
3129
 
                        return (byte) valueAsShort;
3130
 
                case MysqlDefs.FIELD_TYPE_INT24:
3131
 
                case MysqlDefs.FIELD_TYPE_LONG:
3132
 
                        int valueAsInt = getNativeInt(columnIndex + 1, false);
3133
 
 
3134
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3135
 
                                if (valueAsInt < Byte.MIN_VALUE || valueAsInt > Byte.MAX_VALUE) {
3136
 
                                        throwRangeException(String.valueOf(valueAsInt),
3137
 
                                                        columnIndex + 1, Types.TINYINT);
3138
 
                                }
3139
 
                        }
3140
 
 
3141
 
                        return (byte) valueAsInt;
3142
 
 
3143
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
3144
 
                        float valueAsFloat = getNativeFloat(columnIndex + 1);
3145
 
 
3146
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3147
 
                                if (valueAsFloat < Byte.MIN_VALUE
3148
 
                                                || valueAsFloat > Byte.MAX_VALUE) {
3149
 
 
3150
 
                                        throwRangeException(String.valueOf(valueAsFloat),
3151
 
                                                        columnIndex + 1, Types.TINYINT);
3152
 
                                }
3153
 
                        }
3154
 
 
3155
 
                        return (byte) valueAsFloat;
3156
 
 
3157
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
3158
 
                        double valueAsDouble = getNativeDouble(columnIndex + 1);
3159
 
 
3160
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3161
 
                                if (valueAsDouble < Byte.MIN_VALUE
3162
 
                                                || valueAsDouble > Byte.MAX_VALUE) {
3163
 
                                        throwRangeException(String.valueOf(valueAsDouble),
3164
 
                                                        columnIndex + 1, Types.TINYINT);
3165
 
                                }
3166
 
                        }
3167
 
 
3168
 
                        return (byte) valueAsDouble;
3169
 
 
3170
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
3171
 
                        valueAsLong = getNativeLong(columnIndex + 1, false, true);
3172
 
 
3173
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3174
 
                                if (valueAsLong < Byte.MIN_VALUE
3175
 
                                                || valueAsLong > Byte.MAX_VALUE) {
3176
 
                                        throwRangeException(String.valueOf(valueAsLong),
3177
 
                                                        columnIndex + 1, Types.TINYINT);
3178
 
                                }
3179
 
                        }
3180
 
 
3181
 
                        return (byte) valueAsLong;
3182
 
 
3183
 
                default:
3184
 
                        if (this.useUsageAdvisor) {
3185
 
                                issueConversionViaParsingWarning("getByte()", columnIndex,
3186
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
3187
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
3188
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
3189
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
3190
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
3191
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
3192
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
3193
 
                        }
3194
 
 
3195
 
                        return getByteFromString(getNativeString(columnIndex + 1),
3196
 
                                        columnIndex + 1);
3197
 
                }
3198
 
        }
3199
 
 
3200
 
        /**
3201
 
         * Get the value of a column in the current row as a Java byte array.
3202
 
         * 
3203
 
         * <p>
3204
 
         * <b>Be warned</b> If the blob is huge, then you may run out of memory.
3205
 
         * </p>
3206
 
         * 
3207
 
         * @param columnIndex
3208
 
         *            the first column is 1, the second is 2, ...
3209
 
         * 
3210
 
         * @return the column value; if the value is SQL NULL, the result is null
3211
 
         * 
3212
 
         * @exception SQLException
3213
 
         *                if a database access error occurs
3214
 
         */
3215
 
        protected byte[] getNativeBytes(int columnIndex, boolean noConversion)
3216
 
                        throws SQLException {
3217
 
                checkRowPos();
3218
 
 
3219
 
                checkColumnBounds(columnIndex);
3220
 
 
3221
 
                try {
3222
 
                        if (this.thisRow[columnIndex - 1] == null) {
3223
 
                                this.wasNullFlag = true;
3224
 
                        } else {
3225
 
                                this.wasNullFlag = false;
3226
 
                        }
3227
 
                } catch (NullPointerException E) {
3228
 
                        this.wasNullFlag = true;
3229
 
                }
3230
 
 
3231
 
                if (this.wasNullFlag) {
3232
 
                        return null;
3233
 
                }
3234
 
 
3235
 
                Field field = this.fields[columnIndex - 1];
3236
 
                
3237
 
                int mysqlType = field.getMysqlType();
3238
 
 
3239
 
                // Workaround for emulated locators in servers > 4.1,
3240
 
                // as server returns SUBSTRING(blob) as STRING type...
3241
 
                if (noConversion) {
3242
 
                        mysqlType = MysqlDefs.FIELD_TYPE_BLOB;
3243
 
                }
3244
 
 
3245
 
                switch (mysqlType) {
3246
 
                case MysqlDefs.FIELD_TYPE_TINY_BLOB:
3247
 
                case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
3248
 
                case MysqlDefs.FIELD_TYPE_LONG_BLOB:
3249
 
                case MysqlDefs.FIELD_TYPE_BLOB:
3250
 
                case MysqlDefs.FIELD_TYPE_BIT:
3251
 
                        return (byte[]) this.thisRow[columnIndex - 1];
3252
 
 
3253
 
                default:
3254
 
                        int sqlType = field.getSQLType();
3255
 
                
3256
 
                        if (sqlType == Types.VARBINARY || sqlType == Types.BINARY) {
3257
 
                                return (byte[]) this.thisRow[columnIndex - 1];
3258
 
                        }
3259
 
                
3260
 
                        return getBytesFromString(getNativeString(columnIndex), columnIndex);
3261
 
                }
3262
 
        }
3263
 
 
3264
 
        /**
3265
 
         * JDBC 2.0
3266
 
         * 
3267
 
         * <p>
3268
 
         * Get the value of a column in the current row as a java.io.Reader.
3269
 
         * </p>
3270
 
         * 
3271
 
         * @param columnIndex
3272
 
         *            the column to get the value from
3273
 
         * 
3274
 
         * @return the value in the column as a java.io.Reader.
3275
 
         * 
3276
 
         * @throws SQLException
3277
 
         *             if an error occurs
3278
 
         */
3279
 
        protected java.io.Reader getNativeCharacterStream(int columnIndex)
3280
 
                        throws SQLException {
3281
 
                String asString = null;
3282
 
                
3283
 
                asString = getStringForClob(columnIndex);
3284
 
 
3285
 
                if (asString == null) {
3286
 
                        return null;
3287
 
                }
3288
 
                return getCharacterStreamFromString(asString, columnIndex);
3289
 
        }
3290
 
 
3291
 
        /**
3292
 
         * JDBC 2.0 Get a CLOB column.
3293
 
         * 
3294
 
         * @param columnIndex
3295
 
         *            the first column is 1, the second is 2, ...
3296
 
         * 
3297
 
         * @return an object representing a CLOB
3298
 
         * 
3299
 
         * @throws SQLException
3300
 
         *             if an error occurs
3301
 
         */
3302
 
        protected java.sql.Clob getNativeClob(int columnIndex) throws SQLException {
3303
 
                String stringVal = getStringForClob(columnIndex);
3304
 
 
3305
 
                if (stringVal == null) {
3306
 
                        return null;
3307
 
                }
3308
 
 
3309
 
                return getClobFromString(stringVal, columnIndex);
3310
 
        }
3311
 
 
3312
 
        private String getNativeConvertToString(int columnIndex, 
3313
 
                        Field field)
3314
 
                        throws SQLException {
3315
 
 
3316
 
                
3317
 
                int sqlType = field.getSQLType();
3318
 
                int mysqlType = field.getMysqlType();
3319
 
 
3320
 
                switch (sqlType) {
3321
 
                case Types.BIT:
3322
 
                        return String.valueOf(getNumericRepresentationOfSQLBitType(columnIndex));
3323
 
                case Types.BOOLEAN:
3324
 
                        boolean booleanVal = getBoolean(columnIndex);
3325
 
 
3326
 
                        if (this.wasNullFlag) {
3327
 
                                return null;
3328
 
                        }
3329
 
 
3330
 
                        return String.valueOf(booleanVal);
3331
 
 
3332
 
                case Types.TINYINT:
3333
 
                        byte tinyintVal = getNativeByte(columnIndex, false);
3334
 
 
3335
 
                        if (this.wasNullFlag) {
3336
 
                                return null;
3337
 
                        }
3338
 
 
3339
 
                        if (!field.isUnsigned() || tinyintVal >= 0) {
3340
 
                                return String.valueOf(tinyintVal);
3341
 
                        }
3342
 
 
3343
 
                        short unsignedTinyVal = (short) (tinyintVal & 0xff);
3344
 
 
3345
 
                        return String.valueOf(unsignedTinyVal);
3346
 
 
3347
 
                case Types.SMALLINT:
3348
 
 
3349
 
                        int intVal = getNativeInt(columnIndex, false);
3350
 
 
3351
 
                        if (this.wasNullFlag) {
3352
 
                                return null;
3353
 
                        }
3354
 
 
3355
 
                        if (!field.isUnsigned() || intVal >= 0) {
3356
 
                                return String.valueOf(intVal);
3357
 
                        }
3358
 
 
3359
 
                        intVal = intVal & 0xffff;
3360
 
 
3361
 
                        return String.valueOf(intVal);
3362
 
 
3363
 
                case Types.INTEGER:
3364
 
                        intVal = getNativeInt(columnIndex, false);
3365
 
 
3366
 
                        if (this.wasNullFlag) {
3367
 
                                return null;
3368
 
                        }
3369
 
 
3370
 
                        if (!field.isUnsigned() || intVal >= 0
3371
 
                                        || field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
3372
 
 
3373
 
                                return String.valueOf(intVal);
3374
 
                        }
3375
 
 
3376
 
                        long longVal = intVal & 0xffffffffL;
3377
 
 
3378
 
                        return String.valueOf(longVal);
3379
 
 
3380
 
                case Types.BIGINT:
3381
 
 
3382
 
                        if (!field.isUnsigned()) {
3383
 
                                longVal = getNativeLong(columnIndex, false, true);
3384
 
 
3385
 
                                if (this.wasNullFlag) {
3386
 
                                        return null;
3387
 
                                }
3388
 
 
3389
 
                                return String.valueOf(longVal);
3390
 
                        }
3391
 
 
3392
 
                        longVal = getNativeLong(columnIndex, false, false);
3393
 
 
3394
 
                        if (this.wasNullFlag) {
3395
 
                                return null;
3396
 
                        }
3397
 
 
3398
 
                        return String.valueOf(convertLongToUlong(longVal));
3399
 
                case Types.REAL:
3400
 
                        float floatVal = getNativeFloat(columnIndex);
3401
 
 
3402
 
                        if (this.wasNullFlag) {
3403
 
                                return null;
3404
 
                        }
3405
 
 
3406
 
                        return String.valueOf(floatVal);
3407
 
 
3408
 
                case Types.FLOAT:
3409
 
                case Types.DOUBLE:
3410
 
                        double doubleVal = getNativeDouble(columnIndex);
3411
 
 
3412
 
                        if (this.wasNullFlag) {
3413
 
                                return null;
3414
 
                        }
3415
 
 
3416
 
                        return String.valueOf(doubleVal);
3417
 
 
3418
 
                case Types.DECIMAL:
3419
 
                case Types.NUMERIC:
3420
 
                        String stringVal = StringUtils
3421
 
                                        .toAsciiString((byte[]) this.thisRow[columnIndex - 1]);
3422
 
 
3423
 
                        BigDecimal val;
3424
 
 
3425
 
                        if (stringVal != null) {
3426
 
                                this.wasNullFlag = false;
3427
 
                                
3428
 
                                if (stringVal.length() == 0) {
3429
 
                                        val = new BigDecimal(0);
3430
 
 
3431
 
                                        return val.toString();
3432
 
                                }
3433
 
 
3434
 
                                try {
3435
 
                                        val = new BigDecimal(stringVal);
3436
 
                                } catch (NumberFormatException ex) {
3437
 
                                        throw SQLError.createSQLException(
3438
 
                                                        Messages
3439
 
                                                                        .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
3440
 
                                                                        + stringVal
3441
 
                                                                        + Messages
3442
 
                                                                                        .getString("ResultSet.___in_column__87")
3443
 
                                                                        + columnIndex + "(" //$NON-NLS-1$
3444
 
                                                                        + this.fields[columnIndex - 1] + ").",
3445
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
3446
 
                                }
3447
 
 
3448
 
                                return val.toString();
3449
 
                        }
3450
 
 
3451
 
                        this.wasNullFlag = true;
3452
 
                        
3453
 
                        return null;
3454
 
 
3455
 
                case Types.CHAR:
3456
 
                case Types.VARCHAR:
3457
 
                case Types.LONGVARCHAR:
3458
 
 
3459
 
                        return extractStringFromNativeColumn(columnIndex, mysqlType);
3460
 
                case Types.BINARY:
3461
 
                case Types.VARBINARY:
3462
 
                case Types.LONGVARBINARY:
3463
 
 
3464
 
                        if (!field.isBlob()) {
3465
 
                                return extractStringFromNativeColumn(columnIndex, mysqlType);
3466
 
                        } else if (!field.isBinary()) {
3467
 
                                return extractStringFromNativeColumn(columnIndex, mysqlType);
3468
 
                        } else {
3469
 
                                byte[] data = getBytes(columnIndex);
3470
 
                                Object obj = data;
3471
 
 
3472
 
                                if ((data != null) && (data.length >= 2)) {
3473
 
                                        if ((data[0] == -84) && (data[1] == -19)) {
3474
 
                                                // Serialized object?
3475
 
                                                try {
3476
 
                                                        ByteArrayInputStream bytesIn = new ByteArrayInputStream(
3477
 
                                                                        data);
3478
 
                                                        ObjectInputStream objIn = new ObjectInputStream(
3479
 
                                                                        bytesIn);
3480
 
                                                        obj = objIn.readObject();
3481
 
                                                        objIn.close();
3482
 
                                                        bytesIn.close();
3483
 
                                                } catch (ClassNotFoundException cnfe) {
3484
 
                                                        throw SQLError.createSQLException(
3485
 
                                                                        Messages
3486
 
                                                                                        .getString("ResultSet.Class_not_found___91") //$NON-NLS-1$
3487
 
                                                                                        + cnfe.toString()
3488
 
                                                                                        + Messages
3489
 
                                                                                                        .getString("ResultSet._while_reading_serialized_object_92")); //$NON-NLS-1$
3490
 
                                                } catch (IOException ex) {
3491
 
                                                        obj = data; // not serialized?
3492
 
                                                }
3493
 
                                        }
3494
 
 
3495
 
                                        return obj.toString();
3496
 
                                }
3497
 
 
3498
 
                                return extractStringFromNativeColumn(columnIndex, mysqlType);
3499
 
                        }
3500
 
 
3501
 
                case Types.DATE:
3502
 
 
3503
 
                        // The YEAR datatype needs to be handled differently here.
3504
 
                        if (mysqlType == MysqlDefs.FIELD_TYPE_YEAR) {
3505
 
                                short shortVal = getNativeShort(columnIndex);
3506
 
 
3507
 
                                if (!this.connection.getYearIsDateType()) {
3508
 
 
3509
 
                                        if (this.wasNullFlag) {
3510
 
                                                return null;
3511
 
                                        }
3512
 
 
3513
 
                                        return String.valueOf(shortVal);
3514
 
                                }
3515
 
 
3516
 
                                if (field.getLength() == 2) {
3517
 
 
3518
 
                                        if (shortVal <= 69) {
3519
 
                                                shortVal = (short) (shortVal + 100);
3520
 
                                        }
3521
 
 
3522
 
                                        shortVal += 1900;
3523
 
                                }
3524
 
 
3525
 
                                return fastDateCreate(null, shortVal, 1, 1).toString();
3526
 
 
3527
 
                        }
3528
 
 
3529
 
                        Date dt = getNativeDate(columnIndex);
3530
 
 
3531
 
                        if (dt == null) {
3532
 
                                return null;
3533
 
                        }
3534
 
 
3535
 
                        return String.valueOf(dt);
3536
 
 
3537
 
                case Types.TIME:
3538
 
                        Time tm = getNativeTime(columnIndex, null, this.defaultTimeZone, false);
3539
 
 
3540
 
                        if (tm == null) {
3541
 
                                return null;
3542
 
                        }
3543
 
 
3544
 
                        return String.valueOf(tm);
3545
 
 
3546
 
                case Types.TIMESTAMP:
3547
 
                        Timestamp tstamp = getNativeTimestamp(columnIndex,
3548
 
                                        null, this.defaultTimeZone, false);
3549
 
 
3550
 
                        if (tstamp == null) {
3551
 
                                return null;
3552
 
                        }
3553
 
 
3554
 
                        String result = String.valueOf(tstamp);
3555
 
 
3556
 
                        if (!this.connection.getNoDatetimeStringSync()) {
3557
 
                                return result;
3558
 
                        }
3559
 
 
3560
 
                        if (result.endsWith(".0")) {
3561
 
                                return result.substring(0, result.length() - 2);
3562
 
                        }
3563
 
 
3564
 
                default:
3565
 
                        return extractStringFromNativeColumn(columnIndex, mysqlType);
3566
 
                }
3567
 
        }
3568
 
 
3569
 
        /**
3570
 
         * Get the value of a column in the current row as a java.sql.Date object
3571
 
         * 
3572
 
         * @param columnIndex
3573
 
         *            the first column is 1, the second is 2...
3574
 
         * 
3575
 
         * @return the column value; null if SQL NULL
3576
 
         * 
3577
 
         * @exception SQLException
3578
 
         *                if a database access error occurs
3579
 
         */
3580
 
        protected java.sql.Date getNativeDate(int columnIndex) throws SQLException {
3581
 
                return getNativeDate(columnIndex, null);
3582
 
        }
3583
 
 
3584
 
        /**
3585
 
         * JDBC 2.0 Get the value of a column in the current row as a java.sql.Date
3586
 
         * object. Use the calendar to construct an appropriate millisecond value
3587
 
         * for the Date, if the underlying database doesn't store timezone
3588
 
         * information.
3589
 
         * 
3590
 
         * @param columnIndex
3591
 
         *            the first column is 1, the second is 2, ...
3592
 
         * @param tz
3593
 
         *            the calendar to use in constructing the date
3594
 
         * 
3595
 
         * @return the column value; if the value is SQL NULL, the result is null
3596
 
         * 
3597
 
         * @exception SQLException
3598
 
         *                if a database-access error occurs.
3599
 
         */
3600
 
        protected java.sql.Date getNativeDate(int columnIndex, TimeZone tz)
3601
 
                        throws SQLException {
3602
 
                checkRowPos();
3603
 
                checkColumnBounds(columnIndex);
3604
 
 
3605
 
                int mysqlType = this.fields[columnIndex - 1].getMysqlType();
3606
 
                
3607
 
                if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) {
3608
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
3609
 
 
3610
 
                        if (bits == null) {
3611
 
                                this.wasNullFlag = true;
3612
 
 
3613
 
                                return null;
3614
 
                        }
3615
 
 
3616
 
                        this.wasNullFlag = false;
3617
 
 
3618
 
                        java.sql.Date dateToReturn = null;
3619
 
 
3620
 
                        int year = 0;
3621
 
                        int month = 0;
3622
 
                        int day = 0;
3623
 
 
3624
 
                        int hour = 0;
3625
 
                        int minute = 0;
3626
 
                        int seconds = 0;
3627
 
 
3628
 
                        if (bits.length != 0) {
3629
 
                                year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
3630
 
 
3631
 
                                month = bits[2];
3632
 
                                day = bits[3];
3633
 
                        }
3634
 
 
3635
 
                        if ((year == 0) && (month == 0) && (day == 0)) {
3636
 
                                if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
3637
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
3638
 
                                        this.wasNullFlag = true;
3639
 
 
3640
 
                                        return null;
3641
 
                                } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
3642
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
3643
 
                                        throw SQLError.createSQLException(
3644
 
                                                        "Value '0000-00-00' can not be represented as java.sql.Date",
3645
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
3646
 
                                }
3647
 
 
3648
 
                                year = 1;
3649
 
                                month = 1;
3650
 
                                day = 1;
3651
 
                        }
3652
 
 
3653
 
                        return fastDateCreate(
3654
 
                                        getCalendarInstanceForSessionOrNew(), year, month, day);
3655
 
                }
3656
 
 
3657
 
                boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone()));
3658
 
 
3659
 
                return (Date)getNativeDateTimeValue(columnIndex, null, Types.DATE, mysqlType, 
3660
 
                                        tz, rollForward);
3661
 
        }
3662
 
 
3663
 
        private java.sql.Date getNativeDateViaParseConversion(int columnIndex) throws SQLException {
3664
 
                if (this.useUsageAdvisor) {
3665
 
                        issueConversionViaParsingWarning("getDate()", columnIndex,
3666
 
                                        this.thisRow[columnIndex - 1], this.fields[columnIndex - 1],
3667
 
                                        new int[] { MysqlDefs.FIELD_TYPE_DATE });
3668
 
                }
3669
 
 
3670
 
                String stringVal = getNativeString(columnIndex);
3671
 
 
3672
 
                return getDateFromString(stringVal, columnIndex);
3673
 
        }
3674
 
 
3675
 
        /**
3676
 
         * Get the value of a column in the current row as a Java double.
3677
 
         * 
3678
 
         * @param columnIndex
3679
 
         *            the first column is 1, the second is 2,...
3680
 
         * 
3681
 
         * @return the column value; 0 if SQL NULL
3682
 
         * 
3683
 
         * @exception SQLException
3684
 
         *                if a database access error occurs
3685
 
         */
3686
 
        protected double getNativeDouble(int columnIndex) throws SQLException {
3687
 
                checkRowPos();
3688
 
                checkColumnBounds(columnIndex);
3689
 
 
3690
 
                columnIndex--; // / JDBC is 1-based
3691
 
 
3692
 
                if (this.thisRow[columnIndex] == null) {
3693
 
                        this.wasNullFlag = true;
3694
 
 
3695
 
                        return 0;
3696
 
                }
3697
 
 
3698
 
                this.wasNullFlag = false;
3699
 
 
3700
 
                Field f= this.fields[columnIndex];
3701
 
                
3702
 
                switch (f.getMysqlType()) {
3703
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
3704
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex];
3705
 
 
3706
 
                        long valueAsLong = (bits[0] & 0xff)
3707
 
                                        | ((long) (bits[1] & 0xff) << 8)
3708
 
                                        | ((long) (bits[2] & 0xff) << 16)
3709
 
                                        | ((long) (bits[3] & 0xff) << 24)
3710
 
                                        | ((long) (bits[4] & 0xff) << 32)
3711
 
                                        | ((long) (bits[5] & 0xff) << 40)
3712
 
                                        | ((long) (bits[6] & 0xff) << 48)
3713
 
                                        | ((long) (bits[7] & 0xff) << 56);
3714
 
 
3715
 
                        return Double.longBitsToDouble(valueAsLong);
3716
 
                case MysqlDefs.FIELD_TYPE_TINY:
3717
 
                        if (!f.isUnsigned()) {
3718
 
                                return (double) getNativeByte(columnIndex + 1);
3719
 
                        }
3720
 
                        
3721
 
                        return (double) getNativeShort(columnIndex + 1);
3722
 
                case MysqlDefs.FIELD_TYPE_SHORT:
3723
 
                case MysqlDefs.FIELD_TYPE_YEAR:
3724
 
                        if (!f.isUnsigned()) {
3725
 
                                return (double) getNativeShort(columnIndex + 1);
3726
 
                        }
3727
 
                        
3728
 
                        return (double) getNativeInt(columnIndex + 1);
3729
 
                case MysqlDefs.FIELD_TYPE_INT24:
3730
 
                case MysqlDefs.FIELD_TYPE_LONG:
3731
 
                        if (!f.isUnsigned()) {
3732
 
                                return (double) getNativeInt(columnIndex + 1);
3733
 
                        }
3734
 
                        
3735
 
                        return (double) getNativeLong(columnIndex + 1);
3736
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
3737
 
                        valueAsLong = getNativeLong(columnIndex + 1);
3738
 
                        
3739
 
                        if (!f.isUnsigned()) {
3740
 
                                return (double) valueAsLong;
3741
 
                        }
3742
 
                        
3743
 
                        BigInteger asBigInt = convertLongToUlong(valueAsLong);
3744
 
                        
3745
 
                        // TODO: Check for overflow
3746
 
                        
3747
 
                        return asBigInt.doubleValue();
3748
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
3749
 
                        return (double) getNativeFloat(columnIndex + 1);
3750
 
                case MysqlDefs.FIELD_TYPE_BIT:
3751
 
                        return getNumericRepresentationOfSQLBitType(columnIndex + 1);
3752
 
                default:
3753
 
 
3754
 
                        if (this.useUsageAdvisor) {
3755
 
                                issueConversionViaParsingWarning("getDouble()", columnIndex,
3756
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
3757
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
3758
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
3759
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
3760
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
3761
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
3762
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
3763
 
                        }
3764
 
 
3765
 
                        String stringVal = getNativeString(columnIndex + 1);
3766
 
 
3767
 
                        return getDoubleFromString(stringVal, columnIndex + 1);
3768
 
                }
3769
 
        }
3770
 
 
3771
 
        /**
3772
 
         * Get the value of a column in the current row as a Java float.
3773
 
         * 
3774
 
         * @param columnIndex
3775
 
         *            the first column is 1, the second is 2,...
3776
 
         * 
3777
 
         * @return the column value; 0 if SQL NULL
3778
 
         * 
3779
 
         * @exception SQLException
3780
 
         *                if a database access error occurs
3781
 
         */
3782
 
        protected float getNativeFloat(int columnIndex) throws SQLException {
3783
 
                checkRowPos();
3784
 
                checkColumnBounds(columnIndex);
3785
 
 
3786
 
                columnIndex--; // / JDBC is 1-based
3787
 
 
3788
 
                if (this.thisRow[columnIndex] == null) {
3789
 
                        this.wasNullFlag = true;
3790
 
 
3791
 
                        return 0;
3792
 
                }
3793
 
 
3794
 
                this.wasNullFlag = false;
3795
 
 
3796
 
                Field f = this.fields[columnIndex];
3797
 
                
3798
 
                switch (f.getMysqlType()) {
3799
 
                case MysqlDefs.FIELD_TYPE_BIT:
3800
 
                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3801
 
 
3802
 
                        return valueAsLong;
3803
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
3804
 
                        
3805
 
                        // Only foolproof way to check for overflow
3806
 
                        // Not efficient, but if you don't want to be inefficient, use the
3807
 
                        // correct binding for the type!
3808
 
                        
3809
 
                        Double valueAsDouble = new Double(getNativeDouble(columnIndex + 1));
3810
 
                        
3811
 
                        float valueAsFloat = valueAsDouble.floatValue();
3812
 
                        
3813
 
                        if (this.connection.getJdbcCompliantTruncationForReads() && 
3814
 
                                        valueAsFloat == Float.NEGATIVE_INFINITY ||
3815
 
                                        valueAsFloat == Float.POSITIVE_INFINITY) {
3816
 
                                throwRangeException(valueAsDouble.toString(), 
3817
 
                                                columnIndex + 1, Types.FLOAT);
3818
 
                        }
3819
 
 
3820
 
                        return (float) getNativeDouble(columnIndex + 1);
3821
 
                case MysqlDefs.FIELD_TYPE_TINY:
3822
 
                        if (!f.isUnsigned()) {
3823
 
                                return (float) getNativeByte(columnIndex + 1);
3824
 
                        }
3825
 
                        
3826
 
                        return (float) getNativeShort(columnIndex + 1);
3827
 
                case MysqlDefs.FIELD_TYPE_SHORT:
3828
 
                case MysqlDefs.FIELD_TYPE_YEAR:
3829
 
                        if (!f.isUnsigned()) {
3830
 
                                return (float) getNativeShort(columnIndex + 1);
3831
 
                        }
3832
 
                        
3833
 
                        return (float) getNativeInt(columnIndex + 1);
3834
 
                case MysqlDefs.FIELD_TYPE_INT24:
3835
 
                case MysqlDefs.FIELD_TYPE_LONG:
3836
 
                        if (!f.isUnsigned()) {
3837
 
                                return (float) getNativeInt(columnIndex + 1);
3838
 
                        }
3839
 
                        
3840
 
                        return (float) getNativeLong(columnIndex + 1);
3841
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
3842
 
                        valueAsLong = getNativeLong(columnIndex + 1);
3843
 
                        
3844
 
                        if (!f.isUnsigned()) {
3845
 
                                return (float) valueAsLong;
3846
 
                        }
3847
 
                        
3848
 
                        BigInteger asBigInt = convertLongToUlong(valueAsLong);
3849
 
                        
3850
 
                        // TODO: Check for overflow
3851
 
                        
3852
 
                        return asBigInt.floatValue();
3853
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
3854
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex];
3855
 
 
3856
 
                        int asInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
3857
 
                                        | ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
3858
 
 
3859
 
                        return Float.intBitsToFloat(asInt);
3860
 
 
3861
 
                default:
3862
 
 
3863
 
                        if (this.useUsageAdvisor) {
3864
 
                                issueConversionViaParsingWarning("getFloat()", columnIndex,
3865
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
3866
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
3867
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
3868
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
3869
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
3870
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
3871
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
3872
 
                        }
3873
 
 
3874
 
                        String stringVal = getNativeString(columnIndex + 1);
3875
 
 
3876
 
                        return getFloatFromString(stringVal, columnIndex + 1);
3877
 
                }
3878
 
        }
3879
 
 
3880
 
        /**
3881
 
         * Get the value of a column in the current row as a Java int.
3882
 
         * 
3883
 
         * @param columnIndex
3884
 
         *            the first column is 1, the second is 2,...
3885
 
         * 
3886
 
         * @return the column value; 0 if SQL NULL
3887
 
         * 
3888
 
         * @exception SQLException
3889
 
         *                if a database access error occurs
3890
 
         */
3891
 
        protected int getNativeInt(int columnIndex) throws SQLException {
3892
 
                return getNativeInt(columnIndex, true);
3893
 
        }
3894
 
        
3895
 
        protected int getNativeInt(int columnIndex, boolean overflowCheck) throws SQLException {
3896
 
                checkRowPos();
3897
 
                checkColumnBounds(columnIndex);
3898
 
 
3899
 
                columnIndex--; // / JDBC is 1-based
3900
 
 
3901
 
                if (this.thisRow[columnIndex] == null) {
3902
 
                        this.wasNullFlag = true;
3903
 
 
3904
 
                        return 0;
3905
 
                }
3906
 
 
3907
 
                this.wasNullFlag = false;
3908
 
 
3909
 
                Field f = this.fields[columnIndex];
3910
 
 
3911
 
                switch (f.getMysqlType()) {
3912
 
                case MysqlDefs.FIELD_TYPE_BIT:
3913
 
                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3914
 
                        
3915
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3916
 
                                        (valueAsLong < Integer.MIN_VALUE
3917
 
                                                        || valueAsLong > Integer.MAX_VALUE)) {
3918
 
                                throwRangeException(String.valueOf(valueAsLong), columnIndex + 1,
3919
 
                                                Types.INTEGER);
3920
 
                        }
3921
 
                        
3922
 
                        return (short)valueAsLong;
3923
 
                case MysqlDefs.FIELD_TYPE_TINY:
3924
 
                        byte tinyintVal = getNativeByte(columnIndex + 1, false);
3925
 
                        
3926
 
                        if (!f.isUnsigned() || tinyintVal >= 0) {
3927
 
                                return tinyintVal;
3928
 
                        }
3929
 
 
3930
 
                        return tinyintVal + 256;
3931
 
                case MysqlDefs.FIELD_TYPE_SHORT:
3932
 
                case MysqlDefs.FIELD_TYPE_YEAR:
3933
 
                        short asShort = getNativeShort(columnIndex + 1, false);
3934
 
                        
3935
 
                        if (!f.isUnsigned() || asShort >= 0) {
3936
 
                                return asShort;
3937
 
                        }
3938
 
 
3939
 
                        return asShort + 65536;
3940
 
                case MysqlDefs.FIELD_TYPE_INT24:
3941
 
                case MysqlDefs.FIELD_TYPE_LONG:
3942
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex];
3943
 
 
3944
 
                        int valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
3945
 
                                        | ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
3946
 
 
3947
 
                        if (!f.isUnsigned()) {  
3948
 
                                return valueAsInt;
3949
 
                        }
3950
 
                        
3951
 
                        valueAsLong = (valueAsInt >= 0) ? 
3952
 
                                        valueAsInt : valueAsInt + 4294967296L; 
3953
 
                        
3954
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3955
 
                                        valueAsLong > Integer.MAX_VALUE) {
3956
 
                                throwRangeException(String.valueOf(valueAsLong),
3957
 
                                                columnIndex + 1, Types.INTEGER);
3958
 
                        }
3959
 
                        
3960
 
                        return (int)valueAsLong;
3961
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
3962
 
                        valueAsLong = getNativeLong(columnIndex + 1, false, true);
3963
 
 
3964
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3965
 
                                if (valueAsLong < Integer.MIN_VALUE
3966
 
                                                || valueAsLong > Integer.MAX_VALUE) {
3967
 
                                        throwRangeException(String.valueOf(valueAsLong),
3968
 
                                                        columnIndex + 1, Types.INTEGER);
3969
 
                                }
3970
 
                        }
3971
 
 
3972
 
                        return (int) valueAsLong;
3973
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
3974
 
                        double valueAsDouble = getNativeDouble(columnIndex + 1);
3975
 
 
3976
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3977
 
                                if (valueAsDouble < Integer.MIN_VALUE
3978
 
                                                || valueAsDouble > Integer.MAX_VALUE) {
3979
 
                                        throwRangeException(String.valueOf(valueAsDouble),
3980
 
                                                        columnIndex + 1, Types.INTEGER);
3981
 
                                }
3982
 
                        }
3983
 
 
3984
 
                        return (int) valueAsDouble;
3985
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
3986
 
                        valueAsDouble = getNativeFloat(columnIndex + 1);
3987
 
 
3988
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3989
 
                                if (valueAsDouble < Integer.MIN_VALUE
3990
 
                                                || valueAsDouble > Integer.MAX_VALUE) {
3991
 
                                        throwRangeException(String.valueOf(valueAsDouble),
3992
 
                                                        columnIndex + 1, Types.INTEGER);
3993
 
                                }
3994
 
                        }
3995
 
 
3996
 
                        return (int) valueAsDouble;
3997
 
 
3998
 
                default:
3999
 
 
4000
 
                        if (this.useUsageAdvisor) {
4001
 
                                issueConversionViaParsingWarning("getInt()", columnIndex,
4002
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
4003
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
4004
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
4005
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
4006
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
4007
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
4008
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
4009
 
                        }
4010
 
 
4011
 
                        String stringVal = getNativeString(columnIndex + 1);
4012
 
 
4013
 
                        return getIntFromString(stringVal, columnIndex + 1);
4014
 
                }
4015
 
        }
4016
 
 
4017
 
        /**
4018
 
         * Get the value of a column in the current row as a Java long.
4019
 
         * 
4020
 
         * @param columnIndex
4021
 
         *            the first column is 1, the second is 2,...
4022
 
         * 
4023
 
         * @return the column value; 0 if SQL NULL
4024
 
         * 
4025
 
         * @exception SQLException
4026
 
         *                if a database access error occurs
4027
 
         */
4028
 
        protected long getNativeLong(int columnIndex) throws SQLException {
4029
 
                return getNativeLong(columnIndex, true, true);
4030
 
        }
4031
 
        
4032
 
        protected long getNativeLong(int columnIndex, boolean overflowCheck, 
4033
 
                        boolean expandUnsignedLong) throws SQLException {
4034
 
                checkRowPos();
4035
 
                checkColumnBounds(columnIndex);
4036
 
 
4037
 
                columnIndex--; // / JDBC is 1-based
4038
 
 
4039
 
                if (this.thisRow[columnIndex] == null) {
4040
 
                        this.wasNullFlag = true;
4041
 
 
4042
 
                        return 0;
4043
 
                }
4044
 
 
4045
 
                this.wasNullFlag = false;
4046
 
 
4047
 
                Field f = this.fields[columnIndex];
4048
 
 
4049
 
                switch (f.getMysqlType()) {
4050
 
                case MysqlDefs.FIELD_TYPE_BIT:
4051
 
                        return getNumericRepresentationOfSQLBitType(columnIndex + 1);
4052
 
                case MysqlDefs.FIELD_TYPE_TINY:
4053
 
                        if (!f.isUnsigned()) {
4054
 
                                return getNativeByte(columnIndex + 1);
4055
 
                        }
4056
 
 
4057
 
                        return getNativeInt(columnIndex + 1);
4058
 
                case MysqlDefs.FIELD_TYPE_SHORT:
4059
 
                        if (!f.isUnsigned()) {
4060
 
                                return getNativeShort(columnIndex + 1);
4061
 
                        }
4062
 
 
4063
 
                        return getNativeInt(columnIndex + 1, false);
4064
 
                case MysqlDefs.FIELD_TYPE_YEAR:
4065
 
 
4066
 
                        return getNativeShort(columnIndex + 1);
4067
 
                case MysqlDefs.FIELD_TYPE_INT24:
4068
 
                case MysqlDefs.FIELD_TYPE_LONG:
4069
 
                        int asInt = getNativeInt(columnIndex + 1, false);
4070
 
                        
4071
 
                        if (!f.isUnsigned() || asInt >= 0) {
4072
 
                                return asInt;
4073
 
                        }
4074
 
 
4075
 
                        return asInt + 4294967296L;
4076
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
4077
 
 
4078
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex];
4079
 
 
4080
 
                        long valueAsLong = (bits[0] & 0xff)
4081
 
                                        | ((long) (bits[1] & 0xff) << 8)
4082
 
                                        | ((long) (bits[2] & 0xff) << 16)
4083
 
                                        | ((long) (bits[3] & 0xff) << 24)
4084
 
                                        | ((long) (bits[4] & 0xff) << 32)
4085
 
                                        | ((long) (bits[5] & 0xff) << 40)
4086
 
                                        | ((long) (bits[6] & 0xff) << 48)
4087
 
                                        | ((long) (bits[7] & 0xff) << 56);
4088
 
 
4089
 
                        if (!f.isUnsigned() || !expandUnsignedLong) {
4090
 
                                return valueAsLong;
4091
 
                        }
4092
 
                        
4093
 
                        BigInteger asBigInt = convertLongToUlong(valueAsLong);
4094
 
                        
4095
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() && 
4096
 
                                        ((asBigInt.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0 ) ||
4097
 
                                         (asBigInt.compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0))) {
4098
 
                                throwRangeException(asBigInt.toString(),
4099
 
                                                columnIndex + 1, Types.BIGINT);
4100
 
                        }
4101
 
                        
4102
 
                        return getLongFromString(asBigInt.toString(), columnIndex + 1);
4103
 
 
4104
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
4105
 
                        double valueAsDouble = getNativeDouble(columnIndex + 1);
4106
 
 
4107
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
4108
 
                                if (valueAsDouble < Long.MIN_VALUE
4109
 
                                                || valueAsDouble > Long.MAX_VALUE) {
4110
 
                                        throwRangeException(String.valueOf(valueAsDouble),
4111
 
                                                        columnIndex + 1, Types.BIGINT);
4112
 
                                }
4113
 
                        }
4114
 
 
4115
 
                        return (long) valueAsDouble;
4116
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
4117
 
                        valueAsDouble = getNativeFloat(columnIndex + 1);
4118
 
 
4119
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
4120
 
                                if (valueAsDouble < Long.MIN_VALUE
4121
 
                                                || valueAsDouble > Long.MAX_VALUE) {
4122
 
                                        throwRangeException(String.valueOf(valueAsDouble),
4123
 
                                                        columnIndex + 1, Types.BIGINT);
4124
 
                                }
4125
 
                        }
4126
 
 
4127
 
                        return (long) valueAsDouble;
4128
 
                default:
4129
 
 
4130
 
                        if (this.useUsageAdvisor) {
4131
 
                                issueConversionViaParsingWarning("getLong()", columnIndex,
4132
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
4133
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
4134
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
4135
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
4136
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
4137
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
4138
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
4139
 
                        }
4140
 
 
4141
 
                        String stringVal = getNativeString(columnIndex + 1);
4142
 
 
4143
 
                        return getLongFromString(stringVal, columnIndex + 1);
4144
 
                }
4145
 
        }
4146
 
 
4147
 
        /**
4148
 
         * JDBC 2.0 Get a REF(&lt;structured-type&gt;) column.
4149
 
         * 
4150
 
         * @param i
4151
 
         *            the first column is 1, the second is 2, ...
4152
 
         * 
4153
 
         * @return an object representing data of an SQL REF type
4154
 
         * 
4155
 
         * @throws SQLException
4156
 
         *             as this is not implemented
4157
 
         * @throws NotImplemented
4158
 
         *             DOCUMENT ME!
4159
 
         */
4160
 
        protected java.sql.Ref getNativeRef(int i) throws SQLException {
4161
 
                throw new NotImplemented();
4162
 
        }
4163
 
 
4164
 
        /**
4165
 
         * Get the value of a column in the current row as a Java short.
4166
 
         * 
4167
 
         * @param columnIndex
4168
 
         *            the first column is 1, the second is 2,...
4169
 
         * 
4170
 
         * @return the column value; 0 if SQL NULL
4171
 
         * 
4172
 
         * @exception SQLException
4173
 
         *                if a database access error occurs
4174
 
         */
4175
 
        protected short getNativeShort(int columnIndex) throws SQLException {
4176
 
                return getNativeShort(columnIndex, true);
4177
 
        }
4178
 
        
4179
 
        protected short getNativeShort(int columnIndex, boolean overflowCheck) throws SQLException {
4180
 
                checkRowPos();
4181
 
                checkColumnBounds(columnIndex);
4182
 
 
4183
 
                columnIndex--; // / JDBC is 1-based
4184
 
 
4185
 
                if (this.thisRow[columnIndex] == null) {
4186
 
                        this.wasNullFlag = true;
4187
 
 
4188
 
                        return 0;
4189
 
                }
4190
 
 
4191
 
                this.wasNullFlag = false;
4192
 
 
4193
 
                Field f = this.fields[columnIndex];
4194
 
 
4195
 
                switch (f.getMysqlType()) {
4196
 
 
4197
 
                case MysqlDefs.FIELD_TYPE_TINY:
4198
 
                        byte tinyintVal = getNativeByte(columnIndex + 1, false);
4199
 
                        
4200
 
                        if (!f.isUnsigned() || tinyintVal >= 0) {
4201
 
                return tinyintVal;
4202
 
                        }
4203
 
                        
4204
 
                        return (short)(tinyintVal + (short)256);
4205
 
                case MysqlDefs.FIELD_TYPE_SHORT:
4206
 
                case MysqlDefs.FIELD_TYPE_YEAR:
4207
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex];
4208
 
                        
4209
 
                        short asShort = (short) ((bits[0] & 0xff) | ((bits[1] & 0xff) << 8));
4210
 
 
4211
 
                        if (!f.isUnsigned()) {
4212
 
                                return asShort;
4213
 
                        }
4214
 
                        
4215
 
                        int valueAsInt = asShort & 0xffff;
4216
 
                        
4217
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
4218
 
                                        valueAsInt > Short.MAX_VALUE) {
4219
 
                                throwRangeException(String.valueOf(valueAsInt),
4220
 
                                                columnIndex + 1, Types.SMALLINT);
4221
 
                        }
4222
 
                        
4223
 
                        return (short)valueAsInt;
4224
 
                case MysqlDefs.FIELD_TYPE_INT24:
4225
 
                case MysqlDefs.FIELD_TYPE_LONG:
4226
 
                        if (!f.isUnsigned()) {
4227
 
                                valueAsInt = getNativeInt(columnIndex + 1, false);
4228
 
                                
4229
 
                                if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
4230
 
                                                valueAsInt > Short.MAX_VALUE ||
4231
 
                                                valueAsInt < Short.MIN_VALUE) {
4232
 
                                        throwRangeException(String.valueOf(valueAsInt),
4233
 
                                                        columnIndex + 1, Types.SMALLINT);
4234
 
                                }
4235
 
                                
4236
 
                                return (short)valueAsInt;
4237
 
                        }
4238
 
                        
4239
 
                        long valueAsLong = getNativeLong(columnIndex + 1, false, true);
4240
 
                        
4241
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
4242
 
                                        valueAsLong > Short.MAX_VALUE) {
4243
 
                                throwRangeException(String.valueOf(valueAsLong),
4244
 
                                                columnIndex + 1, Types.SMALLINT);
4245
 
                        }
4246
 
                        
4247
 
                        return (short)valueAsLong;
4248
 
                        
4249
 
                case MysqlDefs.FIELD_TYPE_LONGLONG:
4250
 
                        valueAsLong = getNativeLong(columnIndex + 1, false, false);
4251
 
                        
4252
 
                        if (!f.isUnsigned()) {
4253
 
                                if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
4254
 
                                        if (valueAsLong < Short.MIN_VALUE
4255
 
                                                        || valueAsLong > Short.MAX_VALUE) {
4256
 
                                                throwRangeException(String.valueOf(valueAsLong),
4257
 
                                                                columnIndex + 1, Types.SMALLINT);
4258
 
                                        }
4259
 
                                }
4260
 
        
4261
 
                                return (short) valueAsLong;
4262
 
                        }
4263
 
                        
4264
 
                        BigInteger asBigInt = convertLongToUlong(valueAsLong);
4265
 
                        
4266
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() && 
4267
 
                                        ((asBigInt.compareTo(new BigInteger(String.valueOf(Short.MAX_VALUE))) > 0 ) ||
4268
 
                                         (asBigInt.compareTo(new BigInteger(String.valueOf(Short.MIN_VALUE))) < 0))) {
4269
 
                                throwRangeException(asBigInt.toString(),
4270
 
                                                columnIndex + 1, Types.SMALLINT);
4271
 
                        }
4272
 
                        
4273
 
                        return (short)getIntFromString(asBigInt.toString(), columnIndex + 1);
4274
 
 
4275
 
                case MysqlDefs.FIELD_TYPE_DOUBLE:
4276
 
                        double valueAsDouble = getNativeDouble(columnIndex + 1);
4277
 
 
4278
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
4279
 
                                if (valueAsDouble < Short.MIN_VALUE
4280
 
                                                || valueAsDouble > Short.MAX_VALUE) {
4281
 
                                        throwRangeException(String.valueOf(valueAsDouble),
4282
 
                                                        columnIndex + 1, Types.SMALLINT);
4283
 
                                }
4284
 
                        }
4285
 
 
4286
 
                        return (short) valueAsDouble;
4287
 
                case MysqlDefs.FIELD_TYPE_FLOAT:
4288
 
                        float valueAsFloat = getNativeFloat(columnIndex + 1);
4289
 
 
4290
 
                        if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
4291
 
                                if (valueAsFloat < Short.MIN_VALUE
4292
 
                                                || valueAsFloat > Short.MAX_VALUE) {
4293
 
                                        throwRangeException(String.valueOf(valueAsFloat),
4294
 
                                                        columnIndex + 1, Types.SMALLINT);
4295
 
                                }
4296
 
                        }
4297
 
 
4298
 
                        return (short) valueAsFloat;
4299
 
                default:
4300
 
 
4301
 
                        if (this.useUsageAdvisor) {
4302
 
                                issueConversionViaParsingWarning("getShort()", columnIndex,
4303
 
                                                this.thisRow[columnIndex], this.fields[columnIndex],
4304
 
                                                new int[] { MysqlDefs.FIELD_TYPE_DOUBLE,
4305
 
                                                                MysqlDefs.FIELD_TYPE_TINY,
4306
 
                                                                MysqlDefs.FIELD_TYPE_SHORT,
4307
 
                                                                MysqlDefs.FIELD_TYPE_LONG,
4308
 
                                                                MysqlDefs.FIELD_TYPE_LONGLONG,
4309
 
                                                                MysqlDefs.FIELD_TYPE_FLOAT });
4310
 
                        }
4311
 
 
4312
 
                        String stringVal = getNativeString(columnIndex + 1);
4313
 
 
4314
 
                        return getShortFromString(stringVal, columnIndex + 1);
4315
 
                }
4316
 
        }
4317
 
 
4318
 
        /**
4319
 
         * Get the value of a column in the current row as a Java String
4320
 
         * 
4321
 
         * @param columnIndex
4322
 
         *            the first column is 1, the second is 2...
4323
 
         * 
4324
 
         * @return the column value, null for SQL NULL
4325
 
         * 
4326
 
         * @exception SQLException
4327
 
         *                if a database access error occurs
4328
 
         */
4329
 
        protected String getNativeString(int columnIndex) throws SQLException {
4330
 
                checkRowPos();
4331
 
                checkColumnBounds(columnIndex);
4332
 
 
4333
 
                if (this.fields == null) {
4334
 
                        throw SQLError.createSQLException(
4335
 
                                        Messages
4336
 
                                                        .getString("ResultSet.Query_generated_no_fields_for_ResultSet_133"), //$NON-NLS-1$
4337
 
                                        SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
4338
 
                }
4339
 
 
4340
 
                try {
4341
 
                        if (this.thisRow[columnIndex - 1] == null) {
4342
 
                                this.wasNullFlag = true;
4343
 
 
4344
 
                                return null;
4345
 
                        }
4346
 
 
4347
 
                        this.wasNullFlag = false;
4348
 
                } catch (NullPointerException E) {
4349
 
                        this.wasNullFlag = true;
4350
 
 
4351
 
                        return null;
4352
 
                }
4353
 
 
4354
 
                String stringVal = null;
4355
 
 
4356
 
                if (this.thisRow[columnIndex - 1] instanceof String) {
4357
 
                        return (String) this.thisRow[columnIndex - 1];
4358
 
                }
4359
 
 
4360
 
                Field field = this.fields[columnIndex - 1];
4361
 
 
4362
 
                // TODO: Check Types Here.
4363
 
                stringVal = getNativeConvertToString(columnIndex, field);
4364
 
 
4365
 
                if (field.isZeroFill() && (stringVal != null)) {
4366
 
                        int origLength = stringVal.length();
4367
 
 
4368
 
                        StringBuffer zeroFillBuf = new StringBuffer(origLength);
4369
 
 
4370
 
                        long numZeros = field.getLength() - origLength;
4371
 
 
4372
 
                        for (long i = 0; i < numZeros; i++) {
4373
 
                                zeroFillBuf.append('0');
4374
 
                        }
4375
 
 
4376
 
                        zeroFillBuf.append(stringVal);
4377
 
 
4378
 
                        stringVal = zeroFillBuf.toString();
4379
 
                }
4380
 
 
4381
 
                return stringVal;
4382
 
                // }
4383
 
        }
4384
 
 
4385
 
        private Time getNativeTime(int columnIndex, Calendar targetCalendar,
4386
 
                        TimeZone tz, boolean rollForward)
4387
 
                        throws SQLException {
4388
 
                checkRowPos();
4389
 
                checkColumnBounds(columnIndex);
4390
 
 
4391
 
                if (this.thisRow[columnIndex - 1] == null) {
4392
 
                        this.wasNullFlag = true;
4393
 
 
4394
 
                        return null;
4395
 
                } else {
4396
 
                        this.wasNullFlag = false;
4397
 
                }
4398
 
 
4399
 
                int mysqlType = this.fields[columnIndex - 1].getMysqlType();
4400
 
 
4401
 
                if (mysqlType == MysqlDefs.FIELD_TYPE_TIME) {
4402
 
 
4403
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
4404
 
 
4405
 
                        int length = bits.length;
4406
 
                        int hour = 0;
4407
 
                        int minute = 0;
4408
 
                        int seconds = 0;
4409
 
 
4410
 
                        if (length != 0) {
4411
 
                                // bits[0] // skip tm->neg
4412
 
                                // binaryData.readLong(); // skip daysPart
4413
 
                                hour = bits[5];
4414
 
                                minute = bits[6];
4415
 
                                seconds = bits[7];
4416
 
                        }
4417
 
 
4418
 
                        Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
4419
 
                        
4420
 
                        synchronized (sessionCalendar) {
4421
 
                                Time time = TimeUtil
4422
 
                                                .fastTimeCreate(sessionCalendar, hour,
4423
 
                                                                minute, seconds);
4424
 
        
4425
 
                                Time adjustedTime = TimeUtil.changeTimezone(this.connection, 
4426
 
                                                sessionCalendar,
4427
 
                                                targetCalendar,
4428
 
                                                time,
4429
 
                                                this.connection.getServerTimezoneTZ(), tz, rollForward);
4430
 
 
4431
 
                                return adjustedTime;
4432
 
                        }
4433
 
                }
4434
 
 
4435
 
                return (Time)getNativeDateTimeValue(columnIndex, targetCalendar,
4436
 
                                Types.TIME, mysqlType, 
4437
 
                                tz, rollForward);
4438
 
        }
4439
 
        
4440
 
        private Time getNativeTimeViaParseConversion(int columnIndex, Calendar targetCalendar,
4441
 
                        TimeZone tz, boolean rollForward) throws SQLException {
4442
 
                if (this.useUsageAdvisor) {
4443
 
                        issueConversionViaParsingWarning("getTime()", columnIndex,
4444
 
                                        this.thisRow[columnIndex - 1], this.fields[columnIndex - 1],
4445
 
                                        new int[] { MysqlDefs.FIELD_TYPE_TIME });
4446
 
                }
4447
 
        
4448
 
                String strTime = getNativeString(columnIndex);
4449
 
        
4450
 
                return getTimeFromString(strTime, targetCalendar, columnIndex, tz, rollForward);
4451
 
        }
4452
 
 
4453
 
        private Timestamp getNativeTimestamp(int columnIndex, 
4454
 
                        Calendar targetCalendar,
4455
 
                        TimeZone tz,
4456
 
                        boolean rollForward) throws SQLException {
4457
 
                checkRowPos();
4458
 
                checkColumnBounds(columnIndex);
4459
 
 
4460
 
                if (this.thisRow[columnIndex - 1] == null) {
4461
 
                        this.wasNullFlag = true;
4462
 
 
4463
 
                        return null;
4464
 
                }
4465
 
 
4466
 
                this.wasNullFlag = false;
4467
 
 
4468
 
                int mysqlType = this.fields[columnIndex - 1].getMysqlType();
4469
 
 
4470
 
                switch (mysqlType) {
4471
 
                case MysqlDefs.FIELD_TYPE_DATETIME:
4472
 
                case MysqlDefs.FIELD_TYPE_TIMESTAMP:
4473
 
                        byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
4474
 
 
4475
 
                        int length = bits.length;
4476
 
 
4477
 
                        int year = 0;
4478
 
                        int month = 0;
4479
 
                        int day = 0;
4480
 
 
4481
 
                        int hour = 0;
4482
 
                        int minute = 0;
4483
 
                        int seconds = 0;
4484
 
 
4485
 
                        int nanos = 0;
4486
 
 
4487
 
                        if (length != 0) {
4488
 
                                year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
4489
 
                                month = bits[2];
4490
 
                                day = bits[3];
4491
 
 
4492
 
                                if (length > 4) {
4493
 
                                        hour = bits[4];
4494
 
                                        minute = bits[5];
4495
 
                                        seconds = bits[6];
4496
 
                                }
4497
 
 
4498
 
                                if (length > 7) {
4499
 
                                        nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8)
4500
 
                                                        | ((bits[9] & 0xff) << 16)
4501
 
                                                        | ((bits[10] & 0xff) << 24);
4502
 
                                }
4503
 
                        }
4504
 
 
4505
 
                        if ((year == 0) && (month == 0) && (day == 0)) {
4506
 
                                if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
4507
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
4508
 
                                        this.wasNullFlag = true;
4509
 
 
4510
 
                                        return null;
4511
 
                                } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
4512
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
4513
 
                                        throw SQLError.createSQLException(
4514
 
                                                        "Value '0000-00-00' can not be represented as java.sql.Timestamp",
4515
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
4516
 
                                }
4517
 
 
4518
 
                                year = 1;
4519
 
                                month = 1;
4520
 
                                day = 1;
4521
 
                        }
4522
 
 
4523
 
                        Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
4524
 
                                        this.connection.getUtcCalendar() : 
4525
 
                                                getCalendarInstanceForSessionOrNew();
4526
 
                        
4527
 
                        synchronized (sessionCalendar) {
4528
 
                                Timestamp ts = fastTimestampCreate(
4529
 
                                                sessionCalendar, year, month, day,
4530
 
                                                hour, minute, seconds, nanos);
4531
 
        
4532
 
                                Timestamp adjustedTs = TimeUtil.changeTimezone(
4533
 
                                                this.connection, sessionCalendar,
4534
 
                                                targetCalendar,
4535
 
                                                ts,
4536
 
                                                this.connection.getServerTimezoneTZ(), tz, rollForward);
4537
 
                                
4538
 
                                return adjustedTs;
4539
 
                        }
4540
 
 
4541
 
                default:
4542
 
                        return (Timestamp)getNativeDateTimeValue(columnIndex, targetCalendar,
4543
 
                                        Types.TIMESTAMP, mysqlType, 
4544
 
                                        tz, rollForward);
4545
 
                }
4546
 
        }
4547
 
 
4548
 
        private Timestamp getNativeTimestampViaParseConversion(int columnIndex, Calendar targetCalendar, 
4549
 
                        TimeZone tz, boolean rollForward) throws SQLException {
4550
 
                if (this.useUsageAdvisor) {
4551
 
                        issueConversionViaParsingWarning("getTimestamp()", columnIndex,
4552
 
                                        this.thisRow[columnIndex - 1], this.fields[columnIndex - 1],
4553
 
                                        new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP,
4554
 
                                                        MysqlDefs.FIELD_TYPE_DATETIME });
4555
 
                }
4556
 
 
4557
 
                String strTimestamp = getNativeString(columnIndex);
4558
 
 
4559
 
                return getTimestampFromString(columnIndex, targetCalendar, strTimestamp, tz,
4560
 
                                rollForward);
4561
 
        }
4562
 
 
4563
 
        // ---------------------------------------------------------------------
4564
 
        // Updates
4565
 
        // ---------------------------------------------------------------------
4566
 
 
4567
 
        /**
4568
 
         * A column value can also be retrieved as a stream of Unicode characters.
4569
 
         * We implement this as a binary stream.
4570
 
         * 
4571
 
         * @param columnIndex
4572
 
         *            the first column is 1, the second is 2...
4573
 
         * 
4574
 
         * @return a Java InputStream that delivers the database column value as a
4575
 
         *         stream of two byte Unicode characters. If the value is SQL NULL,
4576
 
         *         then the result is null
4577
 
         * 
4578
 
         * @exception SQLException
4579
 
         *                if a database access error occurs
4580
 
         * 
4581
 
         * @see getAsciiStream
4582
 
         * @see getBinaryStream
4583
 
         */
4584
 
        protected InputStream getNativeUnicodeStream(int columnIndex)
4585
 
                        throws SQLException {
4586
 
                checkRowPos();
4587
 
 
4588
 
                return getBinaryStream(columnIndex);
4589
 
        }
4590
 
 
4591
 
        /**
4592
 
         * @see ResultSet#getURL(int)
4593
 
         */
4594
 
        protected URL getNativeURL(int colIndex) throws SQLException {
4595
 
                String val = getString(colIndex);
4596
 
 
4597
 
                if (val == null) {
4598
 
                        return null;
4599
 
                }
4600
 
 
4601
 
                try {
4602
 
                        return new URL(val);
4603
 
                } catch (MalformedURLException mfe) {
4604
 
                        throw SQLError.createSQLException(Messages
4605
 
                                        .getString("ResultSet.Malformed_URL____141")
4606
 
                                        + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
4607
 
                }
4608
 
        }
4609
 
 
4610
 
        /**
4611
 
         * DOCUMENT ME!
4612
 
         * 
4613
 
         * @return Returns the nextResultSet, if any, null if none exists.
4614
 
         */
4615
 
        protected ResultSet getNextResultSet() {
4616
 
                return this.nextResultSet;
4617
 
        }
4618
 
 
4619
 
        /**
4620
 
         * Get the value of a column in the current row as a Java object
4621
 
         * 
4622
 
         * <p>
4623
 
         * This method will return the value of the given column as a Java object.
4624
 
         * The type of the Java object will be the default Java Object type
4625
 
         * corresponding to the column's SQL type, following the mapping specified
4626
 
         * in the JDBC specification.
4627
 
         * </p>
4628
 
         * 
4629
 
         * <p>
4630
 
         * This method may also be used to read database specific abstract data
4631
 
         * types.
4632
 
         * </p>
4633
 
         * 
4634
 
         * @param columnIndex
4635
 
         *            the first column is 1, the second is 2...
4636
 
         * 
4637
 
         * @return a Object holding the column value
4638
 
         * 
4639
 
         * @exception SQLException
4640
 
         *                if a database access error occurs
4641
 
         */
4642
 
        public Object getObject(int columnIndex) throws SQLException {
4643
 
                checkRowPos();
4644
 
 
4645
 
                try {
4646
 
                        if (this.thisRow[columnIndex - 1] == null) {
4647
 
                                this.wasNullFlag = true;
4648
 
 
4649
 
                                return null;
4650
 
                        }
4651
 
                } catch (ArrayIndexOutOfBoundsException aioobEx) {
4652
 
                        throw SQLError.createSQLException(Messages.getString(
4653
 
                                        "ResultSet.Column_Index_out_of_range", new Object[] {
4654
 
                                                        new Integer(columnIndex),
4655
 
                                                        new Integer(this.fields.length) }),
4656
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
4657
 
                }
4658
 
 
4659
 
                this.wasNullFlag = false;
4660
 
 
4661
 
                Field field;
4662
 
                field = this.fields[columnIndex - 1];
4663
 
 
4664
 
                //
4665
 
                // If they come from a binary-encode result set,
4666
 
                // no need to create another new object to represent
4667
 
                // the value, just return it directly, unless it's
4668
 
                // a byte[], which means it could be a string or blob.
4669
 
                //
4670
 
                if (this.isBinaryEncoded
4671
 
                                && !(this.thisRow[columnIndex - 1] instanceof byte[])) {
4672
 
 
4673
 
                        //
4674
 
                        // Special case here...If this is a 'bit' type, it will actually
4675
 
                        // have
4676
 
                        // been returned as an Integer by the server...
4677
 
                        //
4678
 
                        if (field.getSQLType() == Types.BIT && field.getLength() > 0) {
4679
 
                                // valueOf would be nicer here, but it isn't
4680
 
                                // present in JDK-1.3.1, which is what the CTS
4681
 
                                // uses.
4682
 
                                return new Boolean(getBoolean(columnIndex));
4683
 
                        }
4684
 
 
4685
 
                        Object columnValue = this.thisRow[columnIndex - 1];
4686
 
 
4687
 
                        if (columnValue == null) {
4688
 
                                this.wasNullFlag = true;
4689
 
 
4690
 
                                return null;
4691
 
                        }
4692
 
 
4693
 
                        return columnValue;
4694
 
                }
4695
 
 
4696
 
                switch (field.getSQLType()) {
4697
 
                case Types.BIT:
4698
 
                case Types.BOOLEAN:
4699
 
                        if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT
4700
 
                                        && !field.isSingleBit()) {
4701
 
                                return getBytes(columnIndex);
4702
 
                        }
4703
 
 
4704
 
                        // valueOf would be nicer here, but it isn't
4705
 
                        // present in JDK-1.3.1, which is what the CTS
4706
 
                        // uses.
4707
 
                        return new Boolean(getBoolean(columnIndex));
4708
 
 
4709
 
                case Types.TINYINT:
4710
 
                        if (!field.isUnsigned()) {
4711
 
                                return new Integer(getByte(columnIndex));
4712
 
                        }
4713
 
 
4714
 
                        return new Integer(getInt(columnIndex));
4715
 
 
4716
 
                case Types.SMALLINT:
4717
 
 
4718
 
                        return new Integer(getInt(columnIndex));
4719
 
 
4720
 
                case Types.INTEGER:
4721
 
 
4722
 
                        if (!field.isUnsigned() || 
4723
 
                                        field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
4724
 
                                return new Integer(getInt(columnIndex));
4725
 
                        }
4726
 
 
4727
 
                        return new Long(getLong(columnIndex));
4728
 
                        
4729
 
                case Types.BIGINT:
4730
 
 
4731
 
                        if (!field.isUnsigned()) {
4732
 
                                return new Long(getLong(columnIndex));
4733
 
                        }
4734
 
 
4735
 
                        String stringVal = getString(columnIndex);
4736
 
 
4737
 
                        if (stringVal == null) {
4738
 
                                return null;
4739
 
                        }
4740
 
 
4741
 
                        try {
4742
 
                                return new BigInteger(stringVal);
4743
 
                        } catch (NumberFormatException nfe) {
4744
 
                                throw SQLError.createSQLException(Messages.getString(
4745
 
                                                "ResultSet.Bad_format_for_BigInteger", new Object[] {
4746
 
                                                                new Integer(columnIndex), stringVal }),
4747
 
                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
4748
 
                        }
4749
 
 
4750
 
                case Types.DECIMAL:
4751
 
                case Types.NUMERIC:
4752
 
                        stringVal = getString(columnIndex);
4753
 
 
4754
 
                        BigDecimal val;
4755
 
 
4756
 
                        if (stringVal != null) {
4757
 
                                if (stringVal.length() == 0) {
4758
 
                                        val = new BigDecimal(0);
4759
 
 
4760
 
                                        return val;
4761
 
                                }
4762
 
 
4763
 
                                try {
4764
 
                                        val = new BigDecimal(stringVal);
4765
 
                                } catch (NumberFormatException ex) {
4766
 
                                        throw SQLError.createSQLException(
4767
 
                                                        Messages
4768
 
                                                                        .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
4769
 
                                                                        + stringVal
4770
 
                                                                        + Messages
4771
 
                                                                                        .getString("ResultSet.___in_column__87")
4772
 
                                                                        + columnIndex + "(" //$NON-NLS-1$
4773
 
                                                                        + this.fields[columnIndex - 1] + ").",
4774
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
4775
 
                                }
4776
 
 
4777
 
                                return val;
4778
 
                        }
4779
 
 
4780
 
                        return null;
4781
 
 
4782
 
                case Types.REAL:
4783
 
                        return new Float(getFloat(columnIndex));
4784
 
 
4785
 
                case Types.FLOAT:
4786
 
                case Types.DOUBLE:
4787
 
                        return new Double(getDouble(columnIndex));
4788
 
 
4789
 
                case Types.CHAR:
4790
 
                case Types.VARCHAR:
4791
 
                        if (!field.isOpaqueBinary()) {
4792
 
                                return getString(columnIndex);
4793
 
                        }
4794
 
 
4795
 
                        return getBytes(columnIndex);
4796
 
                case Types.LONGVARCHAR:
4797
 
                        if (!field.isOpaqueBinary()) {
4798
 
                                return getStringForClob(columnIndex);
4799
 
                        }
4800
 
 
4801
 
                        return getBytes(columnIndex);
4802
 
 
4803
 
                case Types.BINARY:
4804
 
                case Types.VARBINARY:
4805
 
                case Types.LONGVARBINARY:
4806
 
                        if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_GEOMETRY) {
4807
 
                                return getBytes(columnIndex);
4808
 
                        } else if (field.isBinary() || field.isBlob()) {
4809
 
                                byte[] data = getBytes(columnIndex);
4810
 
 
4811
 
                                if (this.connection.getAutoDeserialize()) {
4812
 
                                        Object obj = data;
4813
 
 
4814
 
                                        if ((data != null) && (data.length >= 2)) {
4815
 
                                                if ((data[0] == -84) && (data[1] == -19)) {
4816
 
                                                        // Serialized object?
4817
 
                                                        try {
4818
 
                                                                ByteArrayInputStream bytesIn = new ByteArrayInputStream(
4819
 
                                                                                data);
4820
 
                                                                ObjectInputStream objIn = new ObjectInputStream(
4821
 
                                                                                bytesIn);
4822
 
                                                                obj = objIn.readObject();
4823
 
                                                                objIn.close();
4824
 
                                                                bytesIn.close();
4825
 
                                                        } catch (ClassNotFoundException cnfe) {
4826
 
                                                                throw SQLError.createSQLException(
4827
 
                                                                                Messages
4828
 
                                                                                                .getString("ResultSet.Class_not_found___91") //$NON-NLS-1$
4829
 
                                                                                                + cnfe.toString()
4830
 
                                                                                                + Messages
4831
 
                                                                                                                .getString("ResultSet._while_reading_serialized_object_92")); //$NON-NLS-1$
4832
 
                                                        } catch (IOException ex) {
4833
 
                                                                obj = data; // not serialized?
4834
 
                                                        }
4835
 
                                                } else {
4836
 
                                                        return getString(columnIndex);
4837
 
                                                }
4838
 
                                        }
4839
 
 
4840
 
                                        return obj;
4841
 
                                }
4842
 
 
4843
 
                                return data;
4844
 
                        }
4845
 
 
4846
 
                case Types.DATE:
4847
 
                        if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR
4848
 
                                        && !this.connection.getYearIsDateType()) {
4849
 
                                return new Short(getShort(columnIndex));
4850
 
                        }
4851
 
 
4852
 
                        return getDate(columnIndex);
4853
 
 
4854
 
                case Types.TIME:
4855
 
                        return getTime(columnIndex);
4856
 
 
4857
 
                case Types.TIMESTAMP:
4858
 
                        return getTimestamp(columnIndex);
4859
 
 
4860
 
                default:
4861
 
                        return getString(columnIndex);
4862
 
                }
4863
 
        }
4864
 
 
4865
 
        /**
4866
 
         * JDBC 2.0 Returns the value of column i as a Java object. Use the map to
4867
 
         * determine the class from which to construct data of SQL structured and
4868
 
         * distinct types.
4869
 
         * 
4870
 
         * @param i
4871
 
         *            the first column is 1, the second is 2, ...
4872
 
         * @param map
4873
 
         *            the mapping from SQL type names to Java classes
4874
 
         * 
4875
 
         * @return an object representing the SQL value
4876
 
         * 
4877
 
         * @throws SQLException
4878
 
         *             because this is not implemented
4879
 
         */
4880
 
        public Object getObject(int i, java.util.Map map) throws SQLException {
4881
 
                return getObject(i);
4882
 
        }
4883
 
 
4884
 
        /**
4885
 
         * Get the value of a column in the current row as a Java object
4886
 
         * 
4887
 
         * <p>
4888
 
         * This method will return the value of the given column as a Java object.
4889
 
         * The type of the Java object will be the default Java Object type
4890
 
         * corresponding to the column's SQL type, following the mapping specified
4891
 
         * in the JDBC specification.
4892
 
         * </p>
4893
 
         * 
4894
 
         * <p>
4895
 
         * This method may also be used to read database specific abstract data
4896
 
         * types.
4897
 
         * </p>
4898
 
         * 
4899
 
         * @param columnName
4900
 
         *            is the SQL name of the column
4901
 
         * 
4902
 
         * @return a Object holding the column value
4903
 
         * 
4904
 
         * @exception SQLException
4905
 
         *                if a database access error occurs
4906
 
         */
4907
 
        public Object getObject(String columnName) throws SQLException {
4908
 
                return getObject(findColumn(columnName));
4909
 
        }
4910
 
 
4911
 
        /**
4912
 
         * JDBC 2.0 Returns the value of column i as a Java object. Use the map to
4913
 
         * determine the class from which to construct data of SQL structured and
4914
 
         * distinct types.
4915
 
         * 
4916
 
         * @param colName
4917
 
         *            the column name
4918
 
         * @param map
4919
 
         *            the mapping from SQL type names to Java classes
4920
 
         * 
4921
 
         * @return an object representing the SQL value
4922
 
         * 
4923
 
         * @throws SQLException
4924
 
         *             as this is not implemented
4925
 
         */
4926
 
        public Object getObject(String colName, java.util.Map map)
4927
 
                        throws SQLException {
4928
 
                return getObject(findColumn(colName), map);
4929
 
        }
4930
 
 
4931
 
        protected Object getObjectStoredProc(int columnIndex, int desiredSqlType)
4932
 
                        throws SQLException {
4933
 
                checkRowPos();
4934
 
 
4935
 
                try {
4936
 
                        if (this.thisRow[columnIndex - 1] == null) {
4937
 
                                this.wasNullFlag = true;
4938
 
 
4939
 
                                return null;
4940
 
                        }
4941
 
                } catch (ArrayIndexOutOfBoundsException aioobEx) {
4942
 
                        throw SQLError.createSQLException(Messages.getString(
4943
 
                                        "ResultSet.Column_Index_out_of_range", new Object[] {
4944
 
                                                        new Integer(columnIndex),
4945
 
                                                        new Integer(this.fields.length) }),
4946
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
4947
 
                }
4948
 
 
4949
 
                this.wasNullFlag = false;
4950
 
 
4951
 
                Field field;
4952
 
                field = this.fields[columnIndex - 1];
4953
 
 
4954
 
                switch (desiredSqlType) {
4955
 
                case Types.BIT:
4956
 
                case Types.BOOLEAN:
4957
 
                        // valueOf would be nicer here, but it isn't
4958
 
                        // present in JDK-1.3.1, which is what the CTS
4959
 
                        // uses.
4960
 
                        return new Boolean(getBoolean(columnIndex));
4961
 
 
4962
 
                case Types.TINYINT:
4963
 
                        return new Integer(getInt(columnIndex));
4964
 
 
4965
 
                case Types.SMALLINT:
4966
 
                        return new Integer(getInt(columnIndex));
4967
 
 
4968
 
                case Types.INTEGER:
4969
 
 
4970
 
                        if (!field.isUnsigned() || 
4971
 
                                        field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
4972
 
                                return new Integer(getInt(columnIndex));
4973
 
                        }
4974
 
 
4975
 
                        return new Long(getLong(columnIndex));
4976
 
 
4977
 
                case Types.BIGINT:
4978
 
 
4979
 
                        if (field.isUnsigned()) {
4980
 
                                return getBigDecimal(columnIndex);
4981
 
                        }
4982
 
 
4983
 
                        return new Long(getLong(columnIndex));
4984
 
 
4985
 
                case Types.DECIMAL:
4986
 
                case Types.NUMERIC:
4987
 
 
4988
 
                        String stringVal = getString(columnIndex);
4989
 
                        BigDecimal val;
4990
 
 
4991
 
                        if (stringVal != null) {
4992
 
                                if (stringVal.length() == 0) {
4993
 
                                        val = new BigDecimal(0);
4994
 
 
4995
 
                                        return val;
4996
 
                                }
4997
 
 
4998
 
                                try {
4999
 
                                        val = new BigDecimal(stringVal);
5000
 
                                } catch (NumberFormatException ex) {
5001
 
                                        throw SQLError.createSQLException(
5002
 
                                                        Messages
5003
 
                                                                        .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
5004
 
                                                                        + stringVal
5005
 
                                                                        + Messages
5006
 
                                                                                        .getString("ResultSet.___in_column__87")
5007
 
                                                                        + columnIndex + "(" //$NON-NLS-1$
5008
 
                                                                        + this.fields[columnIndex - 1] + ").",
5009
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5010
 
                                }
5011
 
 
5012
 
                                return val;
5013
 
                        }
5014
 
 
5015
 
                        return null;
5016
 
 
5017
 
                case Types.REAL:
5018
 
                        return new Float(getFloat(columnIndex));
5019
 
 
5020
 
                case Types.FLOAT:
5021
 
 
5022
 
                        if (!this.connection.getRunningCTS13()) {
5023
 
                                return new Double(getFloat(columnIndex));
5024
 
                        } else {
5025
 
                                return new Float(getFloat(columnIndex)); // NB - bug in JDBC
5026
 
                                                                                                                        // compliance test,
5027
 
                                                                                                                        // according
5028
 
                                // to JDBC spec, FLOAT type should return DOUBLE
5029
 
                                // but causes ClassCastException in CTS :(
5030
 
                        }
5031
 
                case Types.DOUBLE:
5032
 
                        return new Double(getDouble(columnIndex));
5033
 
 
5034
 
                case Types.CHAR:
5035
 
                case Types.VARCHAR:
5036
 
                        return getString(columnIndex);
5037
 
                case Types.LONGVARCHAR:
5038
 
                        return getStringForClob(columnIndex);
5039
 
                case Types.BINARY:
5040
 
                case Types.VARBINARY:
5041
 
                case Types.LONGVARBINARY:
5042
 
                        return getBytes(columnIndex);
5043
 
 
5044
 
                case Types.DATE:
5045
 
                        if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR
5046
 
                                        && !this.connection.getYearIsDateType()) {
5047
 
                                return new Short(getShort(columnIndex));
5048
 
                        }
5049
 
 
5050
 
                        return getDate(columnIndex);
5051
 
 
5052
 
                case Types.TIME:
5053
 
                        return getTime(columnIndex);
5054
 
 
5055
 
                case Types.TIMESTAMP:
5056
 
                        return getTimestamp(columnIndex);
5057
 
 
5058
 
                default:
5059
 
                        return getString(columnIndex);
5060
 
                }
5061
 
        }
5062
 
 
5063
 
        protected Object getObjectStoredProc(int i, java.util.Map map,
5064
 
                        int desiredSqlType) throws SQLException {
5065
 
                return getObjectStoredProc(i, desiredSqlType);
5066
 
        }
5067
 
 
5068
 
        protected Object getObjectStoredProc(String columnName, int desiredSqlType)
5069
 
                        throws SQLException {
5070
 
                return getObjectStoredProc(findColumn(columnName), desiredSqlType);
5071
 
        }
5072
 
 
5073
 
        protected Object getObjectStoredProc(String colName, java.util.Map map,
5074
 
                        int desiredSqlType) throws SQLException {
5075
 
                return getObjectStoredProc(findColumn(colName), map, desiredSqlType);
5076
 
        }
5077
 
 
5078
 
        /**
5079
 
         * JDBC 2.0 Get a REF(&lt;structured-type&gt;) column.
5080
 
         * 
5081
 
         * @param i
5082
 
         *            the first column is 1, the second is 2, ...
5083
 
         * 
5084
 
         * @return an object representing data of an SQL REF type
5085
 
         * 
5086
 
         * @throws SQLException
5087
 
         *             as this is not implemented
5088
 
         * @throws NotImplemented
5089
 
         *             DOCUMENT ME!
5090
 
         */
5091
 
        public java.sql.Ref getRef(int i) throws SQLException {
5092
 
                checkColumnBounds(i);
5093
 
                throw new NotImplemented();
5094
 
        }
5095
 
 
5096
 
        /**
5097
 
         * JDBC 2.0 Get a REF(&lt;structured-type&gt;) column.
5098
 
         * 
5099
 
         * @param colName
5100
 
         *            the column name
5101
 
         * 
5102
 
         * @return an object representing data of an SQL REF type
5103
 
         * 
5104
 
         * @throws SQLException
5105
 
         *             as this method is not implemented.
5106
 
         * @throws NotImplemented
5107
 
         *             DOCUMENT ME!
5108
 
         */
5109
 
        public java.sql.Ref getRef(String colName) throws SQLException {
5110
 
                return getRef(findColumn(colName));
5111
 
        }
5112
 
 
5113
 
        /**
5114
 
         * JDBC 2.0
5115
 
         * 
5116
 
         * <p>
5117
 
         * Determine the current row number. The first row is number 1, the second
5118
 
         * number 2, etc.
5119
 
         * </p>
5120
 
         * 
5121
 
         * @return the current row number, else return 0 if there is no current row
5122
 
         * 
5123
 
         * @exception SQLException
5124
 
         *                if a database-access error occurs.
5125
 
         */
5126
 
        public int getRow() throws SQLException {
5127
 
                checkClosed();
5128
 
 
5129
 
                int currentRowNumber = this.rowData.getCurrentRowNumber();
5130
 
                int row = 0;
5131
 
 
5132
 
                // Non-dynamic result sets can be interrogated
5133
 
                // for this information
5134
 
                if (!this.rowData.isDynamic()) {
5135
 
                        if ((currentRowNumber < 0) || this.rowData.isAfterLast()
5136
 
                                        || this.rowData.isEmpty()) {
5137
 
                                row = 0;
5138
 
                        } else {
5139
 
                                row = currentRowNumber + 1;
5140
 
                        }
5141
 
                } else {
5142
 
                        // dynamic (streaming) can not
5143
 
                        row = currentRowNumber + 1;
5144
 
                }
5145
 
 
5146
 
                return row;
5147
 
        }
5148
 
 
5149
 
        /**
5150
 
         * Returns the server info (if any), or null if none.
5151
 
         * 
5152
 
         * @return server info created for this ResultSet
5153
 
         */
5154
 
        protected String getServerInfo() {
5155
 
                return this.serverInfo;
5156
 
        }
5157
 
 
5158
 
        private long getNumericRepresentationOfSQLBitType(int columnIndex) throws SQLException {
5159
 
                
5160
 
                if (this.fields[columnIndex - 1].isSingleBit() || 
5161
 
                                ((byte[])this.thisRow[columnIndex - 1]).length == 1) {
5162
 
                        return ((byte[])this.thisRow[columnIndex - 1])[0];
5163
 
                }
5164
 
                
5165
 
                
5166
 
                byte[] asBytes = (byte[])this.thisRow[columnIndex - 1];
5167
 
                
5168
 
                
5169
 
                int shift = 0;
5170
 
                
5171
 
                long[] steps = new long[asBytes.length];
5172
 
                
5173
 
                for (int i = asBytes.length - 1; i >= 0; i--) {
5174
 
                        steps[i] = (long)(asBytes[i] & 0xff) << shift;
5175
 
                        shift += 8;
5176
 
                }
5177
 
                
5178
 
                long valueAsLong = 0;
5179
 
                
5180
 
                for (int i = 0; i < asBytes.length; i++) {
5181
 
                        valueAsLong |= steps[i];
5182
 
                }
5183
 
                
5184
 
                return valueAsLong;
5185
 
        }
5186
 
 
5187
 
        /**
5188
 
         * Get the value of a column in the current row as a Java short.
5189
 
         * 
5190
 
         * @param columnIndex
5191
 
         *            the first column is 1, the second is 2,...
5192
 
         * 
5193
 
         * @return the column value; 0 if SQL NULL
5194
 
         * 
5195
 
         * @exception SQLException
5196
 
         *                if a database access error occurs
5197
 
         */
5198
 
        public short getShort(int columnIndex) throws SQLException {
5199
 
                if (!this.isBinaryEncoded) {
5200
 
                        checkRowPos();
5201
 
                        
5202
 
                        if (this.connection.getUseFastIntParsing()) {
5203
 
                                
5204
 
                                checkColumnBounds(columnIndex);
5205
 
                                
5206
 
                                try {
5207
 
                                        if (this.thisRow[columnIndex - 1] == null) {
5208
 
                                                this.wasNullFlag = true;
5209
 
                                        } else {
5210
 
                                                this.wasNullFlag = false;
5211
 
                                        }
5212
 
                                } catch (NullPointerException E) {
5213
 
                                        this.wasNullFlag = true;
5214
 
                                } catch (ArrayIndexOutOfBoundsException aioobEx) {
5215
 
                                        throw SQLError.createSQLException(Messages.getString(
5216
 
                                                        "ResultSet.Column_Index_out_of_range",
5217
 
                                                        new Object[] { new Integer(columnIndex),
5218
 
                                                                        new Integer(this.fields.length) }),
5219
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
5220
 
                                }
5221
 
 
5222
 
                                if (this.wasNullFlag) {
5223
 
                                        return 0;
5224
 
                                }
5225
 
 
5226
 
                                byte[] shortAsBytes = (byte[]) this.thisRow[columnIndex - 1];
5227
 
 
5228
 
                                if (shortAsBytes.length == 0) {
5229
 
                                        return (short) convertToZeroWithEmptyCheck();
5230
 
                                }
5231
 
 
5232
 
                                boolean needsFullParse = false;
5233
 
 
5234
 
                                for (int i = 0; i < shortAsBytes.length; i++) {
5235
 
                                        if (((char) shortAsBytes[i] == 'e')
5236
 
                                                        || ((char) shortAsBytes[i] == 'E')) {
5237
 
                                                needsFullParse = true;
5238
 
 
5239
 
                                                break;
5240
 
                                        }
5241
 
                                }
5242
 
 
5243
 
                                if (!needsFullParse) {
5244
 
                                        try {
5245
 
                                                return parseShortWithOverflowCheck(columnIndex,
5246
 
                                                                shortAsBytes, null);
5247
 
                                        } catch (NumberFormatException nfe) {
5248
 
                                                try {
5249
 
                                                        // To do: Warn of over/underflow???
5250
 
                                                        return parseShortAsDouble(columnIndex, new String(
5251
 
                                                                        shortAsBytes));
5252
 
                                                } catch (NumberFormatException newNfe) {
5253
 
                                                        ; // ignore, it's not a number
5254
 
                                                }
5255
 
 
5256
 
                                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5257
 
                                                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
5258
 
                                                        
5259
 
                                                        if (this.connection.getJdbcCompliantTruncationForReads() &&
5260
 
                                                                        (valueAsLong < Short.MIN_VALUE
5261
 
                                                                                        || valueAsLong > Short.MAX_VALUE)) {
5262
 
                                                                throwRangeException(String.valueOf(valueAsLong), columnIndex,
5263
 
                                                                                Types.SMALLINT);
5264
 
                                                        }
5265
 
                                                        
5266
 
                                                        return (short)valueAsLong;
5267
 
                                                }
5268
 
                                                
5269
 
                                                throw SQLError.createSQLException(
5270
 
                                                                Messages
5271
 
                                                                                .getString("ResultSet.Invalid_value_for_getShort()_-____96")
5272
 
                                                                                + new String(shortAsBytes) //$NON-NLS-1$
5273
 
                                                                                + "'",
5274
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5275
 
                                        }
5276
 
                                }
5277
 
                        }
5278
 
 
5279
 
                        String val = null;
5280
 
 
5281
 
                        try {
5282
 
                                val = getString(columnIndex);
5283
 
 
5284
 
                                if ((val != null)) {
5285
 
 
5286
 
                                        if (val.length() == 0) {
5287
 
                                                return (short) convertToZeroWithEmptyCheck();
5288
 
                                        }
5289
 
 
5290
 
                                        if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
5291
 
                                                        && (val.indexOf(".") == -1)) {
5292
 
                                                return parseShortWithOverflowCheck(columnIndex, null,
5293
 
                                                                val);
5294
 
                                        }
5295
 
 
5296
 
                                        // Convert floating point
5297
 
                                        return parseShortAsDouble(columnIndex, val);
5298
 
                                }
5299
 
 
5300
 
                                return 0; // for NULL
5301
 
                        } catch (NumberFormatException nfe) {
5302
 
                                try {
5303
 
                                        return parseShortAsDouble(columnIndex, val);
5304
 
                                } catch (NumberFormatException newNfe) {
5305
 
                                        ; // ignore, it's not a number
5306
 
                                }
5307
 
 
5308
 
                                if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5309
 
                                        long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
5310
 
                                        
5311
 
                                        if (this.connection.getJdbcCompliantTruncationForReads() &&
5312
 
                                                        (valueAsLong < Short.MIN_VALUE
5313
 
                                                                        || valueAsLong > Short.MAX_VALUE)) {
5314
 
                                                throwRangeException(String.valueOf(valueAsLong), columnIndex,
5315
 
                                                                Types.SMALLINT);
5316
 
                                        }
5317
 
                                        
5318
 
                                        return (short)valueAsLong;
5319
 
                                }
5320
 
                                
5321
 
                                throw SQLError.createSQLException(
5322
 
                                                Messages
5323
 
                                                                .getString("ResultSet.Invalid_value_for_getShort()_-____96")
5324
 
                                                                + val //$NON-NLS-1$
5325
 
                                                                + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5326
 
                        }
5327
 
                }
5328
 
 
5329
 
                return getNativeShort(columnIndex);
5330
 
        }
5331
 
 
5332
 
        /**
5333
 
         * DOCUMENT ME!
5334
 
         * 
5335
 
         * @param columnName
5336
 
         *            DOCUMENT ME!
5337
 
         * 
5338
 
         * @return DOCUMENT ME!
5339
 
         * 
5340
 
         * @throws SQLException
5341
 
         *             DOCUMENT ME!
5342
 
         */
5343
 
        public short getShort(String columnName) throws SQLException {
5344
 
                return getShort(findColumn(columnName));
5345
 
        }
5346
 
 
5347
 
        private final short getShortFromString(String val, int columnIndex)
5348
 
                        throws SQLException {
5349
 
                try {
5350
 
                        if ((val != null)) {
5351
 
 
5352
 
                                if (val.length() == 0) {
5353
 
                                        return (short) convertToZeroWithEmptyCheck();
5354
 
                                }
5355
 
 
5356
 
                                if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
5357
 
                                                && (val.indexOf(".") == -1)) {
5358
 
                                        return parseShortWithOverflowCheck(columnIndex, null, val);
5359
 
                                }
5360
 
 
5361
 
                                // Convert floating point
5362
 
                                return parseShortAsDouble(columnIndex, val);
5363
 
                        }
5364
 
 
5365
 
                        return 0; // for NULL
5366
 
                } catch (NumberFormatException nfe) {
5367
 
                        try {
5368
 
                                return parseShortAsDouble(columnIndex, val);
5369
 
                        } catch (NumberFormatException newNfe) {
5370
 
                                ; // ignore, it's not a number
5371
 
                        }
5372
 
 
5373
 
                        throw SQLError.createSQLException(
5374
 
                                        Messages
5375
 
                                                        .getString("ResultSet.Invalid_value_for_getShort()_-____217")
5376
 
                                                        + val //$NON-NLS-1$
5377
 
                                                        + Messages.getString("ResultSet.___in_column__218")
5378
 
                                                        + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
5379
 
                }
5380
 
        }
5381
 
 
5382
 
        /**
5383
 
         * JDBC 2.0 Return the Statement that produced the ResultSet.
5384
 
         * 
5385
 
         * @return the Statment that produced the result set, or null if the result
5386
 
         *         was produced some other way.
5387
 
         * 
5388
 
         * @exception SQLException
5389
 
         *                if a database-access error occurs
5390
 
         */
5391
 
        public java.sql.Statement getStatement() throws SQLException {
5392
 
                if (this.isClosed && !this.retainOwningStatement) {
5393
 
                        throw SQLError.createSQLException(
5394
 
                                        "Operation not allowed on closed ResultSet. Statements "
5395
 
                                                        + "can be retained over result set closure by setting the connection property "
5396
 
                                                        + "\"retainStatementAfterResultSetClose\" to \"true\".",
5397
 
                                        SQLError.SQL_STATE_GENERAL_ERROR);
5398
 
 
5399
 
                }
5400
 
                
5401
 
                if (this.wrapperStatement != null) {
5402
 
                        return this.wrapperStatement;
5403
 
                }
5404
 
 
5405
 
                return this.owningStatement;
5406
 
        }
5407
 
 
5408
 
        /**
5409
 
         * Get the value of a column in the current row as a Java String
5410
 
         * 
5411
 
         * @param columnIndex
5412
 
         *            the first column is 1, the second is 2...
5413
 
         * 
5414
 
         * @return the column value, null for SQL NULL
5415
 
         * 
5416
 
         * @exception SQLException
5417
 
         *                if a database access error occurs
5418
 
         */
5419
 
        public String getString(int columnIndex) throws SQLException {
5420
 
                return getStringInternal(columnIndex, true);
5421
 
        }
5422
 
 
5423
 
        /**
5424
 
         * The following routines simply convert the columnName into a columnIndex
5425
 
         * and then call the appropriate routine above.
5426
 
         * 
5427
 
         * @param columnName
5428
 
         *            is the SQL name of the column
5429
 
         * 
5430
 
         * @return the column value
5431
 
         * 
5432
 
         * @exception SQLException
5433
 
         *                if a database access error occurs
5434
 
         */
5435
 
        public String getString(String columnName) throws SQLException {
5436
 
                return getString(findColumn(columnName));
5437
 
        }
5438
 
 
5439
 
        private String getStringForClob(int columnIndex) throws SQLException {
5440
 
                String asString = null;
5441
 
                
5442
 
                String forcedEncoding = 
5443
 
                        this.connection.getClobCharacterEncoding();
5444
 
                
5445
 
                if (forcedEncoding == null) {
5446
 
                        if (!this.isBinaryEncoded) {
5447
 
                                asString = getString(columnIndex);
5448
 
                        } else {
5449
 
                                asString = getNativeString(columnIndex);
5450
 
                        }
5451
 
                } else {
5452
 
                        try {
5453
 
                                byte[] asBytes = null;
5454
 
                                
5455
 
                                if (!this.isBinaryEncoded) {
5456
 
                                        asBytes = getBytes(columnIndex);
5457
 
                                } else {
5458
 
                                        asBytes = getNativeBytes(columnIndex, true);
5459
 
                                }
5460
 
                                
5461
 
                                if (asBytes != null) {
5462
 
                                        asString = new String(asBytes, forcedEncoding);
5463
 
                                }
5464
 
                        } catch (UnsupportedEncodingException uee) {
5465
 
                                throw SQLError.createSQLException("Unsupported character encoding " + 
5466
 
                                                forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5467
 
                        }
5468
 
                }
5469
 
                
5470
 
                return asString;
5471
 
        }
5472
 
 
5473
 
        protected String getStringInternal(int columnIndex, boolean checkDateTypes)
5474
 
                        throws SQLException {
5475
 
                if (!this.isBinaryEncoded) {
5476
 
                        checkRowPos();
5477
 
                        checkColumnBounds(columnIndex);
5478
 
 
5479
 
                        if (this.fields == null) {
5480
 
                                throw SQLError.createSQLException(
5481
 
                                                Messages
5482
 
                                                                .getString("ResultSet.Query_generated_no_fields_for_ResultSet_99"), //$NON-NLS-1$
5483
 
                                                SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
5484
 
                        }
5485
 
 
5486
 
                        try {
5487
 
                                if (this.thisRow[columnIndex - 1] == null) {
5488
 
                                        this.wasNullFlag = true;
5489
 
 
5490
 
                                        return null;
5491
 
                                }
5492
 
 
5493
 
                                this.wasNullFlag = false;
5494
 
                        } catch (NullPointerException E) {
5495
 
                                this.wasNullFlag = true;
5496
 
 
5497
 
                                return null;
5498
 
                        }
5499
 
 
5500
 
                        String stringVal = null;
5501
 
                        columnIndex--; // JDBC is 1-based, Java is not !?
5502
 
 
5503
 
                        if (this.fields[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5504
 
                                if (this.fields[columnIndex].isSingleBit()) {
5505
 
                                        byte[] asBytes = (byte[])this.thisRow[columnIndex];
5506
 
                                        
5507
 
                                        if (asBytes.length == 0) {
5508
 
                                                return String.valueOf(convertToZeroWithEmptyCheck());
5509
 
                                        }
5510
 
                                        
5511
 
                                        return String.valueOf(asBytes[0]);
5512
 
                                }
5513
 
                                
5514
 
                                return String.valueOf(getNumericRepresentationOfSQLBitType(columnIndex + 1));
5515
 
                        }
5516
 
                        
5517
 
                        String encoding = this.fields[columnIndex].getCharacterSet();
5518
 
 
5519
 
                        if ((this.connection != null) && this.connection.getUseUnicode()) {
5520
 
                                try {
5521
 
                                        if (encoding == null) {
5522
 
                                                stringVal = new String(
5523
 
                                                                (byte[]) this.thisRow[columnIndex]);
5524
 
                                        } else {
5525
 
                                                SingleByteCharsetConverter converter = this.connection
5526
 
                                                                .getCharsetConverter(encoding);
5527
 
 
5528
 
                                                if (converter != null) {
5529
 
                                                        stringVal = converter
5530
 
                                                                        .toString((byte[]) this.thisRow[columnIndex]);
5531
 
                                                } else {
5532
 
                                                        stringVal = new String(
5533
 
                                                                        (byte[]) this.thisRow[columnIndex],
5534
 
                                                                        encoding);
5535
 
                                                }
5536
 
                                        }
5537
 
                                } catch (java.io.UnsupportedEncodingException E) {
5538
 
                                        throw SQLError.createSQLException(
5539
 
                                                        Messages
5540
 
                                                                        .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
5541
 
                                                                        + encoding + "'.", "0S100");
5542
 
                                }
5543
 
                        } else {
5544
 
                                stringVal = StringUtils
5545
 
                                                .toAsciiString((byte[]) this.thisRow[columnIndex]);
5546
 
                        }
5547
 
 
5548
 
                        //
5549
 
                        // Special handling for YEAR type from mysql, some people
5550
 
                        // want it as a DATE, others want to treat it as a SHORT
5551
 
                        //
5552
 
 
5553
 
                        if (this.fields[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
5554
 
                                if (!this.connection.getYearIsDateType()) {
5555
 
                                        return stringVal;
5556
 
                                }
5557
 
 
5558
 
                                Date dt = getDateFromString(stringVal, columnIndex + 1);
5559
 
 
5560
 
                                if (dt == null) {
5561
 
                                        this.wasNullFlag = true;
5562
 
 
5563
 
                                        return null;
5564
 
                                }
5565
 
 
5566
 
                                this.wasNullFlag = false;
5567
 
 
5568
 
                                return dt.toString();
5569
 
                        }
5570
 
 
5571
 
                        // Handles timezone conversion and zero-date behavior
5572
 
 
5573
 
                        if (checkDateTypes && !this.connection.getNoDatetimeStringSync()) {
5574
 
                                switch (this.fields[columnIndex].getSQLType()) {
5575
 
                                case Types.TIME:
5576
 
                                        Time tm = getTimeFromString(stringVal, null, columnIndex + 1,
5577
 
                                                        this.getDefaultTimeZone(), false);
5578
 
 
5579
 
                                        if (tm == null) {
5580
 
                                                this.wasNullFlag = true;
5581
 
 
5582
 
                                                return null;
5583
 
                                        }
5584
 
 
5585
 
                                        this.wasNullFlag = false;
5586
 
 
5587
 
                                        return tm.toString();
5588
 
                                case Types.DATE:
5589
 
 
5590
 
                                        Date dt = getDateFromString(stringVal, columnIndex + 1);
5591
 
 
5592
 
                                        if (dt == null) {
5593
 
                                                this.wasNullFlag = true;
5594
 
 
5595
 
                                                return null;
5596
 
                                        }
5597
 
 
5598
 
                                        this.wasNullFlag = false;
5599
 
 
5600
 
                                        return dt.toString();
5601
 
                                case Types.TIMESTAMP:
5602
 
                                        Timestamp ts = getTimestampFromString(columnIndex + 1,
5603
 
                                                        null, stringVal, this.getDefaultTimeZone(), false);
5604
 
 
5605
 
                                        if (ts == null) {
5606
 
                                                this.wasNullFlag = true;
5607
 
 
5608
 
                                                return null;
5609
 
                                        }
5610
 
 
5611
 
                                        this.wasNullFlag = false;
5612
 
 
5613
 
                                        return ts.toString();
5614
 
                                default:
5615
 
                                        break;
5616
 
                                }
5617
 
                        }
5618
 
 
5619
 
                        return stringVal;
5620
 
                }
5621
 
 
5622
 
                return getNativeString(columnIndex);
5623
 
        }
5624
 
 
5625
 
        /**
5626
 
         * Get the value of a column in the current row as a java.sql.Time object
5627
 
         * 
5628
 
         * @param columnIndex
5629
 
         *            the first column is 1, the second is 2...
5630
 
         * 
5631
 
         * @return the column value; null if SQL NULL
5632
 
         * 
5633
 
         * @throws java.sql.SQLException
5634
 
         *             if a database access error occurs
5635
 
         */
5636
 
        public Time getTime(int columnIndex) throws java.sql.SQLException {
5637
 
                return getTimeInternal(columnIndex, null, this.getDefaultTimeZone(), false);
5638
 
        }
5639
 
 
5640
 
        /**
5641
 
         * Get the value of a column in the current row as a java.sql.Time object.
5642
 
         * Use the calendar to construct an appropriate millisecond value for the
5643
 
         * Time, if the underlying database doesn't store timezone information.
5644
 
         * 
5645
 
         * @param columnIndex
5646
 
         *            the first column is 1, the second is 2, ...
5647
 
         * @param cal
5648
 
         *            the calendar to use in constructing the time
5649
 
         * 
5650
 
         * @return the column value; if the value is SQL NULL, the result is null
5651
 
         * 
5652
 
         * @exception SQLException
5653
 
         *                if a database-access error occurs.
5654
 
         */
5655
 
        public java.sql.Time getTime(int columnIndex, Calendar cal)
5656
 
                        throws SQLException {
5657
 
                return getTimeInternal(columnIndex, cal, cal.getTimeZone(), true);
5658
 
        }
5659
 
 
5660
 
        /**
5661
 
         * Get the value of a column in the current row as a java.sql.Time object.
5662
 
         * 
5663
 
         * @param columnName
5664
 
         *            is the SQL name of the column
5665
 
         * 
5666
 
         * @return the column value; if the value is SQL NULL, the result is null
5667
 
         * 
5668
 
         * @throws java.sql.SQLException
5669
 
         *             if a database-access error occurs.
5670
 
         */
5671
 
        public Time getTime(String columnName) throws java.sql.SQLException {
5672
 
                return getTime(findColumn(columnName));
5673
 
        }
5674
 
 
5675
 
        /**
5676
 
         * Get the value of a column in the current row as a java.sql.Time object.
5677
 
         * Use the calendar to construct an appropriate millisecond value for the
5678
 
         * Time, if the underlying database doesn't store timezone information.
5679
 
         * 
5680
 
         * @param columnName
5681
 
         *            is the SQL name of the column
5682
 
         * @param cal
5683
 
         *            the calendar to use in constructing the time
5684
 
         * 
5685
 
         * @return the column value; if the value is SQL NULL, the result is null
5686
 
         * 
5687
 
         * @exception SQLException
5688
 
         *                if a database-access error occurs.
5689
 
         */
5690
 
        public java.sql.Time getTime(String columnName, Calendar cal)
5691
 
                        throws SQLException {
5692
 
                return getTime(findColumn(columnName), cal);
5693
 
        }
5694
 
 
5695
 
        private Time getTimeFromString(String timeAsString, Calendar targetCalendar,
5696
 
                        int columnIndex,
5697
 
                        TimeZone tz, 
5698
 
                        boolean rollForward) throws SQLException {
5699
 
                int hr = 0;
5700
 
                int min = 0;
5701
 
                int sec = 0;
5702
 
 
5703
 
                try {
5704
 
                        
5705
 
                        if (timeAsString == null) {
5706
 
                                this.wasNullFlag = true;
5707
 
 
5708
 
                                return null;
5709
 
                        } 
5710
 
                        
5711
 
                        //
5712
 
                        // JDK-6 doesn't like trailing whitespace
5713
 
                        //
5714
 
                        // Note this isn't a performance issue, other
5715
 
                        // than the iteration over the string, as String.trim()
5716
 
                        // will return a new string only if whitespace is present
5717
 
                        //
5718
 
                        
5719
 
                        timeAsString = timeAsString.trim();
5720
 
                        
5721
 
                        if (timeAsString.equals("0")
5722
 
                                        || timeAsString.equals("0000-00-00")
5723
 
                                        || timeAsString.equals("0000-00-00 00:00:00")
5724
 
                                        || timeAsString.equals("00000000000000")) {
5725
 
                                if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
5726
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
5727
 
                                        this.wasNullFlag = true;
5728
 
 
5729
 
                                        return null;
5730
 
                                } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
5731
 
                                                .equals(this.connection.getZeroDateTimeBehavior())) {
5732
 
                                        throw SQLError.createSQLException("Value '" + timeAsString
5733
 
                                                        + " can not be represented as java.sql.Time",
5734
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5735
 
                                }
5736
 
 
5737
 
                                // We're left with the case of 'round' to a time Java _can_
5738
 
                                // represent, which is '00:00:00'
5739
 
                                return fastTimeCreate(null, 0, 0, 0);
5740
 
                        }
5741
 
 
5742
 
                        this.wasNullFlag = false;
5743
 
 
5744
 
                        Field timeColField = this.fields[columnIndex - 1];
5745
 
 
5746
 
                        if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
5747
 
                                // It's a timestamp
5748
 
                                int length = timeAsString.length();
5749
 
 
5750
 
                                switch (length) {
5751
 
                                case 14:
5752
 
                                case 12: {
5753
 
                                        hr = Integer.parseInt(timeAsString.substring(length - 6,
5754
 
                                                        length - 4));
5755
 
                                        min = Integer.parseInt(timeAsString.substring(length - 4,
5756
 
                                                        length - 2));
5757
 
                                        sec = Integer.parseInt(timeAsString.substring(length - 2,
5758
 
                                                        length));
5759
 
                                }
5760
 
 
5761
 
                                        break;
5762
 
 
5763
 
                                case 10: {
5764
 
                                        hr = Integer.parseInt(timeAsString.substring(6, 8));
5765
 
                                        min = Integer.parseInt(timeAsString.substring(8, 10));
5766
 
                                        sec = 0;
5767
 
                                }
5768
 
 
5769
 
                                        break;
5770
 
 
5771
 
                                default:
5772
 
                                        throw SQLError.createSQLException(
5773
 
                                                        Messages
5774
 
                                                                        .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
5775
 
                                                                        + columnIndex
5776
 
                                                                        + "("
5777
 
                                                                        + this.fields[columnIndex - 1] + ").",
5778
 
                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5779
 
                                } /* endswitch */
5780
 
 
5781
 
                                SQLWarning precisionLost = new SQLWarning(
5782
 
                                                Messages
5783
 
                                                                .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
5784
 
                                                                + columnIndex
5785
 
                                                                + "("
5786
 
                                                                + this.fields[columnIndex - 1] + ").");
5787
 
 
5788
 
                                if (this.warningChain == null) {
5789
 
                                        this.warningChain = precisionLost;
5790
 
                                } else {
5791
 
                                        this.warningChain.setNextWarning(precisionLost);
5792
 
                                }
5793
 
                        } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
5794
 
                                hr = Integer.parseInt(timeAsString.substring(11, 13));
5795
 
                                min = Integer.parseInt(timeAsString.substring(14, 16));
5796
 
                                sec = Integer.parseInt(timeAsString.substring(17, 19));
5797
 
 
5798
 
                                SQLWarning precisionLost = new SQLWarning(
5799
 
                                                Messages
5800
 
                                                                .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
5801
 
                                                                + columnIndex
5802
 
                                                                + "("
5803
 
                                                                + this.fields[columnIndex - 1] + ").");
5804
 
 
5805
 
                                if (this.warningChain == null) {
5806
 
                                        this.warningChain = precisionLost;
5807
 
                                } else {
5808
 
                                        this.warningChain.setNextWarning(precisionLost);
5809
 
                                }
5810
 
                        } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
5811
 
                                return fastTimeCreate(null, 0, 0, 0); // midnight on the given
5812
 
                                                                                                                // date
5813
 
                        } else {
5814
 
                                // convert a String to a Time
5815
 
                                if ((timeAsString.length() != 5)
5816
 
                                                && (timeAsString.length() != 8)) {
5817
 
                                        throw SQLError.createSQLException(Messages
5818
 
                                                        .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
5819
 
                                                        + timeAsString
5820
 
                                                        + Messages.getString("ResultSet.___in_column__268")
5821
 
                                                        + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5822
 
                                }
5823
 
 
5824
 
                                hr = Integer.parseInt(timeAsString.substring(0, 2));
5825
 
                                min = Integer.parseInt(timeAsString.substring(3, 5));
5826
 
                                sec = (timeAsString.length() == 5) ? 0 : Integer
5827
 
                                                .parseInt(timeAsString.substring(6));
5828
 
                        }
5829
 
 
5830
 
                        Calendar sessionCalendar = this.getCalendarInstanceForSessionOrNew();
5831
 
                        
5832
 
                        synchronized (sessionCalendar) {
5833
 
                                return TimeUtil.changeTimezone(this.connection, 
5834
 
                                                sessionCalendar,
5835
 
                                                targetCalendar, 
5836
 
                                                fastTimeCreate(
5837
 
                                                sessionCalendar, hr, min, sec), 
5838
 
                                                this.connection.getServerTimezoneTZ(),
5839
 
                                                tz, rollForward);
5840
 
                        }
5841
 
                } catch (Exception ex) {
5842
 
                        throw SQLError.createSQLException(ex.toString(),
5843
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5844
 
                }
5845
 
        }
5846
 
 
5847
 
        /**
5848
 
         * Get the value of a column in the current row as a java.sql.Time object in
5849
 
         * the given timezone
5850
 
         * 
5851
 
         * @param columnIndex
5852
 
         *            the first column is 1, the second is 2...
5853
 
         * @param tz
5854
 
         *            the Timezone to use
5855
 
         * 
5856
 
         * @return the column value; null if SQL NULL
5857
 
         * 
5858
 
         * @exception java.sql.SQLException
5859
 
         *                if a database access error occurs
5860
 
         */
5861
 
        private Time getTimeInternal(int columnIndex, Calendar targetCalendar,
5862
 
                        TimeZone tz,
5863
 
                        boolean rollForward) throws java.sql.SQLException {
5864
 
                if (this.isBinaryEncoded) {
5865
 
                        return getNativeTime(columnIndex, targetCalendar, tz, rollForward);
5866
 
                }
5867
 
 
5868
 
                String timeAsString = getStringInternal(columnIndex, false);
5869
 
 
5870
 
                return getTimeFromString(timeAsString, targetCalendar,
5871
 
                                columnIndex, tz, rollForward);
5872
 
        }
5873
 
 
5874
 
        /**
5875
 
         * Get the value of a column in the current row as a java.sql.Timestamp
5876
 
         * object
5877
 
         * 
5878
 
         * @param columnIndex
5879
 
         *            the first column is 1, the second is 2...
5880
 
         * 
5881
 
         * @return the column value; null if SQL NULL
5882
 
         * 
5883
 
         * @exception java.sql.SQLException
5884
 
         *                if a database access error occurs
5885
 
         */
5886
 
        public Timestamp getTimestamp(int columnIndex) throws java.sql.SQLException {
5887
 
                return getTimestampInternal(columnIndex, null, this.getDefaultTimeZone(),
5888
 
                                false);
5889
 
        }
5890
 
 
5891
 
        /**
5892
 
         * Get the value of a column in the current row as a java.sql.Timestamp
5893
 
         * object. Use the calendar to construct an appropriate millisecond value
5894
 
         * for the Timestamp, if the underlying database doesn't store timezone
5895
 
         * information.
5896
 
         * 
5897
 
         * @param columnIndex
5898
 
         *            the first column is 1, the second is 2, ...
5899
 
         * @param cal
5900
 
         *            the calendar to use in constructing the timestamp
5901
 
         * 
5902
 
         * @return the column value; if the value is SQL NULL, the result is null
5903
 
         * 
5904
 
         * @exception SQLException
5905
 
         *                if a database-access error occurs.
5906
 
         */
5907
 
        public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal)
5908
 
                        throws SQLException {
5909
 
                return getTimestampInternal(columnIndex, cal, cal.getTimeZone(), true);
5910
 
        }
5911
 
 
5912
 
        /**
5913
 
         * DOCUMENT ME!
5914
 
         * 
5915
 
         * @param columnName
5916
 
         *            DOCUMENT ME!
5917
 
         * 
5918
 
         * @return DOCUMENT ME!
5919
 
         * 
5920
 
         * @throws java.sql.SQLException
5921
 
         *             DOCUMENT ME!
5922
 
         */
5923
 
        public Timestamp getTimestamp(String columnName)
5924
 
                        throws java.sql.SQLException {
5925
 
                return getTimestamp(findColumn(columnName));
5926
 
        }
5927
 
 
5928
 
        /**
5929
 
         * Get the value of a column in the current row as a java.sql.Timestamp
5930
 
         * object. Use the calendar to construct an appropriate millisecond value
5931
 
         * for the Timestamp, if the underlying database doesn't store timezone
5932
 
         * information.
5933
 
         * 
5934
 
         * @param columnName
5935
 
         *            is the SQL name of the column
5936
 
         * @param cal
5937
 
         *            the calendar to use in constructing the timestamp
5938
 
         * 
5939
 
         * @return the column value; if the value is SQL NULL, the result is null
5940
 
         * 
5941
 
         * @exception SQLException
5942
 
         *                if a database-access error occurs.
5943
 
         */
5944
 
        public java.sql.Timestamp getTimestamp(String columnName, Calendar cal)
5945
 
                        throws SQLException {
5946
 
                return getTimestamp(findColumn(columnName), cal);
5947
 
        }
5948
 
 
5949
 
        private Timestamp getTimestampFromString(int columnIndex,
5950
 
                        Calendar targetCalendar,
5951
 
                        String timestampValue, TimeZone tz, boolean rollForward)
5952
 
        throws java.sql.SQLException {
5953
 
                try {
5954
 
                        this.wasNullFlag = false;
5955
 
                        
5956
 
                        if (timestampValue == null) {
5957
 
                                this.wasNullFlag = true;
5958
 
                                
5959
 
                                return null;
5960
 
                        }
5961
 
                        
5962
 
                        //
5963
 
                        // JDK-6 doesn't like trailing whitespace
5964
 
                        //
5965
 
                        // Note this isn't a performance issue, other
5966
 
                        // than the iteration over the string, as String.trim()
5967
 
                        // will return a new string only if whitespace is present
5968
 
                        //
5969
 
                        
5970
 
                        timestampValue = timestampValue.trim();
5971
 
                        
5972
 
                        int length = timestampValue.length();
5973
 
                        
5974
 
                        Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
5975
 
                                        this.connection.getUtcCalendar() : 
5976
 
                                                getCalendarInstanceForSessionOrNew();
5977
 
                        
5978
 
                        synchronized (sessionCalendar) {
5979
 
                                if ((length > 0)
5980
 
                                                && (timestampValue.charAt(0) == '0')
5981
 
                                                && (timestampValue.equals("0000-00-00")
5982
 
                                                                || timestampValue.equals("0000-00-00 00:00:00")
5983
 
                                                                || timestampValue.equals("00000000000000") || timestampValue
5984
 
                                                                .equals("0"))) {
5985
 
                                        
5986
 
                                        if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
5987
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
5988
 
                                                this.wasNullFlag = true;
5989
 
                                                
5990
 
                                                return null;
5991
 
                                        } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
5992
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
5993
 
                                                throw SQLError.createSQLException("Value '" + timestampValue
5994
 
                                                                + " can not be represented as java.sql.Timestamp",
5995
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5996
 
                                        }
5997
 
                                        
5998
 
                                        // We're left with the case of 'round' to a date Java _can_
5999
 
                                        // represent, which is '0001-01-01'.
6000
 
                                        return fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);
6001
 
                                        
6002
 
                                } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
6003
 
                                        
6004
 
                                        return TimeUtil.changeTimezone(this.connection,
6005
 
                                                        sessionCalendar, 
6006
 
                                                        targetCalendar,
6007
 
                                                        fastTimestampCreate(sessionCalendar, 
6008
 
                                                                        Integer
6009
 
                                                                        .parseInt(timestampValue.substring(0, 4)), 1,
6010
 
                                                                        1, 0, 0, 0, 0), this.connection
6011
 
                                                                        .getServerTimezoneTZ(), tz, rollForward);
6012
 
                                        
6013
 
                                } else {
6014
 
                                        if (timestampValue.endsWith(".")) {
6015
 
                                                timestampValue = timestampValue.substring(0, timestampValue
6016
 
                                                                .length() - 1);
6017
 
                                        }
6018
 
                                        
6019
 
                                        // Convert from TIMESTAMP or DATE
6020
 
                                        switch (length) {
6021
 
                                        case 26:
6022
 
                                        case 25:
6023
 
                                        case 24:
6024
 
                                        case 23:
6025
 
                                        case 22:
6026
 
                                        case 21:
6027
 
                                        case 20:
6028
 
                                        case 19: {
6029
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 4));
6030
 
                                                int month = Integer
6031
 
                                                .parseInt(timestampValue.substring(5, 7));
6032
 
                                                int day = Integer.parseInt(timestampValue.substring(8, 10));
6033
 
                                                int hour = Integer.parseInt(timestampValue
6034
 
                                                                .substring(11, 13));
6035
 
                                                int minutes = Integer.parseInt(timestampValue.substring(14,
6036
 
                                                                16));
6037
 
                                                int seconds = Integer.parseInt(timestampValue.substring(17,
6038
 
                                                                19));
6039
 
                                                
6040
 
                                                int nanos = 0;
6041
 
                                                
6042
 
                                                if (length > 19) {
6043
 
                                                        int decimalIndex = timestampValue.lastIndexOf('.');
6044
 
                                                        
6045
 
                                                        if (decimalIndex != -1) {
6046
 
                                                                if ((decimalIndex + 2) <= timestampValue.length()) {
6047
 
                                                                        nanos = Integer.parseInt(timestampValue
6048
 
                                                                                        .substring(decimalIndex + 1));
6049
 
                                                                } else {
6050
 
                                                                        throw new IllegalArgumentException(); // re-thrown
6051
 
                                                                        // further
6052
 
                                                                        // down
6053
 
                                                                        // with
6054
 
                                                                        // a
6055
 
                                                                        // much better error message
6056
 
                                                                }
6057
 
                                                        }
6058
 
                                                }
6059
 
                                                
6060
 
                                                return TimeUtil.changeTimezone(this.connection,
6061
 
                                                                sessionCalendar,
6062
 
                                                                targetCalendar,
6063
 
                                                                fastTimestampCreate(sessionCalendar, year, month, day, hour,
6064
 
                                                                                minutes, seconds, nanos), this.connection
6065
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6066
 
                                        }
6067
 
                                        
6068
 
                                        case 14: {
6069
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 4));
6070
 
                                                int month = Integer
6071
 
                                                .parseInt(timestampValue.substring(4, 6));
6072
 
                                                int day = Integer.parseInt(timestampValue.substring(6, 8));
6073
 
                                                int hour = Integer
6074
 
                                                .parseInt(timestampValue.substring(8, 10));
6075
 
                                                int minutes = Integer.parseInt(timestampValue.substring(10,
6076
 
                                                                12));
6077
 
                                                int seconds = Integer.parseInt(timestampValue.substring(12,
6078
 
                                                                14));
6079
 
                                                
6080
 
                                                return TimeUtil.changeTimezone(this.connection,
6081
 
                                                                sessionCalendar, 
6082
 
                                                                targetCalendar,
6083
 
                                                                fastTimestampCreate(sessionCalendar, year, month, day, hour,
6084
 
                                                                                minutes, seconds, 0), this.connection
6085
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6086
 
                                        }
6087
 
                                        
6088
 
                                        case 12: {
6089
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 2));
6090
 
                                                
6091
 
                                                if (year <= 69) {
6092
 
                                                        year = (year + 100);
6093
 
                                                }
6094
 
                                                
6095
 
                                                int month = Integer
6096
 
                                                .parseInt(timestampValue.substring(2, 4));
6097
 
                                                int day = Integer.parseInt(timestampValue.substring(4, 6));
6098
 
                                                int hour = Integer.parseInt(timestampValue.substring(6, 8));
6099
 
                                                int minutes = Integer.parseInt(timestampValue.substring(8,
6100
 
                                                                10));
6101
 
                                                int seconds = Integer.parseInt(timestampValue.substring(10,
6102
 
                                                                12));
6103
 
                                                
6104
 
                                                return TimeUtil.changeTimezone(this.connection,
6105
 
                                                                sessionCalendar,
6106
 
                                                                targetCalendar,
6107
 
                                                                fastTimestampCreate(sessionCalendar, year + 1900, month, day,
6108
 
                                                                                hour, minutes, seconds, 0), this.connection
6109
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6110
 
                                        }
6111
 
                                        
6112
 
                                        case 10: {
6113
 
                                                int year;
6114
 
                                                int month;
6115
 
                                                int day;
6116
 
                                                int hour;
6117
 
                                                int minutes;
6118
 
                                                
6119
 
                                                if ((this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
6120
 
                                                                || (timestampValue.indexOf("-") != -1)) {
6121
 
                                                        year = Integer.parseInt(timestampValue.substring(0, 4));
6122
 
                                                        month = Integer
6123
 
                                                        .parseInt(timestampValue.substring(5, 7));
6124
 
                                                        day = Integer.parseInt(timestampValue.substring(8, 10));
6125
 
                                                        hour = 0;
6126
 
                                                        minutes = 0;
6127
 
                                                } else {
6128
 
                                                        year = Integer.parseInt(timestampValue.substring(0, 2));
6129
 
                                                        
6130
 
                                                        if (year <= 69) {
6131
 
                                                                year = (year + 100);
6132
 
                                                        }
6133
 
                                                        
6134
 
                                                        month = Integer
6135
 
                                                        .parseInt(timestampValue.substring(2, 4));
6136
 
                                                        day = Integer.parseInt(timestampValue.substring(4, 6));
6137
 
                                                        hour = Integer.parseInt(timestampValue.substring(6, 8));
6138
 
                                                        minutes = Integer.parseInt(timestampValue.substring(8,
6139
 
                                                                        10));
6140
 
                                                        
6141
 
                                                        year += 1900; // two-digit year
6142
 
                                                }
6143
 
                                                
6144
 
                                                return TimeUtil.changeTimezone(this.connection,
6145
 
                                                                sessionCalendar,
6146
 
                                                                targetCalendar,
6147
 
                                                                fastTimestampCreate(sessionCalendar, year, month, day, hour,
6148
 
                                                                                minutes, 0, 0), this.connection
6149
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6150
 
                                        }
6151
 
                                        
6152
 
                                        case 8: {
6153
 
                                                if (timestampValue.indexOf(":") != -1) {
6154
 
                                                        int hour = Integer.parseInt(timestampValue.substring(0,
6155
 
                                                                        2));
6156
 
                                                        int minutes = Integer.parseInt(timestampValue
6157
 
                                                                        .substring(3, 5));
6158
 
                                                        int seconds = Integer.parseInt(timestampValue
6159
 
                                                                        .substring(6, 8));
6160
 
                                                        
6161
 
                                                        return TimeUtil
6162
 
                                                        .changeTimezone(this.connection,
6163
 
                                                                        sessionCalendar,
6164
 
                                                                        targetCalendar,
6165
 
                                                                        fastTimestampCreate(sessionCalendar, 70, 0, 1,
6166
 
                                                                                        hour, minutes, seconds, 0),
6167
 
                                                                                        this.connection.getServerTimezoneTZ(),
6168
 
                                                                                        tz, rollForward);
6169
 
                                                        
6170
 
                                                }
6171
 
                                                
6172
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 4));
6173
 
                                                int month = Integer
6174
 
                                                .parseInt(timestampValue.substring(4, 6));
6175
 
                                                int day = Integer.parseInt(timestampValue.substring(6, 8));
6176
 
                                                
6177
 
                                                return TimeUtil.changeTimezone(this.connection,
6178
 
                                                                sessionCalendar,
6179
 
                                                                targetCalendar,
6180
 
                                                                fastTimestampCreate(sessionCalendar, year - 1900, month - 1,
6181
 
                                                                                day, 0, 0, 0, 0), this.connection
6182
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6183
 
                                        }
6184
 
                                        
6185
 
                                        case 6: {
6186
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 2));
6187
 
                                                
6188
 
                                                if (year <= 69) {
6189
 
                                                        year = (year + 100);
6190
 
                                                }
6191
 
                                                
6192
 
                                                int month = Integer
6193
 
                                                .parseInt(timestampValue.substring(2, 4));
6194
 
                                                int day = Integer.parseInt(timestampValue.substring(4, 6));
6195
 
                                                
6196
 
                                                return TimeUtil.changeTimezone(this.connection,
6197
 
                                                                sessionCalendar,
6198
 
                                                                targetCalendar,
6199
 
                                                                fastTimestampCreate(sessionCalendar, year + 1900, month, day,
6200
 
                                                                                0, 0, 0, 0), this.connection
6201
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6202
 
                                        }
6203
 
                                        
6204
 
                                        case 4: {
6205
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 2));
6206
 
                                                
6207
 
                                                if (year <= 69) {
6208
 
                                                        year = (year + 100);
6209
 
                                                }
6210
 
                                                
6211
 
                                                int month = Integer
6212
 
                                                .parseInt(timestampValue.substring(2, 4));
6213
 
                                                
6214
 
                                                return TimeUtil.changeTimezone(this.connection,
6215
 
                                                                sessionCalendar,
6216
 
                                                                targetCalendar,
6217
 
                                                                fastTimestampCreate(sessionCalendar, year + 1900, month, 1, 0,
6218
 
                                                                                0, 0, 0), this.connection
6219
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6220
 
                                        }
6221
 
                                        
6222
 
                                        case 2: {
6223
 
                                                int year = Integer.parseInt(timestampValue.substring(0, 2));
6224
 
                                                
6225
 
                                                if (year <= 69) {
6226
 
                                                        year = (year + 100);
6227
 
                                                }
6228
 
                                                
6229
 
                                                return TimeUtil.changeTimezone(this.connection,
6230
 
                                                                sessionCalendar,
6231
 
                                                                targetCalendar,
6232
 
                                                                fastTimestampCreate(null, year + 1900, 1, 1, 0, 0,
6233
 
                                                                                0, 0), this.connection
6234
 
                                                                                .getServerTimezoneTZ(), tz, rollForward);
6235
 
                                        }
6236
 
                                        
6237
 
                                        default:
6238
 
                                                throw new java.sql.SQLException(
6239
 
                                                                "Bad format for Timestamp '" + timestampValue
6240
 
                                                                + "' in column " + columnIndex + ".",
6241
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
6242
 
                                        }
6243
 
                                }
6244
 
                        }
6245
 
                } catch (Exception e) {
6246
 
                        throw new java.sql.SQLException("Cannot convert value '"
6247
 
                                        + timestampValue + "' from column " + columnIndex
6248
 
                                        + " to TIMESTAMP.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
6249
 
                }
6250
 
                
6251
 
        }
6252
 
 
6253
 
        /**
6254
 
         * Get the value of a column in the current row as a java.sql.Timestamp
6255
 
         * object in the given timezone
6256
 
         * 
6257
 
         * @param columnIndex
6258
 
         *            the first column is 1, the second is 2...
6259
 
         * @param tz
6260
 
         *            the timezone to use
6261
 
         * 
6262
 
         * @return the column value; null if SQL NULL
6263
 
         * 
6264
 
         * @exception java.sql.SQLException
6265
 
         *                if a database access error occurs
6266
 
         */
6267
 
        private Timestamp getTimestampInternal(int columnIndex, Calendar targetCalendar,
6268
 
                        TimeZone tz,
6269
 
                        boolean rollForward) throws java.sql.SQLException {
6270
 
                if (this.isBinaryEncoded) {
6271
 
                        return getNativeTimestamp(columnIndex, targetCalendar, tz, rollForward);
6272
 
                }
6273
 
 
6274
 
                String timestampValue = getStringInternal(columnIndex, false);
6275
 
 
6276
 
                return getTimestampFromString(columnIndex, targetCalendar, 
6277
 
                                timestampValue, tz,
6278
 
                                rollForward);
6279
 
        }
6280
 
 
6281
 
        /**
6282
 
         * JDBC 2.0 Return the type of this result set. The type is determined based
6283
 
         * on the statement that created the result set.
6284
 
         * 
6285
 
         * @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
6286
 
         *         TYPE_SCROLL_SENSITIVE
6287
 
         * 
6288
 
         * @exception SQLException
6289
 
         *                if a database-access error occurs
6290
 
         */
6291
 
        public int getType() throws SQLException {
6292
 
                return this.resultSetType;
6293
 
        }
6294
 
 
6295
 
        /**
6296
 
         * A column value can also be retrieved as a stream of Unicode characters.
6297
 
         * We implement this as a binary stream.
6298
 
         * 
6299
 
         * @param columnIndex
6300
 
         *            the first column is 1, the second is 2...
6301
 
         * 
6302
 
         * @return a Java InputStream that delivers the database column value as a
6303
 
         *         stream of two byte Unicode characters. If the value is SQL NULL,
6304
 
         *         then the result is null
6305
 
         * 
6306
 
         * @exception SQLException
6307
 
         *                if a database access error occurs
6308
 
         * 
6309
 
         * @see getAsciiStream
6310
 
         * @see getBinaryStream
6311
 
         * @deprecated
6312
 
         */
6313
 
        public InputStream getUnicodeStream(int columnIndex) throws SQLException {
6314
 
                if (!this.isBinaryEncoded) {
6315
 
                        checkRowPos();
6316
 
 
6317
 
                        return getBinaryStream(columnIndex);
6318
 
                }
6319
 
 
6320
 
                return getNativeBinaryStream(columnIndex);
6321
 
        }
6322
 
 
6323
 
        /**
6324
 
         * DOCUMENT ME!
6325
 
         * 
6326
 
         * @param columnName
6327
 
         *            DOCUMENT ME!
6328
 
         * 
6329
 
         * @return DOCUMENT ME!
6330
 
         * 
6331
 
         * @throws SQLException
6332
 
         *             DOCUMENT ME!
6333
 
         * 
6334
 
         * @deprecated
6335
 
         */
6336
 
        public InputStream getUnicodeStream(String columnName) throws SQLException {
6337
 
                return getUnicodeStream(findColumn(columnName));
6338
 
        }
6339
 
 
6340
 
        long getUpdateCount() {
6341
 
                return this.updateCount;
6342
 
        }
6343
 
 
6344
 
        long getUpdateID() {
6345
 
                return this.updateId;
6346
 
        }
6347
 
 
6348
 
        /**
6349
 
         * @see ResultSet#getURL(int)
6350
 
         */
6351
 
        public URL getURL(int colIndex) throws SQLException {
6352
 
                String val = getString(colIndex);
6353
 
 
6354
 
                if (val == null) {
6355
 
                        return null;
6356
 
                }
6357
 
 
6358
 
                try {
6359
 
                        return new URL(val);
6360
 
                } catch (MalformedURLException mfe) {
6361
 
                        throw SQLError.createSQLException(Messages
6362
 
                                        .getString("ResultSet.Malformed_URL____104")
6363
 
                                        + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
6364
 
                }
6365
 
        }
6366
 
 
6367
 
        /**
6368
 
         * @see ResultSet#getURL(String)
6369
 
         */
6370
 
        public URL getURL(String colName) throws SQLException {
6371
 
                String val = getString(colName);
6372
 
 
6373
 
                if (val == null) {
6374
 
                        return null;
6375
 
                }
6376
 
 
6377
 
                try {
6378
 
                        return new URL(val);
6379
 
                } catch (MalformedURLException mfe) {
6380
 
                        throw SQLError.createSQLException(Messages
6381
 
                                        .getString("ResultSet.Malformed_URL____107")
6382
 
                                        + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
6383
 
                }
6384
 
        }
6385
 
 
6386
 
        /**
6387
 
         * The first warning reported by calls on this ResultSet is returned.
6388
 
         * Subsequent ResultSet warnings will be chained to this
6389
 
         * java.sql.SQLWarning.
6390
 
         * 
6391
 
         * <p>
6392
 
         * The warning chain is automatically cleared each time a new row is read.
6393
 
         * </p>
6394
 
         * 
6395
 
         * <p>
6396
 
         * <B>Note:</B> This warning chain only covers warnings caused by ResultSet
6397
 
         * methods. Any warnings caused by statement methods (such as reading OUT
6398
 
         * parameters) will be chained on the Statement object.
6399
 
         * </p>
6400
 
         * 
6401
 
         * @return the first java.sql.SQLWarning or null;
6402
 
         * 
6403
 
         * @exception SQLException
6404
 
         *                if a database access error occurs.
6405
 
         */
6406
 
        public java.sql.SQLWarning getWarnings() throws SQLException {
6407
 
                return this.warningChain;
6408
 
        }
6409
 
 
6410
 
        /**
6411
 
         * JDBC 2.0 Insert the contents of the insert row into the result set and
6412
 
         * the database. Must be on the insert row when this method is called.
6413
 
         * 
6414
 
         * @exception SQLException
6415
 
         *                if a database-access error occurs, if called when not on
6416
 
         *                the insert row, or if all non-nullable columns in the
6417
 
         *                insert row have not been given a value
6418
 
         * @throws NotUpdatable
6419
 
         *             DOCUMENT ME!
6420
 
         */
6421
 
        public void insertRow() throws SQLException {
6422
 
                throw new NotUpdatable();
6423
 
        }
6424
 
 
6425
 
        /**
6426
 
         * JDBC 2.0
6427
 
         * 
6428
 
         * <p>
6429
 
         * Determine if the cursor is after the last row in the result set.
6430
 
         * </p>
6431
 
         * 
6432
 
         * @return true if after the last row, false otherwise. Returns false when
6433
 
         *         the result set contains no rows.
6434
 
         * 
6435
 
         * @exception SQLException
6436
 
         *                if a database-access error occurs.
6437
 
         */
6438
 
        public boolean isAfterLast() throws SQLException {
6439
 
                checkClosed();
6440
 
 
6441
 
                boolean b = this.rowData.isAfterLast();
6442
 
 
6443
 
                return b;
6444
 
        }
6445
 
 
6446
 
        /**
6447
 
         * JDBC 2.0
6448
 
         * 
6449
 
         * <p>
6450
 
         * Determine if the cursor is before the first row in the result set.
6451
 
         * </p>
6452
 
         * 
6453
 
         * @return true if before the first row, false otherwise. Returns false when
6454
 
         *         the result set contains no rows.
6455
 
         * 
6456
 
         * @exception SQLException
6457
 
         *                if a database-access error occurs.
6458
 
         */
6459
 
        public boolean isBeforeFirst() throws SQLException {
6460
 
                checkClosed();
6461
 
 
6462
 
                return this.rowData.isBeforeFirst();
6463
 
        }
6464
 
 
6465
 
        /**
6466
 
         * JDBC 2.0
6467
 
         * 
6468
 
         * <p>
6469
 
         * Determine if the cursor is on the first row of the result set.
6470
 
         * </p>
6471
 
         * 
6472
 
         * @return true if on the first row, false otherwise.
6473
 
         * 
6474
 
         * @exception SQLException
6475
 
         *                if a database-access error occurs.
6476
 
         */
6477
 
        public boolean isFirst() throws SQLException {
6478
 
                checkClosed();
6479
 
 
6480
 
                return this.rowData.isFirst();
6481
 
        }
6482
 
 
6483
 
        /**
6484
 
         * JDBC 2.0
6485
 
         * 
6486
 
         * <p>
6487
 
         * Determine if the cursor is on the last row of the result set. Note:
6488
 
         * Calling isLast() may be expensive since the JDBC driver might need to
6489
 
         * fetch ahead one row in order to determine whether the current row is the
6490
 
         * last row in the result set.
6491
 
         * </p>
6492
 
         * 
6493
 
         * @return true if on the last row, false otherwise.
6494
 
         * 
6495
 
         * @exception SQLException
6496
 
         *                if a database-access error occurs.
6497
 
         */
6498
 
        public boolean isLast() throws SQLException {
6499
 
                checkClosed();
6500
 
 
6501
 
                return this.rowData.isLast();
6502
 
        }
6503
 
 
6504
 
        /**
6505
 
         * @param string
6506
 
         * @param mysqlType
6507
 
         * @param s
6508
 
         */
6509
 
        private void issueConversionViaParsingWarning(String methodName,
6510
 
                        int columnIndex, Object value, Field fieldInfo,
6511
 
                        int[] typesWithNoParseConversion) throws SQLException {
6512
 
                StringBuffer message = new StringBuffer();
6513
 
                message
6514
 
                                .append("ResultSet type conversion via parsing detected when calling ");
6515
 
                message.append(methodName);
6516
 
                message.append(" for column ");
6517
 
                message.append((columnIndex + 1));
6518
 
                message.append(", (column named '");
6519
 
                message.append(fieldInfo.getOriginalName());
6520
 
                message.append("' in table '");
6521
 
                message.append(fieldInfo.getOriginalTableName());
6522
 
                if (this.owningStatement != null
6523
 
                                && this.owningStatement instanceof com.mysql.jdbc.PreparedStatement) {
6524
 
                        message.append("' created from query:\n\n");
6525
 
                        message
6526
 
                                        .append(((com.mysql.jdbc.PreparedStatement) this.owningStatement).originalSql);
6527
 
                        message.append("\n\n");
6528
 
                } else {
6529
 
                        message.append(". ");
6530
 
                }
6531
 
 
6532
 
                message.append("Java class of column type is '");
6533
 
                
6534
 
                if (value != null) {
6535
 
                        message.append(value.getClass().getName());
6536
 
                } else {
6537
 
                        message.append(ResultSetMetaData.getClassNameForJavaType(fieldInfo.getSQLType(), 
6538
 
                                        fieldInfo.isUnsigned(), 
6539
 
                                        fieldInfo.getMysqlType(), 
6540
 
                                        fieldInfo.isBinary() || fieldInfo.isBlob(),
6541
 
                                        fieldInfo.isOpaqueBinary()));
6542
 
                }
6543
 
                
6544
 
                message.append("', MySQL field type is ");
6545
 
                message.append(MysqlDefs.typeToName(fieldInfo.getMysqlType()));
6546
 
                message
6547
 
                                .append(".\n\nTypes that could be converted directly without parsing are:\n");
6548
 
 
6549
 
                for (int i = 0; i < typesWithNoParseConversion.length; i++) {
6550
 
                        message.append(MysqlDefs.typeToName(typesWithNoParseConversion[i]));
6551
 
                        message.append("\n");
6552
 
                }
6553
 
 
6554
 
                this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN,
6555
 
                                "", (this.owningStatement == null) ? "N/A"
6556
 
                                                : this.owningStatement.currentCatalog, 
6557
 
                                                this.connectionId, (this.owningStatement == null) ? (-1)
6558
 
                                                : this.owningStatement.getId(), this.resultId, System
6559
 
                                                .currentTimeMillis(), 0, null, this.pointOfOrigin,
6560
 
                                message.toString()));
6561
 
 
6562
 
        }
6563
 
 
6564
 
        private void issueDataTruncationWarningIfConfigured(int columnIndex,
6565
 
                        int readSize, int truncatedToSize) {
6566
 
                DataTruncation dt = new DataTruncation(columnIndex, false, true,
6567
 
                                readSize, truncatedToSize);
6568
 
        }
6569
 
 
6570
 
        /**
6571
 
         * JDBC 2.0
6572
 
         * 
6573
 
         * <p>
6574
 
         * Moves to the last row in the result set.
6575
 
         * </p>
6576
 
         * 
6577
 
         * @return true if on a valid row, false if no rows in the result set.
6578
 
         * 
6579
 
         * @exception SQLException
6580
 
         *                if a database-access error occurs, or result set type is
6581
 
         *                TYPE_FORWARD_ONLY.
6582
 
         */
6583
 
        public boolean last() throws SQLException {
6584
 
                checkClosed();
6585
 
 
6586
 
                if (this.rowData.size() == 0) {
6587
 
                        return false;
6588
 
                }
6589
 
 
6590
 
                if (this.onInsertRow) {
6591
 
                        this.onInsertRow = false;
6592
 
                }
6593
 
 
6594
 
                if (this.doingUpdates) {
6595
 
                        this.doingUpdates = false;
6596
 
                }
6597
 
 
6598
 
                this.rowData.beforeLast();
6599
 
                this.thisRow = this.rowData.next();
6600
 
 
6601
 
                return true;
6602
 
        }
6603
 
 
6604
 
        // /////////////////////////////////////////
6605
 
        //
6606
 
        // These number conversion routines save
6607
 
        // a ton of "new()s", especially for the heavily
6608
 
        // used getInt() and getDouble() methods
6609
 
        //
6610
 
        // /////////////////////////////////////////
6611
 
 
6612
 
        /**
6613
 
         * JDBC 2.0 Move the cursor to the remembered cursor position, usually the
6614
 
         * current row. Has no effect unless the cursor is on the insert row.
6615
 
         * 
6616
 
         * @exception SQLException
6617
 
         *                if a database-access error occurs, or the result set is
6618
 
         *                not updatable
6619
 
         * @throws NotUpdatable
6620
 
         *             DOCUMENT ME!
6621
 
         */
6622
 
        public void moveToCurrentRow() throws SQLException {
6623
 
                throw new NotUpdatable();
6624
 
        }
6625
 
 
6626
 
        /**
6627
 
         * JDBC 2.0 Move to the insert row. The current cursor position is
6628
 
         * remembered while the cursor is positioned on the insert row. The insert
6629
 
         * row is a special row associated with an updatable result set. It is
6630
 
         * essentially a buffer where a new row may be constructed by calling the
6631
 
         * updateXXX() methods prior to inserting the row into the result set. Only
6632
 
         * the updateXXX(), getXXX(), and insertRow() methods may be called when the
6633
 
         * cursor is on the insert row. All of the columns in a result set must be
6634
 
         * given a value each time this method is called before calling insertRow().
6635
 
         * UpdateXXX()must be called before getXXX() on a column.
6636
 
         * 
6637
 
         * @exception SQLException
6638
 
         *                if a database-access error occurs, or the result set is
6639
 
         *                not updatable
6640
 
         * @throws NotUpdatable
6641
 
         *             DOCUMENT ME!
6642
 
         */
6643
 
        public void moveToInsertRow() throws SQLException {
6644
 
                throw new NotUpdatable();
6645
 
        }
6646
 
 
6647
 
        /**
6648
 
         * A ResultSet is initially positioned before its first row, the first call
6649
 
         * to next makes the first row the current row; the second call makes the
6650
 
         * second row the current row, etc.
6651
 
         * 
6652
 
         * <p>
6653
 
         * If an input stream from the previous row is open, it is implicitly
6654
 
         * closed. The ResultSet's warning chain is cleared when a new row is read
6655
 
         * </p>
6656
 
         * 
6657
 
         * @return true if the new current is valid; false if there are no more rows
6658
 
         * 
6659
 
         * @exception SQLException
6660
 
         *                if a database access error occurs
6661
 
         */
6662
 
        public boolean next() throws SQLException {
6663
 
                checkClosed();
6664
 
 
6665
 
                if (this.onInsertRow) {
6666
 
                        this.onInsertRow = false;
6667
 
                }
6668
 
 
6669
 
                if (this.doingUpdates) {
6670
 
                        this.doingUpdates = false;
6671
 
                }
6672
 
 
6673
 
                boolean b;
6674
 
 
6675
 
                if (!reallyResult()) {
6676
 
                        throw SQLError.createSQLException(
6677
 
                                        Messages
6678
 
                                                        .getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
6679
 
                                        SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
6680
 
                }
6681
 
 
6682
 
                if (this.rowData.size() == 0) {
6683
 
                        b = false;
6684
 
                } else {
6685
 
                        if (!this.rowData.hasNext()) {
6686
 
                                // force scroll past end
6687
 
                                this.rowData.next();
6688
 
                                b = false;
6689
 
                        } else {
6690
 
                                clearWarnings();
6691
 
                                this.thisRow = this.rowData.next();
6692
 
                                b = true;
6693
 
                        }
6694
 
                }
6695
 
 
6696
 
                return b;
6697
 
        }
6698
 
 
6699
 
        private int parseIntAsDouble(int columnIndex, String val)
6700
 
                        throws NumberFormatException, SQLException {
6701
 
                if (val == null) {
6702
 
                        return 0;
6703
 
                }
6704
 
 
6705
 
                double valueAsDouble = Double.parseDouble(val);
6706
 
 
6707
 
                if (this.connection.getJdbcCompliantTruncationForReads()) {
6708
 
                        if (valueAsDouble < Integer.MIN_VALUE
6709
 
                                        || valueAsDouble > Integer.MAX_VALUE) {
6710
 
                                throwRangeException(String.valueOf(valueAsDouble), columnIndex,
6711
 
                                                Types.INTEGER);
6712
 
                        }
6713
 
                }
6714
 
 
6715
 
                return (int) valueAsDouble;
6716
 
        }
6717
 
 
6718
 
        private int parseIntWithOverflowCheck(int columnIndex, byte[] valueAsBytes,
6719
 
                        String valueAsString) throws NumberFormatException, SQLException {
6720
 
 
6721
 
                int intValue = 0;
6722
 
 
6723
 
                if (valueAsBytes == null && valueAsString == null) {
6724
 
                        return 0;
6725
 
                }
6726
 
 
6727
 
                if (valueAsBytes != null) {
6728
 
                        intValue = StringUtils.getInt(valueAsBytes);
6729
 
                } else {
6730
 
                        //
6731
 
                        // JDK-6 doesn't like trailing whitespace
6732
 
                        //
6733
 
                        // Note this isn't a performance issue, other
6734
 
                        // than the iteration over the string, as String.trim()
6735
 
                        // will return a new string only if whitespace is present
6736
 
                        //
6737
 
                        
6738
 
                        valueAsString = valueAsString.trim(); 
6739
 
                        
6740
 
                        intValue = Integer.parseInt(valueAsString);
6741
 
                }
6742
 
 
6743
 
                if (this.connection.getJdbcCompliantTruncationForReads()) {
6744
 
                        if (intValue == Integer.MIN_VALUE || intValue == Integer.MAX_VALUE) {
6745
 
                                long valueAsLong = Long
6746
 
                                                .parseLong(valueAsString == null ? new String(
6747
 
                                                                valueAsBytes) : valueAsString);
6748
 
 
6749
 
                                if (valueAsLong < Integer.MIN_VALUE
6750
 
                                                || valueAsLong > Integer.MAX_VALUE) {
6751
 
                                        throwRangeException(valueAsString == null ? new String(
6752
 
                                                        valueAsBytes) : valueAsString, columnIndex,
6753
 
                                                        Types.INTEGER);
6754
 
                                }
6755
 
                        }
6756
 
                }
6757
 
 
6758
 
                return intValue;
6759
 
        }
6760
 
 
6761
 
        private long parseLongAsDouble(int columnIndex, String val)
6762
 
                        throws NumberFormatException, SQLException {
6763
 
                if (val == null) {
6764
 
                        return 0;
6765
 
                }
6766
 
 
6767
 
                double valueAsDouble = Double.parseDouble(val);
6768
 
 
6769
 
                if (this.connection.getJdbcCompliantTruncationForReads()) {
6770
 
                        if (valueAsDouble < Long.MIN_VALUE
6771
 
                                        || valueAsDouble > Long.MAX_VALUE) {
6772
 
                                throwRangeException(val, columnIndex, Types.BIGINT);
6773
 
                        }
6774
 
                }
6775
 
 
6776
 
                return (long) valueAsDouble;
6777
 
        }
6778
 
 
6779
 
        private long parseLongWithOverflowCheck(int columnIndex,
6780
 
                        byte[] valueAsBytes, String valueAsString, boolean doCheck)
6781
 
                        throws NumberFormatException, SQLException {
6782
 
 
6783
 
                long longValue = 0;
6784
 
 
6785
 
                if (valueAsBytes == null && valueAsString == null) {
6786
 
                        return 0;
6787
 
                }
6788
 
 
6789
 
                if (valueAsBytes != null) {
6790
 
                        longValue = StringUtils.getLong(valueAsBytes);
6791
 
                } else {
6792
 
                        //
6793
 
                        // JDK-6 doesn't like trailing whitespace
6794
 
                        //
6795
 
                        // Note this isn't a performance issue, other
6796
 
                        // than the iteration over the string, as String.trim()
6797
 
                        // will return a new string only if whitespace is present
6798
 
                        //
6799
 
                        
6800
 
                        valueAsString = valueAsString.trim();
6801
 
                        
6802
 
                        longValue = Long.parseLong(valueAsString);
6803
 
                }
6804
 
 
6805
 
                if (doCheck && this.connection.getJdbcCompliantTruncationForReads()) {
6806
 
                        if (longValue == Long.MIN_VALUE
6807
 
                                        || longValue == Long.MAX_VALUE) {
6808
 
                                double valueAsDouble = Double
6809
 
                                                .parseDouble(valueAsString == null ? new String(
6810
 
                                                                valueAsBytes) : valueAsString);
6811
 
 
6812
 
                                if (valueAsDouble < Long.MIN_VALUE
6813
 
                                                || valueAsDouble > Long.MAX_VALUE) {
6814
 
                                        throwRangeException(valueAsString == null ? new String(
6815
 
                                                        valueAsBytes) : valueAsString, columnIndex,
6816
 
                                                        Types.BIGINT);
6817
 
                                }
6818
 
                        }
6819
 
                }
6820
 
 
6821
 
                return longValue;
6822
 
        }
6823
 
 
6824
 
        private short parseShortAsDouble(int columnIndex, String val)
6825
 
                        throws NumberFormatException, SQLException {
6826
 
                if (val == null) {
6827
 
                        return 0;
6828
 
                }
6829
 
 
6830
 
                double valueAsDouble = Double.parseDouble(val);
6831
 
 
6832
 
                if (this.connection.getJdbcCompliantTruncationForReads()) {
6833
 
                        if (valueAsDouble < Short.MIN_VALUE
6834
 
                                        || valueAsDouble > Short.MAX_VALUE) {
6835
 
                                throwRangeException(String.valueOf(valueAsDouble), columnIndex,
6836
 
                                                Types.SMALLINT);
6837
 
                        }
6838
 
                }
6839
 
 
6840
 
                return (short) valueAsDouble;
6841
 
        }
6842
 
 
6843
 
        private short parseShortWithOverflowCheck(int columnIndex,
6844
 
                        byte[] valueAsBytes, String valueAsString)
6845
 
                        throws NumberFormatException, SQLException {
6846
 
 
6847
 
                short shortValue = 0;
6848
 
 
6849
 
                if (valueAsBytes == null && valueAsString == null) {
6850
 
                        return 0;
6851
 
                }
6852
 
 
6853
 
                if (valueAsBytes != null) {
6854
 
                        shortValue = StringUtils.getShort(valueAsBytes);
6855
 
                } else {
6856
 
                        //
6857
 
                        // JDK-6 doesn't like trailing whitespace
6858
 
                        //
6859
 
                        // Note this isn't a performance issue, other
6860
 
                        // than the iteration over the string, as String.trim()
6861
 
                        // will return a new string only if whitespace is present
6862
 
                        //
6863
 
                        
6864
 
                        valueAsString = valueAsString.trim();
6865
 
                
6866
 
                        shortValue = Short.parseShort(valueAsString);
6867
 
                }
6868
 
 
6869
 
                if (this.connection.getJdbcCompliantTruncationForReads()) {
6870
 
                        if (shortValue == Short.MIN_VALUE || shortValue == Short.MAX_VALUE) {
6871
 
                                long valueAsLong = Long
6872
 
                                                .parseLong(valueAsString == null ? new String(
6873
 
                                                                valueAsBytes) : valueAsString);
6874
 
 
6875
 
                                if (valueAsLong < Short.MIN_VALUE
6876
 
                                                || valueAsLong > Short.MAX_VALUE) {
6877
 
                                        throwRangeException(valueAsString == null ? new String(
6878
 
                                                        valueAsBytes) : valueAsString, columnIndex,
6879
 
                                                        Types.SMALLINT);
6880
 
                                }
6881
 
                        }
6882
 
                }
6883
 
 
6884
 
                return shortValue;
6885
 
        }
6886
 
 
6887
 
        // --------------------------JDBC 2.0-----------------------------------
6888
 
        // ---------------------------------------------------------------------
6889
 
        // Getter's and Setter's
6890
 
        // ---------------------------------------------------------------------
6891
 
 
6892
 
        /**
6893
 
         * The prev method is not part of JDBC, but because of the architecture of
6894
 
         * this driver it is possible to move both forward and backward within the
6895
 
         * result set.
6896
 
         * 
6897
 
         * <p>
6898
 
         * If an input stream from the previous row is open, it is implicitly
6899
 
         * closed. The ResultSet's warning chain is cleared when a new row is read
6900
 
         * </p>
6901
 
         * 
6902
 
         * @return true if the new current is valid; false if there are no more rows
6903
 
         * 
6904
 
         * @exception java.sql.SQLException
6905
 
         *                if a database access error occurs
6906
 
         */
6907
 
        public boolean prev() throws java.sql.SQLException {
6908
 
                checkClosed();
6909
 
 
6910
 
                int rowIndex = this.rowData.getCurrentRowNumber();
6911
 
 
6912
 
                if ((rowIndex - 1) >= 0) {
6913
 
                        rowIndex--;
6914
 
                        this.rowData.setCurrentRow(rowIndex);
6915
 
                        this.thisRow = this.rowData.getAt(rowIndex);
6916
 
 
6917
 
                        return true;
6918
 
                } else if ((rowIndex - 1) == -1) {
6919
 
                        rowIndex--;
6920
 
                        this.rowData.setCurrentRow(rowIndex);
6921
 
                        this.thisRow = null;
6922
 
 
6923
 
                        return false;
6924
 
                } else {
6925
 
                        return false;
6926
 
                }
6927
 
        }
6928
 
 
6929
 
        /**
6930
 
         * JDBC 2.0
6931
 
         * 
6932
 
         * <p>
6933
 
         * Moves to the previous row in the result set.
6934
 
         * </p>
6935
 
         * 
6936
 
         * <p>
6937
 
         * Note: previous() is not the same as relative(-1) since it makes sense to
6938
 
         * call previous() when there is no current row.
6939
 
         * </p>
6940
 
         * 
6941
 
         * @return true if on a valid row, false if off the result set.
6942
 
         * 
6943
 
         * @exception SQLException
6944
 
         *                if a database-access error occurs, or result set type is
6945
 
         *                TYPE_FORWAR_DONLY.
6946
 
         */
6947
 
        public boolean previous() throws SQLException {
6948
 
                if (this.onInsertRow) {
6949
 
                        this.onInsertRow = false;
6950
 
                }
6951
 
 
6952
 
                if (this.doingUpdates) {
6953
 
                        this.doingUpdates = false;
6954
 
                }
6955
 
 
6956
 
                return prev();
6957
 
        }
6958
 
 
6959
 
        /**
6960
 
         * Closes this ResultSet and releases resources.
6961
 
         * 
6962
 
         * @param calledExplicitly
6963
 
         *            was this called by close()?
6964
 
         * 
6965
 
         * @throws SQLException
6966
 
         *             if an error occurs
6967
 
         */
6968
 
        protected void realClose(boolean calledExplicitly) throws SQLException {
6969
 
                if (this.isClosed) {
6970
 
                        return;
6971
 
                }
6972
 
 
6973
 
                try {
6974
 
                        if (this.useUsageAdvisor) {
6975
 
                                if (!calledExplicitly) {
6976
 
                                        String message = Messages
6977
 
                                                        .getString("ResultSet.ResultSet_implicitly_closed_by_driver._150") //$NON-NLS-1$
6978
 
                                                        + Messages
6979
 
                                                                        .getString("ResultSet._n_nYou_should_close_ResultSets_explicitly_from_your_code_to_free_up_resources_in_a_more_efficient_manner._151"); //$NON-NLS-1$
6980
 
 
6981
 
                                        this.eventSink.consumeEvent(new ProfilerEvent(
6982
 
                                                        ProfilerEvent.TYPE_WARN, "",
6983
 
                                                        (this.owningStatement == null) ? "N/A"
6984
 
                                                                        : this.owningStatement.currentCatalog,
6985
 
                                                        this.connectionId,
6986
 
                                                        (this.owningStatement == null) ? (-1)
6987
 
                                                                        : this.owningStatement.getId(),
6988
 
                                                        this.resultId, System.currentTimeMillis(), 0, null,
6989
 
                                                        this.pointOfOrigin, message));
6990
 
                                }
6991
 
 
6992
 
                                if (this.rowData instanceof RowDataStatic && !isLast()
6993
 
                                                && !isAfterLast() && (this.rowData.size() != 0)) {
6994
 
                                        StringBuffer messageBuf = new StringBuffer(
6995
 
                                                        Messages
6996
 
                                                                        .getString("ResultSet.Possible_incomplete_traversal_of_result_set._Cursor_was_left_on_row__154")); //$NON-NLS-1$
6997
 
                                        messageBuf.append(getRow());
6998
 
                                        messageBuf.append(Messages.getString("ResultSet._of__155")); //$NON-NLS-1$
6999
 
                                        messageBuf.append(this.rowData.size());
7000
 
                                        messageBuf
7001
 
                                                        .append(Messages
7002
 
                                                                        .getString("ResultSet._rows_when_it_was_closed._156")); //$NON-NLS-1$
7003
 
                                        messageBuf
7004
 
                                                        .append(Messages
7005
 
                                                                        .getString("ResultSet._n_nYou_should_consider_re-formulating_your_query_to_return_only_the_rows_you_are_interested_in_using._157")); //$NON-NLS-1$
7006
 
 
7007
 
                                        this.eventSink.consumeEvent(new ProfilerEvent(
7008
 
                                                        ProfilerEvent.TYPE_WARN, "",
7009
 
                                                        (this.owningStatement == null) ? Messages
7010
 
                                                                        .getString("ResultSet.N/A_159")
7011
 
                                                                        : this.owningStatement.currentCatalog, //$NON-NLS-1$
7012
 
                                                        this.connectionId,
7013
 
                                                        (this.owningStatement == null) ? (-1)
7014
 
                                                                        : this.owningStatement.getId(),
7015
 
                                                        this.resultId, System.currentTimeMillis(), 0, null,
7016
 
                                                        this.pointOfOrigin, messageBuf.toString()));
7017
 
                                }
7018
 
 
7019
 
                                //
7020
 
                                // Report on any columns that were selected but
7021
 
                                // not referenced
7022
 
                                //
7023
 
                                if (this.columnUsed.length > 0) {
7024
 
                                        StringBuffer buf = new StringBuffer(
7025
 
                                                        Messages
7026
 
                                                                        .getString("ResultSet.The_following_columns_were__160")); //$NON-NLS-1$
7027
 
                                        buf
7028
 
                                                        .append(Messages
7029
 
                                                                        .getString("ResultSet._part_of_the_SELECT_statement_for_this_result_set,_but_were_161")); //$NON-NLS-1$
7030
 
                                        buf.append(Messages
7031
 
                                                        .getString("ResultSet._never_referenced___162")); //$NON-NLS-1$
7032
 
 
7033
 
                                        boolean issueWarn = false;
7034
 
 
7035
 
                                        for (int i = 0; i < this.columnUsed.length; i++) {
7036
 
                                                if (!this.columnUsed[i]) {
7037
 
                                                        if (!issueWarn) {
7038
 
                                                                issueWarn = true;
7039
 
                                                        } else {
7040
 
                                                                buf.append(", ");
7041
 
                                                        }
7042
 
 
7043
 
                                                        buf.append(this.fields[i].getFullName());
7044
 
                                                }
7045
 
                                        }
7046
 
 
7047
 
                                        if (issueWarn) {
7048
 
                                                this.eventSink.consumeEvent(new ProfilerEvent(
7049
 
                                                                ProfilerEvent.TYPE_WARN, "",
7050
 
                                                                (this.owningStatement == null) ? "N/A"
7051
 
                                                                                : this.owningStatement.currentCatalog,
7052
 
                                                                this.connectionId,
7053
 
                                                                (this.owningStatement == null) ? (-1)
7054
 
                                                                                : this.owningStatement.getId(), 0,
7055
 
                                                                System.currentTimeMillis(), 0, null,
7056
 
                                                                this.pointOfOrigin, buf.toString()));
7057
 
                                        }
7058
 
                                }
7059
 
                        }
7060
 
                } finally {
7061
 
                        SQLException exceptionDuringClose = null;
7062
 
 
7063
 
                        if (this.rowData != null) {
7064
 
                                try {
7065
 
                                        this.rowData.close();
7066
 
                                } catch (SQLException sqlEx) {
7067
 
                                        exceptionDuringClose = sqlEx;
7068
 
                                }
7069
 
                        }
7070
 
 
7071
 
                        this.rowData = null;
7072
 
                        this.defaultTimeZone = null;
7073
 
                        this.fields = null;
7074
 
                        this.columnNameToIndex = null;
7075
 
                        this.fullColumnNameToIndex = null;
7076
 
                        this.eventSink = null;
7077
 
                        this.warningChain = null;
7078
 
                        
7079
 
                        if (!this.retainOwningStatement) {
7080
 
                                this.owningStatement = null;
7081
 
                        }
7082
 
                        
7083
 
                        this.catalog = null;
7084
 
                        this.serverInfo = null;
7085
 
                        this.thisRow = null;
7086
 
                        this.fastDateCal = null;
7087
 
                        this.connection = null;
7088
 
 
7089
 
                        this.isClosed = true;
7090
 
 
7091
 
                        if (exceptionDuringClose != null) {
7092
 
                                throw exceptionDuringClose;
7093
 
                        }
7094
 
                }
7095
 
        }
7096
 
 
7097
 
        boolean reallyResult() {
7098
 
                if (this.rowData != null) {
7099
 
                        return true;
7100
 
                }
7101
 
 
7102
 
                return this.reallyResult;
7103
 
        }
7104
 
 
7105
 
        /**
7106
 
         * JDBC 2.0 Refresh the value of the current row with its current value in
7107
 
         * the database. Cannot be called when on the insert row. The refreshRow()
7108
 
         * method provides a way for an application to explicitly tell the JDBC
7109
 
         * driver to refetch a row(s) from the database. An application may want to
7110
 
         * call refreshRow() when caching or prefetching is being done by the JDBC
7111
 
         * driver to fetch the latest value of a row from the database. The JDBC
7112
 
         * driver may actually refresh multiple rows at once if the fetch size is
7113
 
         * greater than one. All values are refetched subject to the transaction
7114
 
         * isolation level and cursor sensitivity. If refreshRow() is called after
7115
 
         * calling updateXXX(), but before calling updateRow() then the updates made
7116
 
         * to the row are lost. Calling refreshRow() frequently will likely slow
7117
 
         * performance.
7118
 
         * 
7119
 
         * @exception SQLException
7120
 
         *                if a database-access error occurs, or if called when on
7121
 
         *                the insert row.
7122
 
         * @throws NotUpdatable
7123
 
         *             DOCUMENT ME!
7124
 
         */
7125
 
        public void refreshRow() throws SQLException {
7126
 
                throw new NotUpdatable();
7127
 
        }
7128
 
 
7129
 
        /**
7130
 
         * JDBC 2.0
7131
 
         * 
7132
 
         * <p>
7133
 
         * Moves a relative number of rows, either positive or negative. Attempting
7134
 
         * to move beyond the first/last row in the result set positions the cursor
7135
 
         * before/after the the first/last row. Calling relative(0) is valid, but
7136
 
         * does not change the cursor position.
7137
 
         * </p>
7138
 
         * 
7139
 
         * <p>
7140
 
         * Note: Calling relative(1) is different than calling next() since is makes
7141
 
         * sense to call next() when there is no current row, for example, when the
7142
 
         * cursor is positioned before the first row or after the last row of the
7143
 
         * result set.
7144
 
         * </p>
7145
 
         * 
7146
 
         * @param rows
7147
 
         *            the number of relative rows to move the cursor.
7148
 
         * 
7149
 
         * @return true if on a row, false otherwise.
7150
 
         * 
7151
 
         * @throws SQLException
7152
 
         *             if a database-access error occurs, or there is no current
7153
 
         *             row, or result set type is TYPE_FORWARD_ONLY.
7154
 
         */
7155
 
        public boolean relative(int rows) throws SQLException {
7156
 
                checkClosed();
7157
 
 
7158
 
                if (this.rowData.size() == 0) {
7159
 
                        return false;
7160
 
                }
7161
 
 
7162
 
                this.rowData.moveRowRelative(rows);
7163
 
                this.thisRow = this.rowData.getAt(this.rowData.getCurrentRowNumber());
7164
 
 
7165
 
                return (!this.rowData.isAfterLast() && !this.rowData.isBeforeFirst());
7166
 
        }
7167
 
 
7168
 
        /**
7169
 
         * JDBC 2.0 Determine if this row has been deleted. A deleted row may leave
7170
 
         * a visible "hole" in a result set. This method can be used to detect holes
7171
 
         * in a result set. The value returned depends on whether or not the result
7172
 
         * set can detect deletions.
7173
 
         * 
7174
 
         * @return true if deleted and deletes are detected
7175
 
         * 
7176
 
         * @exception SQLException
7177
 
         *                if a database-access error occurs
7178
 
         * @throws NotImplemented
7179
 
         *             DOCUMENT ME!
7180
 
         * 
7181
 
         * @see DatabaseMetaData#deletesAreDetected
7182
 
         */
7183
 
        public boolean rowDeleted() throws SQLException {
7184
 
                throw new NotImplemented();
7185
 
        }
7186
 
 
7187
 
        /**
7188
 
         * JDBC 2.0 Determine if the current row has been inserted. The value
7189
 
         * returned depends on whether or not the result set can detect visible
7190
 
         * inserts.
7191
 
         * 
7192
 
         * @return true if inserted and inserts are detected
7193
 
         * 
7194
 
         * @exception SQLException
7195
 
         *                if a database-access error occurs
7196
 
         * @throws NotImplemented
7197
 
         *             DOCUMENT ME!
7198
 
         * 
7199
 
         * @see DatabaseMetaData#insertsAreDetected
7200
 
         */
7201
 
        public boolean rowInserted() throws SQLException {
7202
 
                throw new NotImplemented();
7203
 
        }
7204
 
 
7205
 
        /**
7206
 
         * JDBC 2.0 Determine if the current row has been updated. The value
7207
 
         * returned depends on whether or not the result set can detect updates.
7208
 
         * 
7209
 
         * @return true if the row has been visibly updated by the owner or another,
7210
 
         *         and updates are detected
7211
 
         * 
7212
 
         * @exception SQLException
7213
 
         *                if a database-access error occurs
7214
 
         * @throws NotImplemented
7215
 
         *             DOCUMENT ME!
7216
 
         * 
7217
 
         * @see DatabaseMetaData#updatesAreDetected
7218
 
         */
7219
 
        public boolean rowUpdated() throws SQLException {
7220
 
                throw new NotImplemented();
7221
 
        }
7222
 
 
7223
 
        /**
7224
 
         * Flag that this result set is 'binary' encoded (from a PreparedStatement),
7225
 
         * not stored as strings.
7226
 
         */
7227
 
        protected void setBinaryEncoded() {
7228
 
                this.isBinaryEncoded = true;
7229
 
        }
7230
 
 
7231
 
        private void setDefaultTimeZone(TimeZone defaultTimeZone) {
7232
 
                this.defaultTimeZone = defaultTimeZone;
7233
 
        }
7234
 
 
7235
 
        /**
7236
 
         * JDBC 2.0 Give a hint as to the direction in which the rows in this result
7237
 
         * set will be processed. The initial value is determined by the statement
7238
 
         * that produced the result set. The fetch direction may be changed at any
7239
 
         * time.
7240
 
         * 
7241
 
         * @param direction
7242
 
         *            the direction to fetch rows in.
7243
 
         * 
7244
 
         * @exception SQLException
7245
 
         *                if a database-access error occurs, or the result set type
7246
 
         *                is TYPE_FORWARD_ONLY and direction is not FETCH_FORWARD.
7247
 
         *                MM.MySQL actually ignores this, because it has the whole
7248
 
         *                result set anyway, so the direction is immaterial.
7249
 
         */
7250
 
        public void setFetchDirection(int direction) throws SQLException {
7251
 
                if ((direction != FETCH_FORWARD) && (direction != FETCH_REVERSE)
7252
 
                                && (direction != FETCH_UNKNOWN)) {
7253
 
                        throw SQLError.createSQLException(
7254
 
                                        Messages
7255
 
                                                        .getString("ResultSet.Illegal_value_for_fetch_direction_64"),
7256
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
7257
 
                }
7258
 
 
7259
 
                this.fetchDirection = direction;
7260
 
        }
7261
 
 
7262
 
        /**
7263
 
         * JDBC 2.0 Give the JDBC driver a hint as to the number of rows that should
7264
 
         * be fetched from the database when more rows are needed for this result
7265
 
         * set. If the fetch size specified is zero, then the JDBC driver ignores
7266
 
         * the value, and is free to make its own best guess as to what the fetch
7267
 
         * size should be. The default value is set by the statement that creates
7268
 
         * the result set. The fetch size may be changed at any time.
7269
 
         * 
7270
 
         * @param rows
7271
 
         *            the number of rows to fetch
7272
 
         * 
7273
 
         * @exception SQLException
7274
 
         *                if a database-access error occurs, or the condition 0 lteq
7275
 
         *                rows lteq this.getMaxRows() is not satisfied. Currently
7276
 
         *                ignored by this driver.
7277
 
         */
7278
 
        public void setFetchSize(int rows) throws SQLException {
7279
 
                if (rows < 0) { /* || rows > getMaxRows() */
7280
 
                        throw SQLError.createSQLException(
7281
 
                                        Messages
7282
 
                                                        .getString("ResultSet.Value_must_be_between_0_and_getMaxRows()_66"), //$NON-NLS-1$
7283
 
                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
7284
 
                }
7285
 
 
7286
 
                this.fetchSize = rows;
7287
 
        }
7288
 
 
7289
 
        /**
7290
 
         * Sets the first character of the query that this result set was created
7291
 
         * from.
7292
 
         * 
7293
 
         * @param c
7294
 
         *            the first character of the query...uppercased
7295
 
         */
7296
 
        protected void setFirstCharOfQuery(char c) {
7297
 
                this.firstCharOfQuery = c;
7298
 
        }
7299
 
 
7300
 
        /**
7301
 
         * DOCUMENT ME!
7302
 
         * 
7303
 
         * @param nextResultSet
7304
 
         *            Sets the next result set in the result set chain for multiple
7305
 
         *            result sets.
7306
 
         */
7307
 
        protected void setNextResultSet(ResultSet nextResultSet) {
7308
 
                this.nextResultSet = nextResultSet;
7309
 
        }
7310
 
 
7311
 
        protected void setOwningStatement(com.mysql.jdbc.Statement owningStatement) {
7312
 
                this.owningStatement = owningStatement;
7313
 
        }
7314
 
 
7315
 
        /**
7316
 
         * Sets the concurrency (JDBC2)
7317
 
         * 
7318
 
         * @param concurrencyFlag
7319
 
         *            CONCUR_UPDATABLE or CONCUR_READONLY
7320
 
         */
7321
 
        protected void setResultSetConcurrency(int concurrencyFlag) {
7322
 
                this.resultSetConcurrency = concurrencyFlag;
7323
 
        }
7324
 
 
7325
 
        /**
7326
 
         * Sets the result set type for (JDBC2)
7327
 
         * 
7328
 
         * @param typeFlag
7329
 
         *            SCROLL_SENSITIVE or SCROLL_INSENSITIVE (we only support
7330
 
         *            SCROLL_INSENSITIVE)
7331
 
         */
7332
 
        protected void setResultSetType(int typeFlag) {
7333
 
                this.resultSetType = typeFlag;
7334
 
        }
7335
 
 
7336
 
        /**
7337
 
         * Sets server info (if any)
7338
 
         * 
7339
 
         * @param info
7340
 
         *            the server info message
7341
 
         */
7342
 
        protected void setServerInfo(String info) {
7343
 
                this.serverInfo = info;
7344
 
        }
7345
 
 
7346
 
        void setStatementUsedForFetchingRows(PreparedStatement stmt) {
7347
 
                this.statementUsedForFetchingRows = stmt;
7348
 
        }
7349
 
 
7350
 
        /**
7351
 
         * @param wrapperStatement
7352
 
         *            The wrapperStatement to set.
7353
 
         */
7354
 
        public void setWrapperStatement(java.sql.Statement wrapperStatement) {
7355
 
                this.wrapperStatement = wrapperStatement;
7356
 
        }
7357
 
 
7358
 
        private void throwRangeException(String valueAsString, int columnIndex,
7359
 
                        int jdbcType) throws SQLException {
7360
 
                String datatype = null;
7361
 
 
7362
 
                switch (jdbcType) {
7363
 
                case Types.TINYINT:
7364
 
                        datatype = "TINYINT";
7365
 
                        break;
7366
 
                case Types.SMALLINT:
7367
 
                        datatype = "SMALLINT";
7368
 
                        break;
7369
 
                case Types.INTEGER:
7370
 
                        datatype = "INTEGER";
7371
 
                        break;
7372
 
                case Types.BIGINT:
7373
 
                        datatype = "BIGINT";
7374
 
                        break;
7375
 
                case Types.REAL:
7376
 
                        datatype = "REAL";
7377
 
                        break;
7378
 
                case Types.FLOAT:
7379
 
                        datatype = "FLOAT";
7380
 
                        break;
7381
 
                case Types.DOUBLE:
7382
 
                        datatype = "DOUBLE";
7383
 
                        break;
7384
 
                case Types.DECIMAL:
7385
 
                        datatype = "DECIMAL";
7386
 
                        break;
7387
 
                default:
7388
 
                        datatype = " (JDBC type '" + jdbcType + "')";
7389
 
                }
7390
 
 
7391
 
                throw SQLError.createSQLException("'" + valueAsString + "' in column '"
7392
 
                                + columnIndex + "' is outside valid range for the datatype "
7393
 
                                + datatype + ".", SQLError.SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE);
7394
 
        }
7395
 
 
7396
 
        /**
7397
 
         * DOCUMENT ME!
7398
 
         * 
7399
 
         * @return DOCUMENT ME!
7400
 
         */
7401
 
        public String toString() {
7402
 
                if (this.reallyResult) {
7403
 
                        return super.toString();
7404
 
                }
7405
 
 
7406
 
                return "Result set representing update count of " + this.updateCount;
7407
 
        }
7408
 
 
7409
 
        /**
7410
 
         * @see ResultSet#updateArray(int, Array)
7411
 
         */
7412
 
        public void updateArray(int arg0, Array arg1) throws SQLException {
7413
 
                throw new NotImplemented();
7414
 
        }
7415
 
 
7416
 
        /**
7417
 
         * @see ResultSet#updateArray(String, Array)
7418
 
         */
7419
 
        public void updateArray(String arg0, Array arg1) throws SQLException {
7420
 
                throw new NotImplemented();
7421
 
        }
7422
 
 
7423
 
        /**
7424
 
         * JDBC 2.0 Update a column with an ascii stream value. The updateXXX()
7425
 
         * methods are used to update column values in the current row, or the
7426
 
         * insert row. The updateXXX() methods do not update the underlying
7427
 
         * database, instead the updateRow() or insertRow() methods are called to
7428
 
         * update the database.
7429
 
         * 
7430
 
         * @param columnIndex
7431
 
         *            the first column is 1, the second is 2, ...
7432
 
         * @param x
7433
 
         *            the new column value
7434
 
         * @param length
7435
 
         *            the length of the stream
7436
 
         * 
7437
 
         * @exception SQLException
7438
 
         *                if a database-access error occurs
7439
 
         * @throws NotUpdatable
7440
 
         *             DOCUMENT ME!
7441
 
         */
7442
 
        public void updateAsciiStream(int columnIndex, java.io.InputStream x,
7443
 
                        int length) throws SQLException {
7444
 
                throw new NotUpdatable();
7445
 
        }
7446
 
 
7447
 
        /**
7448
 
         * JDBC 2.0 Update a column with an ascii stream value. The updateXXX()
7449
 
         * methods are used to update column values in the current row, or the
7450
 
         * insert row. The updateXXX() methods do not update the underlying
7451
 
         * database, instead the updateRow() or insertRow() methods are called to
7452
 
         * update the database.
7453
 
         * 
7454
 
         * @param columnName
7455
 
         *            the name of the column
7456
 
         * @param x
7457
 
         *            the new column value
7458
 
         * @param length
7459
 
         *            of the stream
7460
 
         * 
7461
 
         * @exception SQLException
7462
 
         *                if a database-access error occurs
7463
 
         */
7464
 
        public void updateAsciiStream(String columnName, java.io.InputStream x,
7465
 
                        int length) throws SQLException {
7466
 
                updateAsciiStream(findColumn(columnName), x, length);
7467
 
        }
7468
 
 
7469
 
        /**
7470
 
         * JDBC 2.0 Update a column with a BigDecimal value. The updateXXX() methods
7471
 
         * are used to update column values in the current row, or the insert row.
7472
 
         * The updateXXX() methods do not update the underlying database, instead
7473
 
         * the updateRow() or insertRow() methods are called to update the database.
7474
 
         * 
7475
 
         * @param columnIndex
7476
 
         *            the first column is 1, the second is 2, ...
7477
 
         * @param x
7478
 
         *            the new column value
7479
 
         * 
7480
 
         * @exception SQLException
7481
 
         *                if a database-access error occurs
7482
 
         * @throws NotUpdatable
7483
 
         *             DOCUMENT ME!
7484
 
         */
7485
 
        public void updateBigDecimal(int columnIndex, BigDecimal x)
7486
 
                        throws SQLException {
7487
 
                throw new NotUpdatable();
7488
 
        }
7489
 
 
7490
 
        /**
7491
 
         * JDBC 2.0 Update a column with a BigDecimal value. The updateXXX() methods
7492
 
         * are used to update column values in the current row, or the insert row.
7493
 
         * The updateXXX() methods do not update the underlying database, instead
7494
 
         * the updateRow() or insertRow() methods are called to update the database.
7495
 
         * 
7496
 
         * @param columnName
7497
 
         *            the name of the column
7498
 
         * @param x
7499
 
         *            the new column value
7500
 
         * 
7501
 
         * @exception SQLException
7502
 
         *                if a database-access error occurs
7503
 
         */
7504
 
        public void updateBigDecimal(String columnName, BigDecimal x)
7505
 
                        throws SQLException {
7506
 
                updateBigDecimal(findColumn(columnName), x);
7507
 
        }
7508
 
 
7509
 
        /**
7510
 
         * JDBC 2.0 Update a column with a binary stream value. The updateXXX()
7511
 
         * methods are used to update column values in the current row, or the
7512
 
         * insert row. The updateXXX() methods do not update the underlying
7513
 
         * database, instead the updateRow() or insertRow() methods are called to
7514
 
         * update the database.
7515
 
         * 
7516
 
         * @param columnIndex
7517
 
         *            the first column is 1, the second is 2, ...
7518
 
         * @param x
7519
 
         *            the new column value
7520
 
         * @param length
7521
 
         *            the length of the stream
7522
 
         * 
7523
 
         * @exception SQLException
7524
 
         *                if a database-access error occurs
7525
 
         * @throws NotUpdatable
7526
 
         *             DOCUMENT ME!
7527
 
         */
7528
 
        public void updateBinaryStream(int columnIndex, java.io.InputStream x,
7529
 
                        int length) throws SQLException {
7530
 
                throw new NotUpdatable();
7531
 
        }
7532
 
 
7533
 
        /**
7534
 
         * JDBC 2.0 Update a column with a binary stream value. The updateXXX()
7535
 
         * methods are used to update column values in the current row, or the
7536
 
         * insert row. The updateXXX() methods do not update the underlying
7537
 
         * database, instead the updateRow() or insertRow() methods are called to
7538
 
         * update the database.
7539
 
         * 
7540
 
         * @param columnName
7541
 
         *            the name of the column
7542
 
         * @param x
7543
 
         *            the new column value
7544
 
         * @param length
7545
 
         *            of the stream
7546
 
         * 
7547
 
         * @exception SQLException
7548
 
         *                if a database-access error occurs
7549
 
         */
7550
 
        public void updateBinaryStream(String columnName, java.io.InputStream x,
7551
 
                        int length) throws SQLException {
7552
 
                updateBinaryStream(findColumn(columnName), x, length);
7553
 
        }
7554
 
 
7555
 
        /**
7556
 
         * @see ResultSet#updateBlob(int, Blob)
7557
 
         */
7558
 
        public void updateBlob(int arg0, java.sql.Blob arg1) throws SQLException {
7559
 
                throw new NotUpdatable();
7560
 
        }
7561
 
 
7562
 
        /**
7563
 
         * @see ResultSet#updateBlob(String, Blob)
7564
 
         */
7565
 
        public void updateBlob(String arg0, java.sql.Blob arg1) throws SQLException {
7566
 
                throw new NotUpdatable();
7567
 
        }
7568
 
 
7569
 
        /**
7570
 
         * JDBC 2.0 Update a column with a boolean value. The updateXXX() methods
7571
 
         * are used to update column values in the current row, or the insert row.
7572
 
         * The updateXXX() methods do not update the underlying database, instead
7573
 
         * the updateRow() or insertRow() methods are called to update the database.
7574
 
         * 
7575
 
         * @param columnIndex
7576
 
         *            the first column is 1, the second is 2, ...
7577
 
         * @param x
7578
 
         *            the new column value
7579
 
         * 
7580
 
         * @exception SQLException
7581
 
         *                if a database-access error occurs
7582
 
         * @throws NotUpdatable
7583
 
         *             DOCUMENT ME!
7584
 
         */
7585
 
        public void updateBoolean(int columnIndex, boolean x) throws SQLException {
7586
 
                throw new NotUpdatable();
7587
 
        }
7588
 
 
7589
 
        /**
7590
 
         * JDBC 2.0 Update a column with a boolean value. The updateXXX() methods
7591
 
         * are used to update column values in the current row, or the insert row.
7592
 
         * The updateXXX() methods do not update the underlying database, instead
7593
 
         * the updateRow() or insertRow() methods are called to update the database.
7594
 
         * 
7595
 
         * @param columnName
7596
 
         *            the name of the column
7597
 
         * @param x
7598
 
         *            the new column value
7599
 
         * 
7600
 
         * @exception SQLException
7601
 
         *                if a database-access error occurs
7602
 
         */
7603
 
        public void updateBoolean(String columnName, boolean x) throws SQLException {
7604
 
                updateBoolean(findColumn(columnName), x);
7605
 
        }
7606
 
 
7607
 
        /**
7608
 
         * JDBC 2.0 Update a column with a byte value. The updateXXX() methods are
7609
 
         * used to update column values in the current row, or the insert row. The
7610
 
         * updateXXX() methods do not update the underlying database, instead the
7611
 
         * updateRow() or insertRow() methods are called to update the database.
7612
 
         * 
7613
 
         * @param columnIndex
7614
 
         *            the first column is 1, the second is 2, ...
7615
 
         * @param x
7616
 
         *            the new column value
7617
 
         * 
7618
 
         * @exception SQLException
7619
 
         *                if a database-access error occurs
7620
 
         * @throws NotUpdatable
7621
 
         *             DOCUMENT ME!
7622
 
         */
7623
 
        public void updateByte(int columnIndex, byte x) throws SQLException {
7624
 
                throw new NotUpdatable();
7625
 
        }
7626
 
 
7627
 
        /**
7628
 
         * JDBC 2.0 Update a column with a byte value. The updateXXX() methods are
7629
 
         * used to update column values in the current row, or the insert row. The
7630
 
         * updateXXX() methods do not update the underlying database, instead the
7631
 
         * updateRow() or insertRow() methods are called to update the database.
7632
 
         * 
7633
 
         * @param columnName
7634
 
         *            the name of the column
7635
 
         * @param x
7636
 
         *            the new column value
7637
 
         * 
7638
 
         * @exception SQLException
7639
 
         *                if a database-access error occurs
7640
 
         */
7641
 
        public void updateByte(String columnName, byte x) throws SQLException {
7642
 
                updateByte(findColumn(columnName), x);
7643
 
        }
7644
 
 
7645
 
        /**
7646
 
         * JDBC 2.0 Update a column with a byte array value. The updateXXX() methods
7647
 
         * are used to update column values in the current row, or the insert row.
7648
 
         * The updateXXX() methods do not update the underlying database, instead
7649
 
         * the updateRow() or insertRow() methods are called to update the database.
7650
 
         * 
7651
 
         * @param columnIndex
7652
 
         *            the first column is 1, the second is 2, ...
7653
 
         * @param x
7654
 
         *            the new column value
7655
 
         * 
7656
 
         * @exception SQLException
7657
 
         *                if a database-access error occurs
7658
 
         * @throws NotUpdatable
7659
 
         *             DOCUMENT ME!
7660
 
         */
7661
 
        public void updateBytes(int columnIndex, byte[] x) throws SQLException {
7662
 
                throw new NotUpdatable();
7663
 
        }
7664
 
 
7665
 
        /**
7666
 
         * JDBC 2.0 Update a column with a byte array value. The updateXXX() methods
7667
 
         * are used to update column values in the current row, or the insert row.
7668
 
         * The updateXXX() methods do not update the underlying database, instead
7669
 
         * the updateRow() or insertRow() methods are called to update the database.
7670
 
         * 
7671
 
         * @param columnName
7672
 
         *            the name of the column
7673
 
         * @param x
7674
 
         *            the new column value
7675
 
         * 
7676
 
         * @exception SQLException
7677
 
         *                if a database-access error occurs
7678
 
         */
7679
 
        public void updateBytes(String columnName, byte[] x) throws SQLException {
7680
 
                updateBytes(findColumn(columnName), x);
7681
 
        }
7682
 
 
7683
 
        /**
7684
 
         * JDBC 2.0 Update a column with a character stream value. The updateXXX()
7685
 
         * methods are used to update column values in the current row, or the
7686
 
         * insert row. The updateXXX() methods do not update the underlying
7687
 
         * database, instead the updateRow() or insertRow() methods are called to
7688
 
         * update the database.
7689
 
         * 
7690
 
         * @param columnIndex
7691
 
         *            the first column is 1, the second is 2, ...
7692
 
         * @param x
7693
 
         *            the new column value
7694
 
         * @param length
7695
 
         *            the length of the stream
7696
 
         * 
7697
 
         * @exception SQLException
7698
 
         *                if a database-access error occurs
7699
 
         * @throws NotUpdatable
7700
 
         *             DOCUMENT ME!
7701
 
         */
7702
 
        public void updateCharacterStream(int columnIndex, java.io.Reader x,
7703
 
                        int length) throws SQLException {
7704
 
                throw new NotUpdatable();
7705
 
        }
7706
 
 
7707
 
        /**
7708
 
         * JDBC 2.0 Update a column with a character stream value. The updateXXX()
7709
 
         * methods are used to update column values in the current row, or the
7710
 
         * insert row. The updateXXX() methods do not update the underlying
7711
 
         * database, instead the updateRow() or insertRow() methods are called to
7712
 
         * update the database.
7713
 
         * 
7714
 
         * @param columnName
7715
 
         *            the name of the column
7716
 
         * @param reader
7717
 
         *            the stream to update the column with
7718
 
         * @param length
7719
 
         *            of the stream
7720
 
         * 
7721
 
         * @throws SQLException
7722
 
         *             if a database-access error occurs
7723
 
         */
7724
 
        public void updateCharacterStream(String columnName, java.io.Reader reader,
7725
 
                        int length) throws SQLException {
7726
 
                updateCharacterStream(findColumn(columnName), reader, length);
7727
 
        }
7728
 
 
7729
 
        /**
7730
 
         * @see ResultSet#updateClob(int, Clob)
7731
 
         */
7732
 
        public void updateClob(int arg0, java.sql.Clob arg1) throws SQLException {
7733
 
                throw new NotImplemented();
7734
 
        }
7735
 
 
7736
 
        /**
7737
 
         * @see ResultSet#updateClob(String, Clob)
7738
 
         */
7739
 
        public void updateClob(String columnName, java.sql.Clob clob)
7740
 
                        throws SQLException {
7741
 
                updateClob(findColumn(columnName), clob);
7742
 
        }
7743
 
 
7744
 
        /**
7745
 
         * JDBC 2.0 Update a column with a Date value. The updateXXX() methods are
7746
 
         * used to update column values in the current row, or the insert row. The
7747
 
         * updateXXX() methods do not update the underlying database, instead the
7748
 
         * updateRow() or insertRow() methods are called to update the database.
7749
 
         * 
7750
 
         * @param columnIndex
7751
 
         *            the first column is 1, the second is 2, ...
7752
 
         * @param x
7753
 
         *            the new column value
7754
 
         * 
7755
 
         * @exception SQLException
7756
 
         *                if a database-access error occurs
7757
 
         * @throws NotUpdatable
7758
 
         *             DOCUMENT ME!
7759
 
         */
7760
 
        public void updateDate(int columnIndex, java.sql.Date x)
7761
 
                        throws SQLException {
7762
 
                throw new NotUpdatable();
7763
 
        }
7764
 
 
7765
 
        /**
7766
 
         * JDBC 2.0 Update a column with a Date value. The updateXXX() methods are
7767
 
         * used to update column values in the current row, or the insert row. The
7768
 
         * updateXXX() methods do not update the underlying database, instead the
7769
 
         * updateRow() or insertRow() methods are called to update the database.
7770
 
         * 
7771
 
         * @param columnName
7772
 
         *            the name of the column
7773
 
         * @param x
7774
 
         *            the new column value
7775
 
         * 
7776
 
         * @exception SQLException
7777
 
         *                if a database-access error occurs
7778
 
         */
7779
 
        public void updateDate(String columnName, java.sql.Date x)
7780
 
                        throws SQLException {
7781
 
                updateDate(findColumn(columnName), x);
7782
 
        }
7783
 
 
7784
 
        /**
7785
 
         * JDBC 2.0 Update a column with a Double value. The updateXXX() methods are
7786
 
         * used to update column values in the current row, or the insert row. The
7787
 
         * updateXXX() methods do not update the underlying database, instead the
7788
 
         * updateRow() or insertRow() methods are called to update the database.
7789
 
         * 
7790
 
         * @param columnIndex
7791
 
         *            the first column is 1, the second is 2, ...
7792
 
         * @param x
7793
 
         *            the new column value
7794
 
         * 
7795
 
         * @exception SQLException
7796
 
         *                if a database-access error occurs
7797
 
         * @throws NotUpdatable
7798
 
         *             DOCUMENT ME!
7799
 
         */
7800
 
        public void updateDouble(int columnIndex, double x) throws SQLException {
7801
 
                throw new NotUpdatable();
7802
 
        }
7803
 
 
7804
 
        /**
7805
 
         * JDBC 2.0 Update a column with a double value. The updateXXX() methods are
7806
 
         * used to update column values in the current row, or the insert row. The
7807
 
         * updateXXX() methods do not update the underlying database, instead the
7808
 
         * updateRow() or insertRow() methods are called to update the database.
7809
 
         * 
7810
 
         * @param columnName
7811
 
         *            the name of the column
7812
 
         * @param x
7813
 
         *            the new column value
7814
 
         * 
7815
 
         * @exception SQLException
7816
 
         *                if a database-access error occurs
7817
 
         */
7818
 
        public void updateDouble(String columnName, double x) throws SQLException {
7819
 
                updateDouble(findColumn(columnName), x);
7820
 
        }
7821
 
 
7822
 
        /**
7823
 
         * JDBC 2.0 Update a column with a float value. The updateXXX() methods are
7824
 
         * used to update column values in the current row, or the insert row. The
7825
 
         * updateXXX() methods do not update the underlying database, instead the
7826
 
         * updateRow() or insertRow() methods are called to update the database.
7827
 
         * 
7828
 
         * @param columnIndex
7829
 
         *            the first column is 1, the second is 2, ...
7830
 
         * @param x
7831
 
         *            the new column value
7832
 
         * 
7833
 
         * @exception SQLException
7834
 
         *                if a database-access error occurs
7835
 
         * @throws NotUpdatable
7836
 
         *             DOCUMENT ME!
7837
 
         */
7838
 
        public void updateFloat(int columnIndex, float x) throws SQLException {
7839
 
                throw new NotUpdatable();
7840
 
        }
7841
 
 
7842
 
        /**
7843
 
         * JDBC 2.0 Update a column with a float value. The updateXXX() methods are
7844
 
         * used to update column values in the current row, or the insert row. The
7845
 
         * updateXXX() methods do not update the underlying database, instead the
7846
 
         * updateRow() or insertRow() methods are called to update the database.
7847
 
         * 
7848
 
         * @param columnName
7849
 
         *            the name of the column
7850
 
         * @param x
7851
 
         *            the new column value
7852
 
         * 
7853
 
         * @exception SQLException
7854
 
         *                if a database-access error occurs
7855
 
         */
7856
 
        public void updateFloat(String columnName, float x) throws SQLException {
7857
 
                updateFloat(findColumn(columnName), x);
7858
 
        }
7859
 
 
7860
 
        /**
7861
 
         * JDBC 2.0 Update a column with an integer value. The updateXXX() methods
7862
 
         * are used to update column values in the current row, or the insert row.
7863
 
         * The updateXXX() methods do not update the underlying database, instead
7864
 
         * the updateRow() or insertRow() methods are called to update the database.
7865
 
         * 
7866
 
         * @param columnIndex
7867
 
         *            the first column is 1, the second is 2, ...
7868
 
         * @param x
7869
 
         *            the new column value
7870
 
         * 
7871
 
         * @exception SQLException
7872
 
         *                if a database-access error occurs
7873
 
         * @throws NotUpdatable
7874
 
         *             DOCUMENT ME!
7875
 
         */
7876
 
        public void updateInt(int columnIndex, int x) throws SQLException {
7877
 
                throw new NotUpdatable();
7878
 
        }
7879
 
 
7880
 
        /**
7881
 
         * JDBC 2.0 Update a column with an integer value. The updateXXX() methods
7882
 
         * are used to update column values in the current row, or the insert row.
7883
 
         * The updateXXX() methods do not update the underlying database, instead
7884
 
         * the updateRow() or insertRow() methods are called to update the database.
7885
 
         * 
7886
 
         * @param columnName
7887
 
         *            the name of the column
7888
 
         * @param x
7889
 
         *            the new column value
7890
 
         * 
7891
 
         * @exception SQLException
7892
 
         *                if a database-access error occurs
7893
 
         */
7894
 
        public void updateInt(String columnName, int x) throws SQLException {
7895
 
                updateInt(findColumn(columnName), x);
7896
 
        }
7897
 
 
7898
 
        /**
7899
 
         * JDBC 2.0 Update a column with a long value. The updateXXX() methods are
7900
 
         * used to update column values in the current row, or the insert row. The
7901
 
         * updateXXX() methods do not update the underlying database, instead the
7902
 
         * updateRow() or insertRow() methods are called to update the database.
7903
 
         * 
7904
 
         * @param columnIndex
7905
 
         *            the first column is 1, the second is 2, ...
7906
 
         * @param x
7907
 
         *            the new column value
7908
 
         * 
7909
 
         * @exception SQLException
7910
 
         *                if a database-access error occurs
7911
 
         * @throws NotUpdatable
7912
 
         *             DOCUMENT ME!
7913
 
         */
7914
 
        public void updateLong(int columnIndex, long x) throws SQLException {
7915
 
                throw new NotUpdatable();
7916
 
        }
7917
 
 
7918
 
        /**
7919
 
         * JDBC 2.0 Update a column with a long value. The updateXXX() methods are
7920
 
         * used to update column values in the current row, or the insert row. The
7921
 
         * updateXXX() methods do not update the underlying database, instead the
7922
 
         * updateRow() or insertRow() methods are called to update the database.
7923
 
         * 
7924
 
         * @param columnName
7925
 
         *            the name of the column
7926
 
         * @param x
7927
 
         *            the new column value
7928
 
         * 
7929
 
         * @exception SQLException
7930
 
         *                if a database-access error occurs
7931
 
         */
7932
 
        public void updateLong(String columnName, long x) throws SQLException {
7933
 
                updateLong(findColumn(columnName), x);
7934
 
        }
7935
 
 
7936
 
        /**
7937
 
         * JDBC 2.0 Give a nullable column a null value. The updateXXX() methods are
7938
 
         * used to update column values in the current row, or the insert row. The
7939
 
         * updateXXX() methods do not update the underlying database, instead the
7940
 
         * updateRow() or insertRow() methods are called to update the database.
7941
 
         * 
7942
 
         * @param columnIndex
7943
 
         *            the first column is 1, the second is 2, ...
7944
 
         * 
7945
 
         * @exception SQLException
7946
 
         *                if a database-access error occurs
7947
 
         * @throws NotUpdatable
7948
 
         *             DOCUMENT ME!
7949
 
         */
7950
 
        public void updateNull(int columnIndex) throws SQLException {
7951
 
                throw new NotUpdatable();
7952
 
        }
7953
 
 
7954
 
        /**
7955
 
         * JDBC 2.0 Update a column with a null value. The updateXXX() methods are
7956
 
         * used to update column values in the current row, or the insert row. The
7957
 
         * updateXXX() methods do not update the underlying database, instead the
7958
 
         * updateRow() or insertRow() methods are called to update the database.
7959
 
         * 
7960
 
         * @param columnName
7961
 
         *            the name of the column
7962
 
         * 
7963
 
         * @exception SQLException
7964
 
         *                if a database-access error occurs
7965
 
         */
7966
 
        public void updateNull(String columnName) throws SQLException {
7967
 
                updateNull(findColumn(columnName));
7968
 
        }
7969
 
 
7970
 
        /**
7971
 
         * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
7972
 
         * are used to update column values in the current row, or the insert row.
7973
 
         * The updateXXX() methods do not update the underlying database, instead
7974
 
         * the updateRow() or insertRow() methods are called to update the database.
7975
 
         * 
7976
 
         * @param columnIndex
7977
 
         *            the first column is 1, the second is 2, ...
7978
 
         * @param x
7979
 
         *            the new column value
7980
 
         * 
7981
 
         * @exception SQLException
7982
 
         *                if a database-access error occurs
7983
 
         * @throws NotUpdatable
7984
 
         *             DOCUMENT ME!
7985
 
         */
7986
 
        public void updateObject(int columnIndex, Object x) throws SQLException {
7987
 
                throw new NotUpdatable();
7988
 
        }
7989
 
 
7990
 
        /**
7991
 
         * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
7992
 
         * are used to update column values in the current row, or the insert row.
7993
 
         * The updateXXX() methods do not update the underlying database, instead
7994
 
         * the updateRow() or insertRow() methods are called to update the database.
7995
 
         * 
7996
 
         * @param columnIndex
7997
 
         *            the first column is 1, the second is 2, ...
7998
 
         * @param x
7999
 
         *            the new column value
8000
 
         * @param scale
8001
 
         *            For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
8002
 
         *            this is the number of digits after the decimal. For all other
8003
 
         *            types this value will be ignored.
8004
 
         * 
8005
 
         * @exception SQLException
8006
 
         *                if a database-access error occurs
8007
 
         * @throws NotUpdatable
8008
 
         *             DOCUMENT ME!
8009
 
         */
8010
 
        public void updateObject(int columnIndex, Object x, int scale)
8011
 
                        throws SQLException {
8012
 
                throw new NotUpdatable();
8013
 
        }
8014
 
 
8015
 
        /**
8016
 
         * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
8017
 
         * are used to update column values in the current row, or the insert row.
8018
 
         * The updateXXX() methods do not update the underlying database, instead
8019
 
         * the updateRow() or insertRow() methods are called to update the database.
8020
 
         * 
8021
 
         * @param columnName
8022
 
         *            the name of the column
8023
 
         * @param x
8024
 
         *            the new column value
8025
 
         * 
8026
 
         * @exception SQLException
8027
 
         *                if a database-access error occurs
8028
 
         */
8029
 
        public void updateObject(String columnName, Object x) throws SQLException {
8030
 
                updateObject(findColumn(columnName), x);
8031
 
        }
8032
 
 
8033
 
        /**
8034
 
         * JDBC 2.0 Update a column with an Object value. The updateXXX() methods
8035
 
         * are used to update column values in the current row, or the insert row.
8036
 
         * The updateXXX() methods do not update the underlying database, instead
8037
 
         * the updateRow() or insertRow() methods are called to update the database.
8038
 
         * 
8039
 
         * @param columnName
8040
 
         *            the name of the column
8041
 
         * @param x
8042
 
         *            the new column value
8043
 
         * @param scale
8044
 
         *            For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
8045
 
         *            this is the number of digits after the decimal. For all other
8046
 
         *            types this value will be ignored.
8047
 
         * 
8048
 
         * @exception SQLException
8049
 
         *                if a database-access error occurs
8050
 
         */
8051
 
        public void updateObject(String columnName, Object x, int scale)
8052
 
                        throws SQLException {
8053
 
                updateObject(findColumn(columnName), x);
8054
 
        }
8055
 
 
8056
 
        /**
8057
 
         * @see ResultSet#updateRef(int, Ref)
8058
 
         */
8059
 
        public void updateRef(int arg0, Ref arg1) throws SQLException {
8060
 
                throw new NotImplemented();
8061
 
        }
8062
 
 
8063
 
        /**
8064
 
         * @see ResultSet#updateRef(String, Ref)
8065
 
         */
8066
 
        public void updateRef(String arg0, Ref arg1) throws SQLException {
8067
 
                throw new NotImplemented();
8068
 
        }
8069
 
 
8070
 
        /**
8071
 
         * JDBC 2.0 Update the underlying database with the new contents of the
8072
 
         * current row. Cannot be called when on the insert row.
8073
 
         * 
8074
 
         * @exception SQLException
8075
 
         *                if a database-access error occurs, or if called when on
8076
 
         *                the insert row
8077
 
         * @throws NotUpdatable
8078
 
         *             DOCUMENT ME!
8079
 
         */
8080
 
        public void updateRow() throws SQLException {
8081
 
                throw new NotUpdatable();
8082
 
        }
8083
 
 
8084
 
        /**
8085
 
         * JDBC 2.0 Update a column with a short value. The updateXXX() methods are
8086
 
         * used to update column values in the current row, or the insert row. The
8087
 
         * updateXXX() methods do not update the underlying database, instead the
8088
 
         * updateRow() or insertRow() methods are called to update the database.
8089
 
         * 
8090
 
         * @param columnIndex
8091
 
         *            the first column is 1, the second is 2, ...
8092
 
         * @param x
8093
 
         *            the new column value
8094
 
         * 
8095
 
         * @exception SQLException
8096
 
         *                if a database-access error occurs
8097
 
         * @throws NotUpdatable
8098
 
         *             DOCUMENT ME!
8099
 
         */
8100
 
        public void updateShort(int columnIndex, short x) throws SQLException {
8101
 
                throw new NotUpdatable();
8102
 
        }
8103
 
 
8104
 
        /**
8105
 
         * JDBC 2.0 Update a column with a short value. The updateXXX() methods are
8106
 
         * used to update column values in the current row, or the insert row. The
8107
 
         * updateXXX() methods do not update the underlying database, instead the
8108
 
         * updateRow() or insertRow() methods are called to update the database.
8109
 
         * 
8110
 
         * @param columnName
8111
 
         *            the name of the column
8112
 
         * @param x
8113
 
         *            the new column value
8114
 
         * 
8115
 
         * @exception SQLException
8116
 
         *                if a database-access error occurs
8117
 
         */
8118
 
        public void updateShort(String columnName, short x) throws SQLException {
8119
 
                updateShort(findColumn(columnName), x);
8120
 
        }
8121
 
 
8122
 
        /**
8123
 
         * JDBC 2.0 Update a column with a String value. The updateXXX() methods are
8124
 
         * used to update column values in the current row, or the insert row. The
8125
 
         * updateXXX() methods do not update the underlying database, instead the
8126
 
         * updateRow() or insertRow() methods are called to update the database.
8127
 
         * 
8128
 
         * @param columnIndex
8129
 
         *            the first column is 1, the second is 2, ...
8130
 
         * @param x
8131
 
         *            the new column value
8132
 
         * 
8133
 
         * @exception SQLException
8134
 
         *                if a database-access error occurs
8135
 
         * @throws NotUpdatable
8136
 
         *             DOCUMENT ME!
8137
 
         */
8138
 
        public void updateString(int columnIndex, String x) throws SQLException {
8139
 
                throw new NotUpdatable();
8140
 
        }
8141
 
 
8142
 
        /**
8143
 
         * JDBC 2.0 Update a column with a String value. The updateXXX() methods are
8144
 
         * used to update column values in the current row, or the insert row. The
8145
 
         * updateXXX() methods do not update the underlying database, instead the
8146
 
         * updateRow() or insertRow() methods are called to update the database.
8147
 
         * 
8148
 
         * @param columnName
8149
 
         *            the name of the column
8150
 
         * @param x
8151
 
         *            the new column value
8152
 
         * 
8153
 
         * @exception SQLException
8154
 
         *                if a database-access error occurs
8155
 
         */
8156
 
        public void updateString(String columnName, String x) throws SQLException {
8157
 
                updateString(findColumn(columnName), x);
8158
 
        }
8159
 
 
8160
 
        /**
8161
 
         * JDBC 2.0 Update a column with a Time value. The updateXXX() methods are
8162
 
         * used to update column values in the current row, or the insert row. The
8163
 
         * updateXXX() methods do not update the underlying database, instead the
8164
 
         * updateRow() or insertRow() methods are called to update the database.
8165
 
         * 
8166
 
         * @param columnIndex
8167
 
         *            the first column is 1, the second is 2, ...
8168
 
         * @param x
8169
 
         *            the new column value
8170
 
         * 
8171
 
         * @exception SQLException
8172
 
         *                if a database-access error occurs
8173
 
         * @throws NotUpdatable
8174
 
         *             DOCUMENT ME!
8175
 
         */
8176
 
        public void updateTime(int columnIndex, java.sql.Time x)
8177
 
                        throws SQLException {
8178
 
                throw new NotUpdatable();
8179
 
        }
8180
 
 
8181
 
        /**
8182
 
         * JDBC 2.0 Update a column with a Time value. The updateXXX() methods are
8183
 
         * used to update column values in the current row, or the insert row. The
8184
 
         * updateXXX() methods do not update the underlying database, instead the
8185
 
         * updateRow() or insertRow() methods are called to update the database.
8186
 
         * 
8187
 
         * @param columnName
8188
 
         *            the name of the column
8189
 
         * @param x
8190
 
         *            the new column value
8191
 
         * 
8192
 
         * @exception SQLException
8193
 
         *                if a database-access error occurs
8194
 
         */
8195
 
        public void updateTime(String columnName, java.sql.Time x)
8196
 
                        throws SQLException {
8197
 
                updateTime(findColumn(columnName), x);
8198
 
        }
8199
 
 
8200
 
        
8201
 
        /**
8202
 
         * JDBC 2.0 Update a column with a Timestamp value. The updateXXX() methods
8203
 
         * are used to update column values in the current row, or the insert row.
8204
 
         * The updateXXX() methods do not update the underlying database, instead
8205
 
         * the updateRow() or insertRow() methods are called to update the database.
8206
 
         * 
8207
 
         * @param columnIndex
8208
 
         *            the first column is 1, the second is 2, ...
8209
 
         * @param x
8210
 
         *            the new column value
8211
 
         * 
8212
 
         * @exception SQLException
8213
 
         *                if a database-access error occurs
8214
 
         * @throws NotUpdatable
8215
 
         *             DOCUMENT ME!
8216
 
         */
8217
 
        public void updateTimestamp(int columnIndex, java.sql.Timestamp x)
8218
 
                        throws SQLException {
8219
 
                throw new NotUpdatable();
8220
 
        }
8221
 
        
8222
 
        /**
8223
 
         * JDBC 2.0 Update a column with a Timestamp value. The updateXXX() methods
8224
 
         * are used to update column values in the current row, or the insert row.
8225
 
         * The updateXXX() methods do not update the underlying database, instead
8226
 
         * the updateRow() or insertRow() methods are called to update the database.
8227
 
         * 
8228
 
         * @param columnName
8229
 
         *            the name of the column
8230
 
         * @param x
8231
 
         *            the new column value
8232
 
         * 
8233
 
         * @exception SQLException
8234
 
         *                if a database-access error occurs
8235
 
         */
8236
 
        public void updateTimestamp(String columnName, java.sql.Timestamp x)
8237
 
                        throws SQLException {
8238
 
                updateTimestamp(findColumn(columnName), x);
8239
 
        }
8240
 
 
8241
 
        /**
8242
 
         * A column may have the value of SQL NULL; wasNull() reports whether the
8243
 
         * last column read had this special value. Note that you must first call
8244
 
         * getXXX on a column to try to read its value and then call wasNull() to
8245
 
         * find if the value was SQL NULL
8246
 
         * 
8247
 
         * @return true if the last column read was SQL NULL
8248
 
         * 
8249
 
         * @exception SQLException
8250
 
         *                if a database access error occurred
8251
 
         */
8252
 
        public boolean wasNull() throws SQLException {
8253
 
                return this.wasNullFlag;
8254
 
        }
8255
 
 
8256
 
        protected Calendar getGmtCalendar() {
8257
 
                
8258
 
                // Worst case we allocate this twice and the other gets GC'd,
8259
 
                // however prevents deadlock
8260
 
                if (this.gmtCalendar == null) {
8261
 
                        this.gmtCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
8262
 
                }
8263
 
                
8264
 
                return this.gmtCalendar;
8265
 
        }
8266
 
        
8267
 
        private Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
8268
 
                                int jdbcType,
8269
 
                        int mysqlType, TimeZone tz, boolean rollForward)
8270
 
                        throws SQLException {
8271
 
 
8272
 
                int year = 0;
8273
 
                int month = 0;
8274
 
                int day = 0;
8275
 
 
8276
 
                int hour = 0;
8277
 
                int minute = 0;
8278
 
                int seconds = 0;
8279
 
 
8280
 
                int nanos = 0;
8281
 
 
8282
 
                byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
8283
 
 
8284
 
                if (bits == null) {
8285
 
                        this.wasNullFlag = true;
8286
 
 
8287
 
                        return null;
8288
 
                }
8289
 
 
8290
 
                Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
8291
 
                                this.connection.getUtcCalendar() : 
8292
 
                                        getCalendarInstanceForSessionOrNew();
8293
 
                                
8294
 
                this.wasNullFlag = false;
8295
 
                
8296
 
                boolean populatedFromDateTimeValue = false;
8297
 
 
8298
 
                switch (mysqlType) {
8299
 
                case MysqlDefs.FIELD_TYPE_DATETIME:
8300
 
                case MysqlDefs.FIELD_TYPE_TIMESTAMP:
8301
 
                        populatedFromDateTimeValue = true;
8302
 
 
8303
 
                        int length = bits.length;
8304
 
 
8305
 
                        if (length != 0) {
8306
 
                                year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
8307
 
                                month = bits[2];
8308
 
                                day = bits[3];
8309
 
 
8310
 
                                if (length > 4) {
8311
 
                                        hour = bits[4];
8312
 
                                        minute = bits[5];
8313
 
                                        seconds = bits[6];
8314
 
                                }
8315
 
 
8316
 
                                if (length > 7) {
8317
 
                                        nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8)
8318
 
                                                        | ((bits[9] & 0xff) << 16)
8319
 
                                                        | ((bits[10] & 0xff) << 24);
8320
 
                                }
8321
 
                        }
8322
 
 
8323
 
                        break;
8324
 
                case MysqlDefs.FIELD_TYPE_DATE:
8325
 
                        populatedFromDateTimeValue = true;
8326
 
 
8327
 
                        if (bits.length != 0) {
8328
 
                                year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
8329
 
                                month = bits[2];
8330
 
                                day = bits[3];
8331
 
                        }
8332
 
 
8333
 
                        break;
8334
 
                case MysqlDefs.FIELD_TYPE_TIME:
8335
 
                        populatedFromDateTimeValue = true;
8336
 
 
8337
 
                        if (bits.length != 0) {
8338
 
                                // bits[0] // skip tm->neg
8339
 
                                // binaryData.readLong(); // skip daysPart
8340
 
                                hour = bits[5];
8341
 
                                minute = bits[6];
8342
 
                                seconds = bits[7];
8343
 
                        }
8344
 
 
8345
 
                        year = 1970;
8346
 
                        month = 1;
8347
 
                        day = 1;
8348
 
                        
8349
 
                        break;
8350
 
                default:
8351
 
                        populatedFromDateTimeValue = false;
8352
 
                }
8353
 
 
8354
 
                switch (jdbcType) {
8355
 
                case Types.TIME:
8356
 
                        if (populatedFromDateTimeValue) {
8357
 
                                Time time = TimeUtil.fastTimeCreate(
8358
 
                                                getCalendarInstanceForSessionOrNew(), hour, minute,
8359
 
                                                seconds);
8360
 
 
8361
 
                                Time adjustedTime = TimeUtil.changeTimezone(this.connection,
8362
 
                                                sessionCalendar, 
8363
 
                                                targetCalendar,
8364
 
                                                time, this.connection.getServerTimezoneTZ(), tz,
8365
 
                                                rollForward);
8366
 
 
8367
 
                                return adjustedTime;
8368
 
                        }
8369
 
                        
8370
 
                        return getNativeTimeViaParseConversion(columnIndex, targetCalendar,
8371
 
                                        tz, rollForward);
8372
 
 
8373
 
                case Types.DATE:
8374
 
                        if (populatedFromDateTimeValue) {
8375
 
                                if ((year == 0) && (month == 0) && (day == 0)) {
8376
 
                                        if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
8377
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
8378
 
                                                this.wasNullFlag = true;
8379
 
 
8380
 
                                                return null;
8381
 
                                        } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
8382
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
8383
 
                                                throw new SQLException(
8384
 
                                                                "Value '0000-00-00' can not be represented as java.sql.Date",
8385
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
8386
 
                                        }
8387
 
 
8388
 
                                        year = 1;
8389
 
                                        month = 1;
8390
 
                                        day = 1;
8391
 
                                }
8392
 
 
8393
 
                                return fastDateCreate(getCalendarInstanceForSessionOrNew(),
8394
 
                                                year, month, day);
8395
 
                        }
8396
 
 
8397
 
                        return getNativeDateViaParseConversion(columnIndex);
8398
 
                case Types.TIMESTAMP:
8399
 
                        if (populatedFromDateTimeValue) {
8400
 
                                if ((year == 0) && (month == 0) && (day == 0)) {
8401
 
                                        if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
8402
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
8403
 
                                                this.wasNullFlag = true;
8404
 
 
8405
 
                                                return null;
8406
 
                                        } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION
8407
 
                                                        .equals(this.connection.getZeroDateTimeBehavior())) {
8408
 
                                                throw new SQLException(
8409
 
                                                                "Value '0000-00-00' can not be represented as java.sql.Timestamp",
8410
 
                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
8411
 
                                        }
8412
 
 
8413
 
                                        year = 1;
8414
 
                                        month = 1;
8415
 
                                        day = 1;
8416
 
                                }
8417
 
 
8418
 
                                Timestamp ts = fastTimestampCreate(
8419
 
                                                getCalendarInstanceForSessionOrNew(), year, month, day,
8420
 
                                                hour, minute, seconds, nanos);
8421
 
 
8422
 
                                Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection,
8423
 
                                                sessionCalendar, 
8424
 
                                                targetCalendar,
8425
 
                                                ts, this.connection.getServerTimezoneTZ(), tz,
8426
 
                                                rollForward);
8427
 
 
8428
 
                                return adjustedTs;
8429
 
                        }
8430
 
 
8431
 
                        return getNativeTimestampViaParseConversion(columnIndex, targetCalendar, tz, rollForward);
8432
 
                        
8433
 
                default:
8434
 
                        throw new SQLException("Internal error - conversion method doesn't support this type", 
8435
 
                                        SQLError.SQL_STATE_GENERAL_ERROR);
8436
 
                }
8437
 
        }
8438
 
}