2
Copyright (C) 2002-2004 MySQL AB
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.
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.
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.
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
25
package com.mysql.jdbc;
27
import com.mysql.jdbc.profiler.ProfileEventSink;
28
import com.mysql.jdbc.profiler.ProfilerEvent;
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;
37
import java.math.BigDecimal;
38
import java.math.BigInteger;
40
import java.net.MalformedURLException;
43
import java.sql.Array;
44
import java.sql.DataTruncation;
47
import java.sql.SQLException;
48
import java.sql.SQLWarning;
50
import java.sql.Timestamp;
51
import java.sql.Types;
53
import java.util.Calendar;
54
import java.util.GregorianCalendar;
55
import java.util.HashMap;
56
import java.util.Locale;
58
import java.util.StringTokenizer;
59
import java.util.TimeZone;
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.
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.
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.
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.
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.
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.
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.
108
* The number, types and properties of a ResultSet's columns are provided by the
109
* ResultSetMetaData object returned by the getMetaData method.
112
* @author Mark Matthews
113
* @version $Id: ResultSet.java 5900 2006-10-18 21:33:06Z mmatthews $
115
* @see ResultSetMetaData
116
* @see java.sql.ResultSet
118
public class ResultSet implements java.sql.ResultSet {
121
* Epsillon between Float.MIN_VALUE and the double representation of said value.
123
protected static final double MIN_DIFF_PREC = Float.parseFloat(Float.toString(Float.MIN_VALUE))
124
- Double.parseDouble(Float.toString(Float.MIN_VALUE));
127
* Epsillon between Float.MAX_VALUE and the double representation of said value.
129
protected static final double MAX_DIFF_PREC = Float.parseFloat(Float.toString(Float.MAX_VALUE))
130
- Double.parseDouble(Float.toString(Float.MAX_VALUE));
132
/** Counter used to generate IDs for profiling. */
133
protected static int resultCounter = 1;
136
* Converts the given value as a java long, to an 'unsigned' long, using the
137
* java.math.BigInteger class.
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);
150
return new BigInteger(1, asBytes);
153
/** The catalog that was in use when we were created */
154
protected String catalog = null;
156
/** Map column names (and all of their permutations) to column indices */
157
protected Map columnNameToIndex = null;
159
/** Keep track of columns accessed */
160
protected boolean[] columnUsed = null;
162
/** The Connection instance that created us */
163
protected com.mysql.jdbc.Connection connection; // The connection that
166
protected long connectionId = 0;
168
/** The current row #, -1 == before start of result set */
169
protected int currentRow = -1; // Cursor to current row;
171
private TimeZone defaultTimeZone;
173
/** Are we in the middle of doing updates to the current row? */
174
protected boolean doingUpdates = false;
176
protected ProfileEventSink eventSink = null;
178
private Calendar fastDateCal = null;
180
/** The direction to fetch rows (always FETCH_FORWARD) */
181
protected int fetchDirection = FETCH_FORWARD;
183
/** The number of rows to fetch in one go... */
184
protected int fetchSize = 0;
186
/** The fields for this result set */
187
protected Field[] fields; // The fields
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
194
protected char firstCharOfQuery;
196
/** Map of fully-specified column names to column indices */
197
protected Map fullColumnNameToIndex = null;
199
protected boolean hasBuiltIndexMapping = false;
202
* Is the data stored as strings (default) or natively (which is the case
203
* with results from PrepStmts)
205
protected boolean isBinaryEncoded = false;
207
/** Has this result set been closed? */
208
protected boolean isClosed = false;
210
protected ResultSet nextResultSet = null;
212
/** Are we on the insert row? */
213
protected boolean onInsertRow = false;
215
/** The statement that created us */
216
protected com.mysql.jdbc.Statement owningStatement;
219
* StackTrace generated where ResultSet was created... used when profiling
221
protected Throwable pointOfOrigin;
223
/** Are we tracking items for profileSql? */
224
protected boolean profileSql = false;
227
* Do we actually contain rows, or just information about
228
* UPDATE/INSERT/DELETE?
230
protected boolean reallyResult = false;
232
/** The id (used when profiling) to identify us */
233
protected int resultId;
235
/** Are we read-only or updatable? */
236
protected int resultSetConcurrency = 0;
238
/** Are we scroll-sensitive/insensitive? */
239
protected int resultSetType = 0;
241
/** The actual rows */
242
protected RowData rowData; // The results
245
* Any info message from the server that was created while generating this
246
* result set (if 'info parsing' is enabled for the connection).
248
protected String serverInfo = null;
250
private PreparedStatement statementUsedForFetchingRows;
252
/** Pointer to current row data */
253
protected Object[] thisRow = null; // Values for current row
255
// These are longs for
256
// recent versions of the MySQL server.
258
// They get reduced to ints via the JDBC API,
259
// but can be retrieved through a MySQLStatement
260
// in their entirety.
263
/** How many rows were affected by UPDATE/INSERT/DELETE? */
264
protected long updateCount;
266
/** Value generated for AUTO_INCREMENT columns */
267
protected long updateId = -1;
269
private boolean useStrictFloatingPoint = false;
271
protected boolean useUsageAdvisor = false;
273
/** The warning chain */
274
protected java.sql.SQLWarning warningChain = null;
276
/** Did the previous value retrieval find a NULL? */
277
protected boolean wasNullFlag = false;
279
protected java.sql.Statement wrapperStatement;
281
protected boolean retainOwningStatement;
283
protected Calendar gmtCalendar = null;
286
* Create a result set for an executeUpdate statement.
289
* the number of rows affected by the update
291
* the autoincrement value (if any)
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];
304
this.connection = conn;
305
this.owningStatement = creatorStmt;
307
this.retainOwningStatement = false;
309
if (this.connection != null) {
310
this.retainOwningStatement =
311
this.connection.getRetainStatementAfterResultSetClose();
313
this.connectionId = this.connection.getId();
318
* Creates a new ResultSet object.
321
* the database in use when we were created
323
* an array of Field objects (basically, the ResultSet MetaData)
327
* the Connection that created us.
331
* @throws SQLException
334
public ResultSet(String catalog, Field[] fields, RowData tuples,
335
Connection conn, Statement creatorStmt) throws SQLException {
336
this.connection = conn;
338
this.fastDateCal = new GregorianCalendar(Locale.US);
339
this.fastDateCal.setTimeZone(this.getDefaultTimeZone());
341
if (this.connection != null) {
342
this.useStrictFloatingPoint = this.connection
343
.getStrictFloatingPoint();
344
this.setDefaultTimeZone(this.connection.getDefaultTimeZone());
345
this.connectionId = this.connection.getId();
348
this.owningStatement = creatorStmt;
350
this.catalog = catalog;
351
this.profileSql = this.connection.getProfileSql();
353
this.fields = fields;
354
this.rowData = tuples;
355
this.updateCount = this.rowData.size();
358
System.out.println(Messages.getString("ResultSet.Retrieved__1")
359
+ this.updateCount + " rows"); //$NON-NLS-1$
362
this.reallyResult = true;
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;
376
this.rowData.setOwner(this);
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);
386
if (this.connection.getGatherPerformanceMetrics()) {
387
this.connection.incrementNumberOfResultSetsCreated();
389
Map tableNamesMap = new HashMap();
391
for (int i = 0; i < this.fields.length; i++) {
392
Field f = this.fields[i];
394
String tableName = f.getOriginalTableName();
396
if (tableName == null) {
397
tableName = f.getTableName();
400
if (tableName != null) {
401
if (this.connection.lowerCaseTableNames()) {
402
tableName = tableName.toLowerCase(); // on windows, table
403
// names are not case-sens.
406
tableNamesMap.put(tableName, null);
410
this.connection.reportNumberOfTablesAccessed(tableNamesMap.size());
413
this.retainOwningStatement = false;
415
if (this.connection != null) {
416
retainOwningStatement =
417
this.connection.getRetainStatementAfterResultSetClose();
425
* Move to an absolute row number in the result set.
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,
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.
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.
446
* Note: Calling absolute(1) is the same as calling first(). Calling
447
* absolute(-1) is the same as calling last().
451
* the row number to move to
453
* @return true if on the result set, false if off.
455
* @exception SQLException
456
* if a database-access error occurs, or row is 0, or result
457
* set type is TYPE_FORWARD_ONLY.
459
public boolean absolute(int row) throws SQLException {
464
if (this.rowData.size() == 0) {
468
throw SQLError.createSQLException(
470
.getString("ResultSet.Cannot_absolute_position_to_row_0_110"), //$NON-NLS-1$
471
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
474
if (this.onInsertRow) {
475
this.onInsertRow = false;
478
if (this.doingUpdates) {
479
this.doingUpdates = false;
484
} else if (row == -1) {
486
} else if (row > this.rowData.size()) {
491
// adjust to reflect after end of result set
492
int newRowPosition = this.rowData.size() + row + 1;
494
if (newRowPosition <= 0) {
498
b = absolute(newRowPosition);
501
row--; // adjust for index difference
502
this.rowData.setCurrentRow(row);
503
this.thisRow = this.rowData.getAt(row);
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.
520
* @exception SQLException
521
* if a database-access error occurs, or result set type is
524
public void afterLast() throws SQLException {
527
if (this.onInsertRow) {
528
this.onInsertRow = false;
531
if (this.doingUpdates) {
532
this.doingUpdates = false;
535
if (this.rowData.size() != 0) {
536
this.rowData.afterLast();
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.
549
* @exception SQLException
550
* if a database-access error occurs, or result set type is
553
public void beforeFirst() throws SQLException {
556
if (this.onInsertRow) {
557
this.onInsertRow = false;
560
if (this.doingUpdates) {
561
this.doingUpdates = false;
564
if (this.rowData.size() == 0) {
568
this.rowData.beforeFirst();
572
// ---------------------------------------------------------------------
573
// Traversal/Positioning
574
// ---------------------------------------------------------------------
577
* Builds a hash between column names and their indices for fast retrieval.
579
protected void buildIndexMapping() throws SQLException {
580
int numFields = this.fields.length;
581
this.columnNameToIndex = new HashMap(numFields);
582
this.fullColumnNameToIndex = new HashMap(numFields);
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
588
// Quoting the JDBC Spec:
590
// "Column names used as input to getter
591
// methods are case insensitive. When a getter method is called with a
593
// name and several columns have the same name, the value of the first
594
// matching column will be returned. "
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();
601
if (columnName != null) {
602
this.columnNameToIndex.put(columnName, index);
603
this.columnNameToIndex.put(columnName.toUpperCase(), index);
604
this.columnNameToIndex.put(columnName.toLowerCase(), index);
607
if (fullColumnName != null) {
608
this.fullColumnNameToIndex.put(fullColumnName, index);
609
this.fullColumnNameToIndex.put(fullColumnName.toUpperCase(),
611
this.fullColumnNameToIndex.put(fullColumnName.toLowerCase(),
616
// set the flag to prevent rebuilding...
617
this.hasBuiltIndexMapping = true;
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.
626
* @exception SQLException
627
* if a database-access error occurs, or if called when on
629
* @throws NotUpdatable
632
public void cancelRowUpdates() throws SQLException {
633
throw new NotUpdatable();
637
* Ensures that the result set is not closed
639
* @throws SQLException
640
* if the result set is closed
642
protected final void checkClosed() throws SQLException {
644
throw SQLError.createSQLException(
646
.getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$
647
SQLError.SQL_STATE_GENERAL_ERROR);
652
* Checks if columnIndex is within the number of columns in this result set.
657
* @throws SQLException
658
* if the index is out of bounds
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$
669
if (this.profileSql || this.useUsageAdvisor) {
670
this.columnUsed[columnIndex - 1] = true;
675
* Ensures that the cursor is positioned on a valid row and that the result
678
* @throws SQLException
679
* if the result set is not in a valid state for traversal
681
protected void checkRowPos() throws SQLException {
684
if (!this.rowData.isDynamic() && (this.rowData.size() == 0)) {
685
throw SQLError.createSQLException(
687
.getString("ResultSet.Illegal_operation_on_empty_result_set"),
688
SQLError.SQL_STATE_GENERAL_ERROR);
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$
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$
705
* We can't do this ourselves, otherwise the contract for
706
* Statement.getMoreResults() won't work correctly.
708
protected void clearNextResult() {
709
this.nextResultSet = null;
713
* After this call, getWarnings returns null until a new warning is reported
716
* @exception SQLException
717
* if a database access error occurs
719
public void clearWarnings() throws SQLException {
720
this.warningChain = null;
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
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
737
* @exception SQLException
738
* if a database access error occurs
740
public void close() throws SQLException {
747
private int convertToZeroWithEmptyCheck() throws SQLException {
748
if (this.connection.getEmptyStringsConvertToZero()) {
752
throw SQLError.createSQLException("Can't convert empty string ('') to numeric",
753
SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
756
private String convertToZeroLiteralStringWithEmptyCheck()
757
throws SQLException {
759
if (this.connection.getEmptyStringsConvertToZero()) {
763
throw SQLError.createSQLException("Can't convert empty string ('') to numeric",
764
SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
768
// Note, row data is linked between these two result sets
770
protected final ResultSet copy() throws SQLException {
771
ResultSet rs = new ResultSet(this.catalog, this.fields, this.rowData,
772
this.connection, this.owningStatement);
777
protected void redefineFieldsForDBMD(Field[] f) {
780
for (int i = 0; i < this.fields.length; i++) {
781
this.fields[i].setUseOldNameMetadata(true);
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.
789
* @exception SQLException
790
* if a database-access error occurs, or if called when on
792
* @throws NotUpdatable
795
public void deleteRow() throws SQLException {
796
throw new NotUpdatable();
804
* @throws SQLException
806
private String extractStringFromNativeColumn(int columnIndex, int mysqlType)
807
throws SQLException {
808
int columnIndexMinusOne = columnIndex - 1;
810
this.wasNullFlag = false;
812
if (this.thisRow[columnIndexMinusOne] instanceof String) {
813
return (String) this.thisRow[columnIndexMinusOne];
816
if (this.thisRow[columnIndexMinusOne] == null) {
817
this.wasNullFlag = true;
822
this.wasNullFlag = false;
824
String stringVal = null;
826
if ((this.connection != null) && this.connection.getUseUnicode()) {
828
String encoding = this.fields[columnIndexMinusOne]
831
if (encoding == null) {
832
stringVal = new String(
833
(byte[]) this.thisRow[columnIndexMinusOne]);
835
SingleByteCharsetConverter converter = this.connection
836
.getCharsetConverter(encoding);
838
if (converter != null) {
839
stringVal = converter
840
.toString((byte[]) this.thisRow[columnIndexMinusOne]);
842
stringVal = new String(
843
(byte[]) this.thisRow[columnIndexMinusOne],
847
} catch (java.io.UnsupportedEncodingException E) {
848
throw SQLError.createSQLException(
850
.getString("ResultSet.Unsupported_character_encoding____138") //$NON-NLS-1$
851
+ this.connection.getEncoding() + "'.", "0S100");
854
stringVal = StringUtils
855
.toAsciiString((byte[]) this.thisRow[columnIndexMinusOne]);
861
private Date fastDateCreate(Calendar cal, int year, int month,
864
cal = this.fastDateCal;
867
boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes();
869
return TimeUtil.fastDateCreate(useGmtMillis,
870
useGmtMillis ? getGmtCalendar() : null,
871
cal, year, month, day);
874
private Time fastTimeCreate(Calendar cal, int hour,
875
int minute, int second) throws SQLException {
877
cal = this.fastDateCal;
880
return TimeUtil.fastTimeCreate(cal, hour, minute, second);
883
private Timestamp fastTimestampCreate(Calendar cal, int year,
884
int month, int day, int hour, int minute, int seconds,
887
cal = this.fastDateCal;
890
boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes();
892
return TimeUtil.fastTimestampCreate(useGmtMillis,
893
useGmtMillis ? getGmtCalendar() : null,
894
cal, year, month, day, hour,
895
minute, seconds, secondsPart);
900
* Required by JDBC spec
903
protected void finalize() throws Throwable {
904
if (!this.isClosed) {
910
// --------------------------JDBC 2.0-----------------------------------
911
// ---------------------------------------------------------------------
912
// Getter's and Setter's
913
// ---------------------------------------------------------------------
917
* Map a ResultSet column name to a ResultSet column index
920
* the name of the column
922
* @return the column index
924
* @exception SQLException
925
* if a database access error occurs
927
public synchronized int findColumn(String columnName) throws SQLException {
930
if (!this.hasBuiltIndexMapping) {
934
index = (Integer) this.columnNameToIndex.get(columnName);
937
index = (Integer) this.fullColumnNameToIndex.get(columnName);
941
return index.intValue() + 1;
944
// Try this inefficient way, now
946
for (int i = 0; i < this.fields.length; i++) {
947
if (this.fields[i].getName().equalsIgnoreCase(columnName)) {
949
} else if (this.fields[i].getFullName()
950
.equalsIgnoreCase(columnName)) {
955
throw SQLError.createSQLException(Messages.getString("ResultSet.Column____112")
957
+ Messages.getString("ResultSet.___not_found._113"), //$NON-NLS-1$ //$NON-NLS-2$
958
SQLError.SQL_STATE_COLUMN_NOT_FOUND);
965
* Moves to the first row in the result set.
968
* @return true if on a valid row, false if no rows in the result set.
970
* @exception SQLException
971
* if a database-access error occurs, or result set type is
974
public boolean first() throws SQLException {
977
if (this.rowData.isEmpty()) {
981
if (this.onInsertRow) {
982
this.onInsertRow = false;
985
if (this.doingUpdates) {
986
this.doingUpdates = false;
989
this.rowData.beforeFirst();
990
this.thisRow = this.rowData.next();
996
* JDBC 2.0 Get an array column.
999
* the first column is 1, the second is 2, ...
1001
* @return an object representing an SQL array
1003
* @throws SQLException
1004
* if a database error occurs
1005
* @throws NotImplemented
1008
public java.sql.Array getArray(int i) throws SQLException {
1009
checkColumnBounds(i);
1011
throw new NotImplemented();
1015
* JDBC 2.0 Get an array column.
1020
* @return an object representing an SQL array
1022
* @throws SQLException
1023
* if a database error occurs
1024
* @throws NotImplemented
1027
public java.sql.Array getArray(String colName) throws SQLException {
1028
return getArray(findColumn(colName));
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.
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.
1044
* @param columnIndex
1045
* the first column is 1, the second is 2, ...
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
1051
* @exception SQLException
1052
* if a database access error occurs
1054
* @see getBinaryStream
1056
public InputStream getAsciiStream(int columnIndex) throws SQLException {
1059
if (!this.isBinaryEncoded) {
1060
return getBinaryStream(columnIndex);
1063
return getNativeBinaryStream(columnIndex);
1072
* @return DOCUMENT ME!
1074
* @throws SQLException
1077
public InputStream getAsciiStream(String columnName) throws SQLException {
1078
return getAsciiStream(findColumn(columnName));
1082
* JDBC 2.0 Get the value of a column in the current row as a
1083
* java.math.BigDecimal object.
1085
* @param columnIndex
1086
* the first column is 1, the second is 2, ...
1088
* @return the column value (full precision); if the value is SQL NULL, the
1091
* @exception SQLException
1092
* if a database-access error occurs.
1094
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
1095
if (!this.isBinaryEncoded) {
1096
String stringVal = getString(columnIndex);
1099
if (stringVal != null) {
1100
if (stringVal.length() == 0) {
1102
val = new BigDecimal(
1103
convertToZeroLiteralStringWithEmptyCheck());
1109
val = new BigDecimal(stringVal);
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$
1124
return getNativeBigDecimal(columnIndex);
1128
* Get the value of a column in the current row as a java.math.BigDecimal
1131
* @param columnIndex
1132
* the first column is 1, the second is 2...
1134
* the number of digits to the right of the decimal
1136
* @return the column value; if the value is SQL NULL, null
1138
* @exception SQLException
1139
* if a database access error occurs
1143
public BigDecimal getBigDecimal(int columnIndex, int scale)
1144
throws SQLException {
1145
if (!this.isBinaryEncoded) {
1146
String stringVal = getString(columnIndex);
1149
if (stringVal != null) {
1150
if (stringVal.length() == 0) {
1151
val = new BigDecimal(
1152
convertToZeroLiteralStringWithEmptyCheck());
1155
return val.setScale(scale);
1156
} catch (ArithmeticException ex) {
1159
.setScale(scale, BigDecimal.ROUND_HALF_UP);
1160
} catch (ArithmeticException arEx) {
1161
throw SQLError.createSQLException(
1163
.getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$
1166
.getString("ResultSet.___in_column__125")
1169
+ this.fields[columnIndex - 1]
1171
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
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);
1182
val = new BigDecimal(valueAsLong);
1184
throw SQLError.createSQLException(Messages
1185
.getString("ResultSet.Bad_format_for_BigDecimal",
1186
new Object[] { new Integer(columnIndex),
1188
SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1193
return val.setScale(scale);
1194
} catch (ArithmeticException ex) {
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),
1202
SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1210
return getNativeBigDecimal(columnIndex, scale);
1214
* JDBC 2.0 Get the value of a column in the current row as a
1215
* java.math.BigDecimal object.
1218
* the name of the column to retrieve the value from
1220
* @return the BigDecimal value in the column
1222
* @throws SQLException
1223
* if an error occurs
1225
public BigDecimal getBigDecimal(String columnName) throws SQLException {
1226
return getBigDecimal(findColumn(columnName));
1237
* @return DOCUMENT ME!
1239
* @throws SQLException
1244
public BigDecimal getBigDecimal(String columnName, int scale)
1245
throws SQLException {
1246
return getBigDecimal(findColumn(columnName), scale);
1249
private final BigDecimal getBigDecimalFromString(String stringVal,
1250
int columnIndex, int scale) throws SQLException {
1253
if (stringVal != null) {
1254
if (stringVal.length() == 0) {
1255
bdVal = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck());
1258
return bdVal.setScale(scale);
1259
} catch (ArithmeticException ex) {
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$
1274
return new BigDecimal(stringVal).setScale(scale);
1275
} catch (ArithmeticException ex) {
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$
1287
} catch (NumberFormatException ex) {
1288
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
1289
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
1292
return new BigDecimal(valueAsLong).setScale(scale);
1293
} catch (ArithmeticException arEx1) {
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$
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);
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$
1324
* A column value can also be retrieved as a binary stream. This method is
1325
* suitable for retrieving LONGVARBINARY values.
1327
* @param columnIndex
1328
* the first column is 1, the second is 2...
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
1334
* @exception SQLException
1335
* if a database access error occurs
1337
* @see getAsciiStream
1338
* @see getUnicodeStream
1340
public InputStream getBinaryStream(int columnIndex) throws SQLException {
1343
if (!this.isBinaryEncoded) {
1344
byte[] b = getBytes(columnIndex);
1347
return new ByteArrayInputStream(b);
1353
return getNativeBinaryStream(columnIndex);
1362
* @return DOCUMENT ME!
1364
* @throws SQLException
1367
public InputStream getBinaryStream(String columnName) throws SQLException {
1368
return getBinaryStream(findColumn(columnName));
1372
* JDBC 2.0 Get a BLOB column.
1374
* @param columnIndex
1375
* the first column is 1, the second is 2, ...
1377
* @return an object representing a BLOB
1379
* @throws SQLException
1380
* if an error occurs.
1382
public java.sql.Blob getBlob(int columnIndex) throws SQLException {
1383
if (!this.isBinaryEncoded) {
1386
checkColumnBounds(columnIndex);
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$
1397
if (this.thisRow[columnIndex - 1] == null) {
1398
this.wasNullFlag = true;
1400
this.wasNullFlag = false;
1402
} catch (NullPointerException ex) {
1403
this.wasNullFlag = true;
1406
if (this.wasNullFlag) {
1410
if (!this.connection.getEmulateLocators()) {
1411
return new Blob((byte[]) this.thisRow[columnIndex - 1]);
1414
return new BlobFromLocator(this, columnIndex);
1417
return getNativeBlob(columnIndex);
1421
* JDBC 2.0 Get a BLOB column.
1426
* @return an object representing a BLOB
1428
* @throws SQLException
1429
* if an error occurs.
1431
public java.sql.Blob getBlob(String colName) throws SQLException {
1432
return getBlob(findColumn(colName));
1436
* Get the value of a column in the current row as a Java boolean
1438
* @param columnIndex
1439
* the first column is 1, the second is 2...
1441
* @return the column value, false for SQL NULL
1443
* @exception SQLException
1444
* if a database access error occurs
1446
public boolean getBoolean(int columnIndex) throws SQLException {
1448
checkColumnBounds(columnIndex);
1451
// MySQL 5.0 and newer have an actual BIT type,
1452
// so we need to check for that here...
1455
int columnIndexMinusOne = columnIndex - 1;
1457
Field field = this.fields[columnIndexMinusOne];
1459
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
1460
return byteArrayToBoolean(columnIndexMinusOne);
1463
this.wasNullFlag = false;
1465
int sqlType = field.getSQLType();
1471
case Types.SMALLINT:
1479
long boolVal = getLong(columnIndex, false);
1481
return (boolVal == -1 || boolVal > 0);
1483
if (this.connection.getPedantic()) {
1484
// Table B-6 from JDBC spec
1487
case Types.VARBINARY:
1488
case Types.LONGVARBINARY:
1491
case Types.TIMESTAMP:
1496
case Types.DATALINK:
1498
case Types.JAVA_OBJECT:
1499
throw SQLError.createSQLException("Required type conversion not allowed",
1500
SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST);
1504
if (sqlType == Types.BINARY ||
1505
sqlType == Types.VARBINARY ||
1506
sqlType == Types.LONGVARBINARY ||
1507
sqlType == Types.BLOB) {
1508
return byteArrayToBoolean(columnIndexMinusOne);
1511
if (this.useUsageAdvisor) {
1512
issueConversionViaParsingWarning("getBoolean()", columnIndex,
1513
this.thisRow[columnIndex], this.fields[columnIndex],
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 });
1524
String stringVal = getString(columnIndex);
1526
return getBooleanFromString(stringVal, columnIndex);
1530
private boolean byteArrayToBoolean(int columnIndexMinusOne) {
1531
if (this.thisRow[columnIndexMinusOne] == null) {
1532
this.wasNullFlag = true;
1537
this.wasNullFlag = false;
1539
if (((byte[]) this.thisRow[columnIndexMinusOne]).length == 0) {
1543
byte boolVal = ((byte[]) this.thisRow[columnIndexMinusOne])[0];
1545
return (boolVal == -1 || boolVal > 0);
1554
* @return DOCUMENT ME!
1556
* @throws SQLException
1559
public boolean getBoolean(String columnName) throws SQLException {
1560
return getBoolean(findColumn(columnName));
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));
1568
return ((c == 't') || (c == 'y') || (c == '1') || stringVal
1576
* Get the value of a column in the current row as a Java byte.
1578
* @param columnIndex
1579
* the first column is 1, the second is 2,...
1581
* @return the column value; 0 if SQL NULL
1583
* @exception SQLException
1584
* if a database access error occurs
1586
public byte getByte(int columnIndex) throws SQLException {
1587
if (!this.isBinaryEncoded) {
1588
String stringVal = getString(columnIndex);
1590
if (this.wasNullFlag || (stringVal == null)) {
1594
return getByteFromString(stringVal, columnIndex);
1597
return getNativeByte(columnIndex);
1606
* @return DOCUMENT ME!
1608
* @throws SQLException
1611
public byte getByte(String columnName) throws SQLException {
1612
return getByte(findColumn(columnName));
1615
private final byte getByteFromString(String stringVal, int columnIndex)
1616
throws SQLException {
1618
if (stringVal != null && stringVal.length() == 0) {
1619
return (byte) convertToZeroWithEmptyCheck();
1623
// JDK-6 doesn't like trailing whitespace
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
1630
stringVal = stringVal.trim();
1633
int decimalIndex = stringVal.indexOf(".");
1636
if (decimalIndex != -1) {
1637
double valueAsDouble = Double.parseDouble(stringVal);
1639
if (this.connection.getJdbcCompliantTruncationForReads()) {
1640
if (valueAsDouble < Byte.MIN_VALUE
1641
|| valueAsDouble > Byte.MAX_VALUE) {
1642
throwRangeException(stringVal, columnIndex,
1647
return (byte) valueAsDouble;
1650
long valueAsLong = Long.parseLong(stringVal);
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);
1660
return (byte) valueAsLong;
1661
} catch (NumberFormatException NFE) {
1662
throw SQLError.createSQLException(
1663
Messages.getString("ResultSet.Value____173")
1664
+ stringVal //$NON-NLS-1$
1666
.getString("ResultSet.___is_out_of_range_[-127,127]_174"),
1667
SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
1672
* Get the value of a column in the current row as a Java byte array.
1675
* <b>Be warned</b> If the blob is huge, then you may run out of memory.
1678
* @param columnIndex
1679
* the first column is 1, the second is 2, ...
1681
* @return the column value; if the value is SQL NULL, the result is null
1683
* @exception SQLException
1684
* if a database access error occurs
1686
public byte[] getBytes(int columnIndex) throws SQLException {
1687
return getBytes(columnIndex, false);
1690
protected byte[] getBytes(int columnIndex, boolean noConversion)
1691
throws SQLException {
1692
if (!this.isBinaryEncoded) {
1695
checkColumnBounds(columnIndex);
1698
if (this.thisRow[columnIndex - 1] == null) {
1699
this.wasNullFlag = true;
1701
this.wasNullFlag = false;
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$
1713
if (this.wasNullFlag) {
1717
return (byte[]) this.thisRow[columnIndex - 1];
1720
return getNativeBytes(columnIndex, noConversion);
1729
* @return DOCUMENT ME!
1731
* @throws SQLException
1734
public byte[] getBytes(String columnName) throws SQLException {
1735
return getBytes(findColumn(columnName));
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(),
1752
* Optimization to only use one calendar per-session, or calculate it for
1753
* each call, depending on user configuration
1755
private Calendar getCalendarInstanceForSessionOrNew() {
1756
if (this.connection != null) {
1757
return this.connection.getCalendarInstanceForSessionOrNew();
1759
// punt, no connection around
1760
return new GregorianCalendar();
1768
* Get the value of a column in the current row as a java.io.Reader.
1771
* @param columnIndex
1772
* the column to get the value from
1774
* @return the value in the column as a java.io.Reader.
1776
* @throws SQLException
1777
* if an error occurs
1779
public java.io.Reader getCharacterStream(int columnIndex)
1780
throws SQLException {
1781
if (!this.isBinaryEncoded) {
1782
String asString = getStringForClob(columnIndex);
1784
if (asString == null) {
1788
return new StringReader(asString);
1791
return getNativeCharacterStream(columnIndex);
1798
* Get the value of a column in the current row as a java.io.Reader.
1802
* the column name to retrieve the value from
1804
* @return the value as a java.io.Reader
1806
* @throws SQLException
1807
* if an error occurs
1809
public java.io.Reader getCharacterStream(String columnName)
1810
throws SQLException {
1811
return getCharacterStream(findColumn(columnName));
1814
private final java.io.Reader getCharacterStreamFromString(String stringVal,
1815
int columnIndex) throws SQLException {
1816
if (stringVal != null) {
1817
return new StringReader(stringVal);
1824
* JDBC 2.0 Get a CLOB column.
1827
* the first column is 1, the second is 2, ...
1829
* @return an object representing a CLOB
1831
* @throws SQLException
1832
* if an error occurs
1834
public java.sql.Clob getClob(int i) throws SQLException {
1835
if (!this.isBinaryEncoded) {
1836
String asString = getStringForClob(i);
1838
if (asString == null) {
1842
return new com.mysql.jdbc.Clob(asString);
1845
return getNativeClob(i);
1849
* JDBC 2.0 Get a CLOB column.
1854
* @return an object representing a CLOB
1856
* @throws SQLException
1857
* if an error occurs
1859
public java.sql.Clob getClob(String colName) throws SQLException {
1860
return getClob(findColumn(colName));
1863
private final java.sql.Clob getClobFromString(String stringVal,
1864
int columnIndex) throws SQLException {
1865
return new com.mysql.jdbc.Clob(stringVal);
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.
1872
* @return the concurrency type, CONCUR_READ_ONLY, etc.
1874
* @throws SQLException
1875
* if a database-access error occurs
1877
public int getConcurrency() throws SQLException {
1878
return (CONCUR_READ_ONLY);
1882
* Get the name of the SQL cursor used by this ResultSet
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.
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.
1897
* <B>Note:</B> If positioned update is not supported, a SQLException is
1901
* @return the ResultSet's SQL cursor name.
1903
* @exception SQLException
1904
* if a database access error occurs
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$
1913
* Get the value of a column in the current row as a java.sql.Date object
1915
* @param columnIndex
1916
* the first column is 1, the second is 2...
1918
* @return the column value; null if SQL NULL
1920
* @exception java.sql.SQLException
1921
* if a database access error occurs
1923
public java.sql.Date getDate(int columnIndex) throws java.sql.SQLException {
1924
return getDate(columnIndex, null);
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
1933
* @param columnIndex
1934
* the first column is 1, the second is 2, ...
1936
* the calendar to use in constructing the date
1938
* @return the column value; if the value is SQL NULL, the result is null
1940
* @exception SQLException
1941
* if a database-access error occurs.
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());
1950
String stringVal = getStringInternal(columnIndex, false);
1952
if (stringVal == null) {
1956
return getDateFromString(stringVal, columnIndex);
1965
* @return DOCUMENT ME!
1967
* @throws java.sql.SQLException
1970
public java.sql.Date getDate(String columnName)
1971
throws java.sql.SQLException {
1972
return getDate(findColumn(columnName));
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.
1981
* is the SQL name of the column
1983
* the calendar to use in constructing the date
1985
* @return the column value; if the value is SQL NULL, the result is null
1987
* @exception SQLException
1988
* if a database-access error occurs.
1990
public java.sql.Date getDate(String columnName, Calendar cal)
1991
throws SQLException {
1992
return getDate(findColumn(columnName), cal);
1995
private final java.sql.Date getDateFromString(String stringVal,
1996
int columnIndex) throws SQLException {
2002
this.wasNullFlag = false;
2004
if (stringVal == null) {
2005
this.wasNullFlag = true;
2011
// JDK-6 doesn't like trailing whitespace
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
2018
stringVal = stringVal.trim();
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")) {
2025
if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
2026
.equals(this.connection.getZeroDateTimeBehavior())) {
2027
this.wasNullFlag = true;
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);
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);
2041
} else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
2042
// Convert from TIMESTAMP
2043
switch (stringVal.length()) {
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));
2050
return fastDateCreate(null, year, month, day);
2055
year = Integer.parseInt(stringVal.substring(0, 4));
2056
month = Integer.parseInt(stringVal.substring(4, 6));
2057
day = Integer.parseInt(stringVal.substring(6, 8));
2059
return fastDateCreate(null, year, month, day);
2065
year = Integer.parseInt(stringVal.substring(0, 2));
2071
month = Integer.parseInt(stringVal.substring(2, 4));
2072
day = Integer.parseInt(stringVal.substring(4, 6));
2074
return fastDateCreate(null, year + 1900, month, day);
2078
year = Integer.parseInt(stringVal.substring(0, 4));
2084
month = Integer.parseInt(stringVal.substring(2, 4));
2086
return fastDateCreate(null, year + 1900, month, 1);
2090
year = Integer.parseInt(stringVal.substring(0, 2));
2096
return fastDateCreate(null, year + 1900, 1, 1);
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$
2105
} else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
2107
if (stringVal.length() == 2 || stringVal.length() == 1) {
2108
year = Integer.parseInt(stringVal);
2116
year = Integer.parseInt(stringVal.substring(0, 4));
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
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$
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));
2135
// JDK-1.3 timestamp format, not real easy to parse positionally :p
2136
StringTokenizer st = new StringTokenizer(stringVal, "- ");
2138
year = Integer.parseInt(st.nextToken());
2139
month = Integer.parseInt(st.nextToken());
2140
day = Integer.parseInt(st.nextToken());
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$
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();
2162
return this.defaultTimeZone;
2166
* Get the value of a column in the current row as a Java double.
2168
* @param columnIndex
2169
* the first column is 1, the second is 2,...
2171
* @return the column value; 0 if SQL NULL
2173
* @exception SQLException
2174
* if a database access error occurs
2176
public double getDouble(int columnIndex) throws SQLException {
2177
if (!this.isBinaryEncoded) {
2178
return getDoubleInternal(columnIndex);
2181
return getNativeDouble(columnIndex);
2190
* @return DOCUMENT ME!
2192
* @throws SQLException
2195
public double getDouble(String columnName) throws SQLException {
2196
return getDouble(findColumn(columnName));
2199
private final double getDoubleFromString(String stringVal, int columnIndex)
2200
throws SQLException {
2201
return getDoubleInternal(stringVal, columnIndex);
2205
* Converts a string representation of a number to a double. Need a faster
2209
* the 1-based index of the column to retrieve a double from.
2211
* @return the double value represented by the string in buf
2213
* @throws SQLException
2214
* if an error occurs
2216
protected double getDoubleInternal(int colIndex) throws SQLException {
2217
return getDoubleInternal(getString(colIndex), colIndex);
2221
* Converts a string representation of a number to a double. Need a faster
2225
* the double as a String
2227
* the 1-based index of the column to retrieve a double from.
2229
* @return the double value represented by the string in buf
2231
* @throws SQLException
2232
* if an error occurs
2234
protected double getDoubleInternal(String stringVal, int colIndex)
2235
throws SQLException {
2237
if ((stringVal == null)) {
2241
if (stringVal.length() == 0) {
2242
return convertToZeroWithEmptyCheck();
2245
double d = Double.parseDouble(stringVal);
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
2252
} else if (d == 1.0000000036275E-15) {
2253
// Fix odd end-point rounding on MySQL
2255
} else if (d == 9.999999869911E14) {
2256
d = 9.99999999999999E14;
2257
} else if (d == 1.4012984643248E-45) {
2259
} else if (d == 1.4013E-45) {
2261
} else if (d == 3.4028234663853E37) {
2263
} else if (d == -2.14748E9) {
2265
} else if (d == 3.40282E37) {
2271
} catch (NumberFormatException e) {
2272
if (this.fields[colIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2273
long valueAsLong = getNumericRepresentationOfSQLBitType(colIndex);
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);
2286
* JDBC 2.0 Returns the fetch direction for this result set.
2288
* @return the fetch direction for this result set.
2290
* @exception SQLException
2291
* if a database-access error occurs
2293
public int getFetchDirection() throws SQLException {
2294
return this.fetchDirection;
2298
* JDBC 2.0 Return the fetch size for this result set.
2300
* @return the fetch size for this result set.
2302
* @exception SQLException
2303
* if a database-access error occurs
2305
public int getFetchSize() throws SQLException {
2306
return this.fetchSize;
2310
* Returns the first character of the query that this result set was created
2313
* @return the first character of the query...uppercased
2315
protected char getFirstCharOfQuery() {
2316
return this.firstCharOfQuery;
2320
* Get the value of a column in the current row as a Java float.
2322
* @param columnIndex
2323
* the first column is 1, the second is 2,...
2325
* @return the column value; 0 if SQL NULL
2327
* @exception SQLException
2328
* if a database access error occurs
2330
public float getFloat(int columnIndex) throws SQLException {
2331
if (!this.isBinaryEncoded) {
2334
val = getString(columnIndex);
2336
return getFloatFromString(val, columnIndex);
2339
return getNativeFloat(columnIndex);
2348
* @return DOCUMENT ME!
2350
* @throws SQLException
2353
public float getFloat(String columnName) throws SQLException {
2354
return getFloat(findColumn(columnName));
2357
private final float getFloatFromString(String val, int columnIndex)
2358
throws SQLException {
2360
if ((val != null)) {
2361
if (val.length() == 0) {
2362
return convertToZeroWithEmptyCheck();
2365
float f = Float.parseFloat(val);
2367
if (this.connection.getJdbcCompliantTruncationForReads()) {
2368
if (f == Float.MIN_VALUE || f == Float.MAX_VALUE) {
2369
double valAsDouble = Double.parseDouble(val);
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
2375
if ((valAsDouble < Float.MIN_VALUE - MIN_DIFF_PREC)
2376
|| (valAsDouble > Float.MAX_VALUE - MAX_DIFF_PREC)) {
2377
throwRangeException(String.valueOf(valAsDouble), columnIndex,
2386
return 0; // for NULL
2387
} catch (NumberFormatException nfe) {
2389
Double valueAsDouble = new Double(val);
2390
float valueAsFloat = valueAsDouble.floatValue();
2392
if (this.connection.getJdbcCompliantTruncationForReads()) {
2394
if (this.connection.getJdbcCompliantTruncationForReads() &&
2395
valueAsFloat == Float.NEGATIVE_INFINITY ||
2396
valueAsFloat == Float.POSITIVE_INFINITY) {
2397
throwRangeException(valueAsDouble.toString(),
2398
columnIndex, Types.FLOAT);
2402
return valueAsFloat;
2403
} catch (NumberFormatException newNfe) {
2404
; // ignore, it's not a number
2407
throw SQLError.createSQLException(
2409
.getString("ResultSet.Invalid_value_for_getFloat()_-____200")
2411
+ Messages.getString("ResultSet.___in_column__201")
2412
+ columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2417
* Get the value of a column in the current row as a Java int.
2419
* @param columnIndex
2420
* the first column is 1, the second is 2,...
2422
* @return the column value; 0 if SQL NULL
2424
* @exception SQLException
2425
* if a database access error occurs
2427
public int getInt(int columnIndex) throws SQLException {
2430
if (!this.isBinaryEncoded) {
2431
if (this.connection.getUseFastIntParsing()) {
2432
checkColumnBounds(columnIndex);
2435
if (this.thisRow[columnIndex - 1] == null) {
2436
this.wasNullFlag = true;
2438
this.wasNullFlag = false;
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$
2450
if (this.wasNullFlag) {
2454
byte[] intAsBytes = (byte[]) this.thisRow[columnIndex - 1];
2456
if (intAsBytes.length == 0) {
2457
return convertToZeroWithEmptyCheck();
2460
boolean needsFullParse = false;
2462
for (int i = 0; i < intAsBytes.length; i++) {
2463
if (((char) intAsBytes[i] == 'e')
2464
|| ((char) intAsBytes[i] == 'E')) {
2465
needsFullParse = true;
2471
if (!needsFullParse) {
2473
return parseIntWithOverflowCheck(columnIndex,
2475
} catch (NumberFormatException nfe) {
2478
return parseIntAsDouble(columnIndex, new String(
2480
} catch (NumberFormatException newNfe) {
2481
; // ignore, it's not a number
2484
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2485
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
2487
if (this.connection.getJdbcCompliantTruncationForReads() &&
2488
(valueAsLong < Integer.MIN_VALUE
2489
|| valueAsLong > Integer.MAX_VALUE)) {
2490
throwRangeException(String.valueOf(valueAsLong), columnIndex,
2494
return (int)valueAsLong;
2497
throw SQLError.createSQLException(
2499
.getString("ResultSet.Invalid_value_for_getInt()_-____74")
2500
+ new String(intAsBytes) //$NON-NLS-1$
2502
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2510
val = getString(columnIndex);
2512
if ((val != null)) {
2513
if (val.length() == 0) {
2514
return convertToZeroWithEmptyCheck();
2517
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
2518
&& (val.indexOf(".") == -1)) {
2519
return Integer.parseInt(val);
2522
// Convert floating point
2523
return parseIntAsDouble(columnIndex, val);
2527
} catch (NumberFormatException nfe) {
2529
return parseIntAsDouble(columnIndex, val);
2530
} catch (NumberFormatException newNfe) {
2531
; // ignore, it's not a number
2534
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2535
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
2537
if (this.connection.getJdbcCompliantTruncationForReads() &&
2538
(valueAsLong < Integer.MIN_VALUE
2539
|| valueAsLong > Integer.MAX_VALUE)) {
2540
throwRangeException(String.valueOf(valueAsLong), columnIndex,
2544
return (int)valueAsLong;
2547
throw SQLError.createSQLException(
2549
.getString("ResultSet.Invalid_value_for_getInt()_-____74")
2551
+ "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2555
return getNativeInt(columnIndex);
2564
* @return DOCUMENT ME!
2566
* @throws SQLException
2569
public int getInt(String columnName) throws SQLException {
2570
return getInt(findColumn(columnName));
2573
private final int getIntFromString(String val, int columnIndex)
2574
throws SQLException {
2576
if ((val != null)) {
2578
if (val.length() == 0) {
2579
return convertToZeroWithEmptyCheck();
2582
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
2583
&& (val.indexOf(".") == -1)) {
2585
// JDK-6 doesn't like trailing whitespace
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
2594
int valueAsInt = Integer.parseInt(val);
2596
if (this.connection.getJdbcCompliantTruncationForReads()) {
2597
if (valueAsInt == Integer.MIN_VALUE
2598
|| valueAsInt == Integer.MAX_VALUE) {
2599
long valueAsLong = Long.parseLong(val);
2601
if (valueAsLong < Integer.MIN_VALUE
2602
|| valueAsLong > Integer.MAX_VALUE) {
2603
throwRangeException(
2604
String.valueOf(valueAsLong),
2605
columnIndex, Types.INTEGER);
2613
// Convert floating point
2615
double valueAsDouble = Double.parseDouble(val);
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);
2625
return (int) valueAsDouble;
2628
return 0; // for NULL
2629
} catch (NumberFormatException nfe) {
2631
double valueAsDouble = Double.parseDouble(val);
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);
2641
return (int) valueAsDouble;
2642
} catch (NumberFormatException newNfe) {
2643
; // ignore, it's not a number
2646
throw SQLError.createSQLException(Messages
2647
.getString("ResultSet.Invalid_value_for_getInt()_-____206")
2649
+ Messages.getString("ResultSet.___in_column__207")
2650
+ columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2655
* Get the value of a column in the current row as a Java long.
2657
* @param columnIndex
2658
* the first column is 1, the second is 2,...
2660
* @return the column value; 0 if SQL NULL
2662
* @exception SQLException
2663
* if a database access error occurs
2665
public long getLong(int columnIndex) throws SQLException {
2666
return getLong(columnIndex, true);
2669
private long getLong(int columnIndex, boolean overflowCheck) throws SQLException {
2670
if (!this.isBinaryEncoded) {
2673
if (this.connection.getUseFastIntParsing()) {
2675
checkColumnBounds(columnIndex);
2678
if (this.thisRow[columnIndex - 1] == null) {
2679
this.wasNullFlag = true;
2681
this.wasNullFlag = false;
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$
2693
if (this.wasNullFlag) {
2697
byte[] longAsBytes = (byte[]) this.thisRow[columnIndex - 1];
2699
if (longAsBytes.length == 0) {
2700
return convertToZeroWithEmptyCheck();
2703
boolean needsFullParse = false;
2705
for (int i = 0; i < longAsBytes.length; i++) {
2706
if (((char) longAsBytes[i] == 'e')
2707
|| ((char) longAsBytes[i] == 'E')) {
2708
needsFullParse = true;
2714
if (!needsFullParse) {
2716
return parseLongWithOverflowCheck(columnIndex,
2717
longAsBytes, null, overflowCheck);
2718
} catch (NumberFormatException nfe) {
2720
// To do: Warn of over/underflow???
2721
return parseLongAsDouble(columnIndex, new String(
2723
} catch (NumberFormatException newNfe) {
2724
// ; // ignore, it's not a number
2727
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
2728
return getNumericRepresentationOfSQLBitType(columnIndex);
2731
throw SQLError.createSQLException(
2733
.getString("ResultSet.Invalid_value_for_getLong()_-____79")
2734
+ new String(longAsBytes) //$NON-NLS-1$
2736
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2744
val = getString(columnIndex);
2746
if ((val != null)) {
2747
if (val.length() == 0) {
2748
return convertToZeroWithEmptyCheck();
2751
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) {
2752
return parseLongWithOverflowCheck(columnIndex, null,
2753
val, overflowCheck);
2756
// Convert floating point
2757
return parseLongAsDouble(columnIndex, val);
2760
return 0; // for NULL
2761
} catch (NumberFormatException nfe) {
2763
return parseLongAsDouble(columnIndex, val);
2764
} catch (NumberFormatException newNfe) {
2765
// ; // ignore, it's not a number
2768
throw SQLError.createSQLException(
2770
.getString("ResultSet.Invalid_value_for_getLong()_-____79")
2772
+ "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
2776
return getNativeLong(columnIndex, overflowCheck, true);
2785
* @return DOCUMENT ME!
2787
* @throws SQLException
2790
public long getLong(String columnName) throws SQLException {
2791
return getLong(findColumn(columnName));
2794
private final long getLongFromString(String val, int columnIndex)
2795
throws SQLException {
2797
if ((val != null)) {
2799
if (val.length() == 0) {
2800
return convertToZeroWithEmptyCheck();
2803
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) {
2804
return parseLongWithOverflowCheck(columnIndex, null, val, true);
2807
// Convert floating point
2808
return parseLongAsDouble(columnIndex, val);
2811
return 0; // for NULL
2812
} catch (NumberFormatException nfe) {
2814
// To do: Warn of over/underflow???
2815
return parseLongAsDouble(columnIndex, val);
2816
} catch (NumberFormatException newNfe) {
2817
; // ignore, it's not a number
2820
throw SQLError.createSQLException(
2822
.getString("ResultSet.Invalid_value_for_getLong()_-____211")
2824
+ Messages.getString("ResultSet.___in_column__212")
2825
+ columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
2830
* The numbers, types and properties of a ResultSet's columns are provided
2831
* by the getMetaData method
2833
* @return a description of the ResultSet's columns
2835
* @exception SQLException
2836
* if a database access error occurs
2838
public java.sql.ResultSetMetaData getMetaData() throws SQLException {
2841
return new com.mysql.jdbc.ResultSetMetaData(this.fields,
2842
this.connection.getUseOldAliasMetadataBehavior());
2846
* JDBC 2.0 Get an array column.
2849
* the first column is 1, the second is 2, ...
2851
* @return an object representing an SQL array
2853
* @throws SQLException
2854
* if a database error occurs
2855
* @throws NotImplemented
2858
protected java.sql.Array getNativeArray(int i) throws SQLException {
2859
throw new NotImplemented();
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.
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.
2875
* @param columnIndex
2876
* the first column is 1, the second is 2, ...
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
2882
* @exception SQLException
2883
* if a database access error occurs
2885
* @see getBinaryStream
2887
protected InputStream getNativeAsciiStream(int columnIndex)
2888
throws SQLException {
2891
return getNativeBinaryStream(columnIndex);
2895
* JDBC 2.0 Get the value of a column in the current row as a
2896
* java.math.BigDecimal object.
2898
* @param columnIndex
2899
* the first column is 1, the second is 2, ...
2901
* @return the column value (full precision); if the value is SQL NULL, the
2904
* @exception SQLException
2905
* if a database-access error occurs.
2907
protected BigDecimal getNativeBigDecimal(int columnIndex)
2908
throws SQLException {
2910
checkColumnBounds(columnIndex);
2912
int scale = this.fields[columnIndex - 1].getDecimals();
2914
return getNativeBigDecimal(columnIndex, scale);
2918
* Get the value of a column in the current row as a java.math.BigDecimal
2921
* @param columnIndex
2922
* the first column is 1, the second is 2...
2924
* the number of digits to the right of the decimal
2926
* @return the column value; if the value is SQL NULL, null
2928
* @exception SQLException
2929
* if a database access error occurs
2931
protected BigDecimal getNativeBigDecimal(int columnIndex, int scale)
2932
throws SQLException {
2933
checkColumnBounds(columnIndex);
2935
String stringVal = null;
2937
Field f = this.fields[columnIndex - 1];
2939
if (this.thisRow[columnIndex - 1] == null) {
2940
this.wasNullFlag = true;
2945
this.wasNullFlag = false;
2947
switch (f.getSQLType()) {
2950
stringVal = StringUtils
2951
.toAsciiString((byte[]) this.thisRow[columnIndex - 1]);
2954
stringVal = getNativeString(columnIndex);
2957
return getBigDecimalFromString(stringVal, columnIndex, scale);
2961
* A column value can also be retrieved as a binary strea. This method is
2962
* suitable for retrieving LONGVARBINARY values.
2964
* @param columnIndex
2965
* the first column is 1, the second is 2...
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
2971
* @exception SQLException
2972
* if a database access error occurs
2974
* @see getAsciiStream
2975
* @see getUnicodeStream
2977
protected InputStream getNativeBinaryStream(int columnIndex)
2978
throws SQLException {
2981
byte[] b = getNativeBytes(columnIndex, false);
2984
return new ByteArrayInputStream(b);
2991
* JDBC 2.0 Get a BLOB column.
2993
* @param columnIndex
2994
* the first column is 1, the second is 2, ...
2996
* @return an object representing a BLOB
2998
* @throws SQLException
2999
* if an error occurs.
3001
protected java.sql.Blob getNativeBlob(int columnIndex) throws SQLException {
3004
checkColumnBounds(columnIndex);
3007
if (this.thisRow[columnIndex - 1] == null) {
3008
this.wasNullFlag = true;
3010
this.wasNullFlag = false;
3012
} catch (NullPointerException ex) {
3013
this.wasNullFlag = true;
3016
if (this.wasNullFlag) {
3020
int mysqlType = this.fields[columnIndex - 1].getMysqlType();
3022
byte[] dataAsBytes = null;
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];
3032
dataAsBytes = getNativeBytes(columnIndex, false);
3035
if (!this.connection.getEmulateLocators()) {
3036
return new Blob(dataAsBytes);
3039
return new BlobFromLocator(this, columnIndex);
3043
* Get the value of a column in the current row as a Java byte.
3045
* @param columnIndex
3046
* the first column is 1, the second is 2,...
3048
* @return the column value; 0 if SQL NULL
3050
* @exception SQLException
3051
* if a database access error occurs
3053
protected byte getNativeByte(int columnIndex) throws SQLException {
3054
return getNativeByte(columnIndex, true);
3057
protected byte getNativeByte(int columnIndex, boolean overflowCheck) throws SQLException {
3060
checkColumnBounds(columnIndex);
3062
if (this.thisRow[columnIndex - 1] == null) {
3063
this.wasNullFlag = true;
3069
if (this.thisRow[columnIndex - 1] == null) {
3070
this.wasNullFlag = true;
3072
this.wasNullFlag = false;
3074
} catch (NullPointerException E) {
3075
this.wasNullFlag = true;
3078
if (this.wasNullFlag) {
3084
Field field = this.fields[columnIndex];
3086
switch (field.getMysqlType()) {
3087
case MysqlDefs.FIELD_TYPE_BIT:
3088
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3090
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3091
(valueAsLong < Byte.MIN_VALUE
3092
|| valueAsLong > Byte.MAX_VALUE)) {
3093
throwRangeException(String.valueOf(valueAsLong), columnIndex + 1,
3097
return (byte)valueAsLong;
3098
case MysqlDefs.FIELD_TYPE_TINY:
3099
byte valueAsByte = ((byte[]) this.thisRow[columnIndex])[0];
3101
if (!field.isUnsigned()) {
3105
short valueAsShort = (valueAsByte >= 0) ?
3106
valueAsByte : (short)(valueAsByte + (short)256);
3108
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3109
if (valueAsShort > Byte.MAX_VALUE) {
3110
throwRangeException(String.valueOf(valueAsShort),
3111
columnIndex + 1, Types.TINYINT);
3115
return (byte)valueAsShort;
3117
case MysqlDefs.FIELD_TYPE_SHORT:
3118
case MysqlDefs.FIELD_TYPE_YEAR:
3119
valueAsShort = getNativeShort(columnIndex + 1);
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);
3129
return (byte) valueAsShort;
3130
case MysqlDefs.FIELD_TYPE_INT24:
3131
case MysqlDefs.FIELD_TYPE_LONG:
3132
int valueAsInt = getNativeInt(columnIndex + 1, false);
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);
3141
return (byte) valueAsInt;
3143
case MysqlDefs.FIELD_TYPE_FLOAT:
3144
float valueAsFloat = getNativeFloat(columnIndex + 1);
3146
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
3147
if (valueAsFloat < Byte.MIN_VALUE
3148
|| valueAsFloat > Byte.MAX_VALUE) {
3150
throwRangeException(String.valueOf(valueAsFloat),
3151
columnIndex + 1, Types.TINYINT);
3155
return (byte) valueAsFloat;
3157
case MysqlDefs.FIELD_TYPE_DOUBLE:
3158
double valueAsDouble = getNativeDouble(columnIndex + 1);
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);
3168
return (byte) valueAsDouble;
3170
case MysqlDefs.FIELD_TYPE_LONGLONG:
3171
valueAsLong = getNativeLong(columnIndex + 1, false, true);
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);
3181
return (byte) valueAsLong;
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 });
3195
return getByteFromString(getNativeString(columnIndex + 1),
3201
* Get the value of a column in the current row as a Java byte array.
3204
* <b>Be warned</b> If the blob is huge, then you may run out of memory.
3207
* @param columnIndex
3208
* the first column is 1, the second is 2, ...
3210
* @return the column value; if the value is SQL NULL, the result is null
3212
* @exception SQLException
3213
* if a database access error occurs
3215
protected byte[] getNativeBytes(int columnIndex, boolean noConversion)
3216
throws SQLException {
3219
checkColumnBounds(columnIndex);
3222
if (this.thisRow[columnIndex - 1] == null) {
3223
this.wasNullFlag = true;
3225
this.wasNullFlag = false;
3227
} catch (NullPointerException E) {
3228
this.wasNullFlag = true;
3231
if (this.wasNullFlag) {
3235
Field field = this.fields[columnIndex - 1];
3237
int mysqlType = field.getMysqlType();
3239
// Workaround for emulated locators in servers > 4.1,
3240
// as server returns SUBSTRING(blob) as STRING type...
3242
mysqlType = MysqlDefs.FIELD_TYPE_BLOB;
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];
3254
int sqlType = field.getSQLType();
3256
if (sqlType == Types.VARBINARY || sqlType == Types.BINARY) {
3257
return (byte[]) this.thisRow[columnIndex - 1];
3260
return getBytesFromString(getNativeString(columnIndex), columnIndex);
3268
* Get the value of a column in the current row as a java.io.Reader.
3271
* @param columnIndex
3272
* the column to get the value from
3274
* @return the value in the column as a java.io.Reader.
3276
* @throws SQLException
3277
* if an error occurs
3279
protected java.io.Reader getNativeCharacterStream(int columnIndex)
3280
throws SQLException {
3281
String asString = null;
3283
asString = getStringForClob(columnIndex);
3285
if (asString == null) {
3288
return getCharacterStreamFromString(asString, columnIndex);
3292
* JDBC 2.0 Get a CLOB column.
3294
* @param columnIndex
3295
* the first column is 1, the second is 2, ...
3297
* @return an object representing a CLOB
3299
* @throws SQLException
3300
* if an error occurs
3302
protected java.sql.Clob getNativeClob(int columnIndex) throws SQLException {
3303
String stringVal = getStringForClob(columnIndex);
3305
if (stringVal == null) {
3309
return getClobFromString(stringVal, columnIndex);
3312
private String getNativeConvertToString(int columnIndex,
3314
throws SQLException {
3317
int sqlType = field.getSQLType();
3318
int mysqlType = field.getMysqlType();
3322
return String.valueOf(getNumericRepresentationOfSQLBitType(columnIndex));
3324
boolean booleanVal = getBoolean(columnIndex);
3326
if (this.wasNullFlag) {
3330
return String.valueOf(booleanVal);
3333
byte tinyintVal = getNativeByte(columnIndex, false);
3335
if (this.wasNullFlag) {
3339
if (!field.isUnsigned() || tinyintVal >= 0) {
3340
return String.valueOf(tinyintVal);
3343
short unsignedTinyVal = (short) (tinyintVal & 0xff);
3345
return String.valueOf(unsignedTinyVal);
3347
case Types.SMALLINT:
3349
int intVal = getNativeInt(columnIndex, false);
3351
if (this.wasNullFlag) {
3355
if (!field.isUnsigned() || intVal >= 0) {
3356
return String.valueOf(intVal);
3359
intVal = intVal & 0xffff;
3361
return String.valueOf(intVal);
3364
intVal = getNativeInt(columnIndex, false);
3366
if (this.wasNullFlag) {
3370
if (!field.isUnsigned() || intVal >= 0
3371
|| field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
3373
return String.valueOf(intVal);
3376
long longVal = intVal & 0xffffffffL;
3378
return String.valueOf(longVal);
3382
if (!field.isUnsigned()) {
3383
longVal = getNativeLong(columnIndex, false, true);
3385
if (this.wasNullFlag) {
3389
return String.valueOf(longVal);
3392
longVal = getNativeLong(columnIndex, false, false);
3394
if (this.wasNullFlag) {
3398
return String.valueOf(convertLongToUlong(longVal));
3400
float floatVal = getNativeFloat(columnIndex);
3402
if (this.wasNullFlag) {
3406
return String.valueOf(floatVal);
3410
double doubleVal = getNativeDouble(columnIndex);
3412
if (this.wasNullFlag) {
3416
return String.valueOf(doubleVal);
3420
String stringVal = StringUtils
3421
.toAsciiString((byte[]) this.thisRow[columnIndex - 1]);
3425
if (stringVal != null) {
3426
this.wasNullFlag = false;
3428
if (stringVal.length() == 0) {
3429
val = new BigDecimal(0);
3431
return val.toString();
3435
val = new BigDecimal(stringVal);
3436
} catch (NumberFormatException ex) {
3437
throw SQLError.createSQLException(
3439
.getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
3442
.getString("ResultSet.___in_column__87")
3443
+ columnIndex + "(" //$NON-NLS-1$
3444
+ this.fields[columnIndex - 1] + ").",
3445
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
3448
return val.toString();
3451
this.wasNullFlag = true;
3457
case Types.LONGVARCHAR:
3459
return extractStringFromNativeColumn(columnIndex, mysqlType);
3461
case Types.VARBINARY:
3462
case Types.LONGVARBINARY:
3464
if (!field.isBlob()) {
3465
return extractStringFromNativeColumn(columnIndex, mysqlType);
3466
} else if (!field.isBinary()) {
3467
return extractStringFromNativeColumn(columnIndex, mysqlType);
3469
byte[] data = getBytes(columnIndex);
3472
if ((data != null) && (data.length >= 2)) {
3473
if ((data[0] == -84) && (data[1] == -19)) {
3474
// Serialized object?
3476
ByteArrayInputStream bytesIn = new ByteArrayInputStream(
3478
ObjectInputStream objIn = new ObjectInputStream(
3480
obj = objIn.readObject();
3483
} catch (ClassNotFoundException cnfe) {
3484
throw SQLError.createSQLException(
3486
.getString("ResultSet.Class_not_found___91") //$NON-NLS-1$
3489
.getString("ResultSet._while_reading_serialized_object_92")); //$NON-NLS-1$
3490
} catch (IOException ex) {
3491
obj = data; // not serialized?
3495
return obj.toString();
3498
return extractStringFromNativeColumn(columnIndex, mysqlType);
3503
// The YEAR datatype needs to be handled differently here.
3504
if (mysqlType == MysqlDefs.FIELD_TYPE_YEAR) {
3505
short shortVal = getNativeShort(columnIndex);
3507
if (!this.connection.getYearIsDateType()) {
3509
if (this.wasNullFlag) {
3513
return String.valueOf(shortVal);
3516
if (field.getLength() == 2) {
3518
if (shortVal <= 69) {
3519
shortVal = (short) (shortVal + 100);
3525
return fastDateCreate(null, shortVal, 1, 1).toString();
3529
Date dt = getNativeDate(columnIndex);
3535
return String.valueOf(dt);
3538
Time tm = getNativeTime(columnIndex, null, this.defaultTimeZone, false);
3544
return String.valueOf(tm);
3546
case Types.TIMESTAMP:
3547
Timestamp tstamp = getNativeTimestamp(columnIndex,
3548
null, this.defaultTimeZone, false);
3550
if (tstamp == null) {
3554
String result = String.valueOf(tstamp);
3556
if (!this.connection.getNoDatetimeStringSync()) {
3560
if (result.endsWith(".0")) {
3561
return result.substring(0, result.length() - 2);
3565
return extractStringFromNativeColumn(columnIndex, mysqlType);
3570
* Get the value of a column in the current row as a java.sql.Date object
3572
* @param columnIndex
3573
* the first column is 1, the second is 2...
3575
* @return the column value; null if SQL NULL
3577
* @exception SQLException
3578
* if a database access error occurs
3580
protected java.sql.Date getNativeDate(int columnIndex) throws SQLException {
3581
return getNativeDate(columnIndex, null);
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
3590
* @param columnIndex
3591
* the first column is 1, the second is 2, ...
3593
* the calendar to use in constructing the date
3595
* @return the column value; if the value is SQL NULL, the result is null
3597
* @exception SQLException
3598
* if a database-access error occurs.
3600
protected java.sql.Date getNativeDate(int columnIndex, TimeZone tz)
3601
throws SQLException {
3603
checkColumnBounds(columnIndex);
3605
int mysqlType = this.fields[columnIndex - 1].getMysqlType();
3607
if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) {
3608
byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
3611
this.wasNullFlag = true;
3616
this.wasNullFlag = false;
3618
java.sql.Date dateToReturn = null;
3628
if (bits.length != 0) {
3629
year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
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;
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);
3653
return fastDateCreate(
3654
getCalendarInstanceForSessionOrNew(), year, month, day);
3657
boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone()));
3659
return (Date)getNativeDateTimeValue(columnIndex, null, Types.DATE, mysqlType,
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 });
3670
String stringVal = getNativeString(columnIndex);
3672
return getDateFromString(stringVal, columnIndex);
3676
* Get the value of a column in the current row as a Java double.
3678
* @param columnIndex
3679
* the first column is 1, the second is 2,...
3681
* @return the column value; 0 if SQL NULL
3683
* @exception SQLException
3684
* if a database access error occurs
3686
protected double getNativeDouble(int columnIndex) throws SQLException {
3688
checkColumnBounds(columnIndex);
3690
columnIndex--; // / JDBC is 1-based
3692
if (this.thisRow[columnIndex] == null) {
3693
this.wasNullFlag = true;
3698
this.wasNullFlag = false;
3700
Field f= this.fields[columnIndex];
3702
switch (f.getMysqlType()) {
3703
case MysqlDefs.FIELD_TYPE_DOUBLE:
3704
byte[] bits = (byte[]) this.thisRow[columnIndex];
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);
3715
return Double.longBitsToDouble(valueAsLong);
3716
case MysqlDefs.FIELD_TYPE_TINY:
3717
if (!f.isUnsigned()) {
3718
return (double) getNativeByte(columnIndex + 1);
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);
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);
3735
return (double) getNativeLong(columnIndex + 1);
3736
case MysqlDefs.FIELD_TYPE_LONGLONG:
3737
valueAsLong = getNativeLong(columnIndex + 1);
3739
if (!f.isUnsigned()) {
3740
return (double) valueAsLong;
3743
BigInteger asBigInt = convertLongToUlong(valueAsLong);
3745
// TODO: Check for overflow
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);
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 });
3765
String stringVal = getNativeString(columnIndex + 1);
3767
return getDoubleFromString(stringVal, columnIndex + 1);
3772
* Get the value of a column in the current row as a Java float.
3774
* @param columnIndex
3775
* the first column is 1, the second is 2,...
3777
* @return the column value; 0 if SQL NULL
3779
* @exception SQLException
3780
* if a database access error occurs
3782
protected float getNativeFloat(int columnIndex) throws SQLException {
3784
checkColumnBounds(columnIndex);
3786
columnIndex--; // / JDBC is 1-based
3788
if (this.thisRow[columnIndex] == null) {
3789
this.wasNullFlag = true;
3794
this.wasNullFlag = false;
3796
Field f = this.fields[columnIndex];
3798
switch (f.getMysqlType()) {
3799
case MysqlDefs.FIELD_TYPE_BIT:
3800
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3803
case MysqlDefs.FIELD_TYPE_DOUBLE:
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!
3809
Double valueAsDouble = new Double(getNativeDouble(columnIndex + 1));
3811
float valueAsFloat = valueAsDouble.floatValue();
3813
if (this.connection.getJdbcCompliantTruncationForReads() &&
3814
valueAsFloat == Float.NEGATIVE_INFINITY ||
3815
valueAsFloat == Float.POSITIVE_INFINITY) {
3816
throwRangeException(valueAsDouble.toString(),
3817
columnIndex + 1, Types.FLOAT);
3820
return (float) getNativeDouble(columnIndex + 1);
3821
case MysqlDefs.FIELD_TYPE_TINY:
3822
if (!f.isUnsigned()) {
3823
return (float) getNativeByte(columnIndex + 1);
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);
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);
3840
return (float) getNativeLong(columnIndex + 1);
3841
case MysqlDefs.FIELD_TYPE_LONGLONG:
3842
valueAsLong = getNativeLong(columnIndex + 1);
3844
if (!f.isUnsigned()) {
3845
return (float) valueAsLong;
3848
BigInteger asBigInt = convertLongToUlong(valueAsLong);
3850
// TODO: Check for overflow
3852
return asBigInt.floatValue();
3853
case MysqlDefs.FIELD_TYPE_FLOAT:
3854
byte[] bits = (byte[]) this.thisRow[columnIndex];
3856
int asInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
3857
| ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
3859
return Float.intBitsToFloat(asInt);
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 });
3874
String stringVal = getNativeString(columnIndex + 1);
3876
return getFloatFromString(stringVal, columnIndex + 1);
3881
* Get the value of a column in the current row as a Java int.
3883
* @param columnIndex
3884
* the first column is 1, the second is 2,...
3886
* @return the column value; 0 if SQL NULL
3888
* @exception SQLException
3889
* if a database access error occurs
3891
protected int getNativeInt(int columnIndex) throws SQLException {
3892
return getNativeInt(columnIndex, true);
3895
protected int getNativeInt(int columnIndex, boolean overflowCheck) throws SQLException {
3897
checkColumnBounds(columnIndex);
3899
columnIndex--; // / JDBC is 1-based
3901
if (this.thisRow[columnIndex] == null) {
3902
this.wasNullFlag = true;
3907
this.wasNullFlag = false;
3909
Field f = this.fields[columnIndex];
3911
switch (f.getMysqlType()) {
3912
case MysqlDefs.FIELD_TYPE_BIT:
3913
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
3915
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3916
(valueAsLong < Integer.MIN_VALUE
3917
|| valueAsLong > Integer.MAX_VALUE)) {
3918
throwRangeException(String.valueOf(valueAsLong), columnIndex + 1,
3922
return (short)valueAsLong;
3923
case MysqlDefs.FIELD_TYPE_TINY:
3924
byte tinyintVal = getNativeByte(columnIndex + 1, false);
3926
if (!f.isUnsigned() || tinyintVal >= 0) {
3930
return tinyintVal + 256;
3931
case MysqlDefs.FIELD_TYPE_SHORT:
3932
case MysqlDefs.FIELD_TYPE_YEAR:
3933
short asShort = getNativeShort(columnIndex + 1, false);
3935
if (!f.isUnsigned() || asShort >= 0) {
3939
return asShort + 65536;
3940
case MysqlDefs.FIELD_TYPE_INT24:
3941
case MysqlDefs.FIELD_TYPE_LONG:
3942
byte[] bits = (byte[]) this.thisRow[columnIndex];
3944
int valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
3945
| ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
3947
if (!f.isUnsigned()) {
3951
valueAsLong = (valueAsInt >= 0) ?
3952
valueAsInt : valueAsInt + 4294967296L;
3954
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
3955
valueAsLong > Integer.MAX_VALUE) {
3956
throwRangeException(String.valueOf(valueAsLong),
3957
columnIndex + 1, Types.INTEGER);
3960
return (int)valueAsLong;
3961
case MysqlDefs.FIELD_TYPE_LONGLONG:
3962
valueAsLong = getNativeLong(columnIndex + 1, false, true);
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);
3972
return (int) valueAsLong;
3973
case MysqlDefs.FIELD_TYPE_DOUBLE:
3974
double valueAsDouble = getNativeDouble(columnIndex + 1);
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);
3984
return (int) valueAsDouble;
3985
case MysqlDefs.FIELD_TYPE_FLOAT:
3986
valueAsDouble = getNativeFloat(columnIndex + 1);
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);
3996
return (int) valueAsDouble;
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 });
4011
String stringVal = getNativeString(columnIndex + 1);
4013
return getIntFromString(stringVal, columnIndex + 1);
4018
* Get the value of a column in the current row as a Java long.
4020
* @param columnIndex
4021
* the first column is 1, the second is 2,...
4023
* @return the column value; 0 if SQL NULL
4025
* @exception SQLException
4026
* if a database access error occurs
4028
protected long getNativeLong(int columnIndex) throws SQLException {
4029
return getNativeLong(columnIndex, true, true);
4032
protected long getNativeLong(int columnIndex, boolean overflowCheck,
4033
boolean expandUnsignedLong) throws SQLException {
4035
checkColumnBounds(columnIndex);
4037
columnIndex--; // / JDBC is 1-based
4039
if (this.thisRow[columnIndex] == null) {
4040
this.wasNullFlag = true;
4045
this.wasNullFlag = false;
4047
Field f = this.fields[columnIndex];
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);
4057
return getNativeInt(columnIndex + 1);
4058
case MysqlDefs.FIELD_TYPE_SHORT:
4059
if (!f.isUnsigned()) {
4060
return getNativeShort(columnIndex + 1);
4063
return getNativeInt(columnIndex + 1, false);
4064
case MysqlDefs.FIELD_TYPE_YEAR:
4066
return getNativeShort(columnIndex + 1);
4067
case MysqlDefs.FIELD_TYPE_INT24:
4068
case MysqlDefs.FIELD_TYPE_LONG:
4069
int asInt = getNativeInt(columnIndex + 1, false);
4071
if (!f.isUnsigned() || asInt >= 0) {
4075
return asInt + 4294967296L;
4076
case MysqlDefs.FIELD_TYPE_LONGLONG:
4078
byte[] bits = (byte[]) this.thisRow[columnIndex];
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);
4089
if (!f.isUnsigned() || !expandUnsignedLong) {
4093
BigInteger asBigInt = convertLongToUlong(valueAsLong);
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);
4102
return getLongFromString(asBigInt.toString(), columnIndex + 1);
4104
case MysqlDefs.FIELD_TYPE_DOUBLE:
4105
double valueAsDouble = getNativeDouble(columnIndex + 1);
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);
4115
return (long) valueAsDouble;
4116
case MysqlDefs.FIELD_TYPE_FLOAT:
4117
valueAsDouble = getNativeFloat(columnIndex + 1);
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);
4127
return (long) valueAsDouble;
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 });
4141
String stringVal = getNativeString(columnIndex + 1);
4143
return getLongFromString(stringVal, columnIndex + 1);
4148
* JDBC 2.0 Get a REF(<structured-type>) column.
4151
* the first column is 1, the second is 2, ...
4153
* @return an object representing data of an SQL REF type
4155
* @throws SQLException
4156
* as this is not implemented
4157
* @throws NotImplemented
4160
protected java.sql.Ref getNativeRef(int i) throws SQLException {
4161
throw new NotImplemented();
4165
* Get the value of a column in the current row as a Java short.
4167
* @param columnIndex
4168
* the first column is 1, the second is 2,...
4170
* @return the column value; 0 if SQL NULL
4172
* @exception SQLException
4173
* if a database access error occurs
4175
protected short getNativeShort(int columnIndex) throws SQLException {
4176
return getNativeShort(columnIndex, true);
4179
protected short getNativeShort(int columnIndex, boolean overflowCheck) throws SQLException {
4181
checkColumnBounds(columnIndex);
4183
columnIndex--; // / JDBC is 1-based
4185
if (this.thisRow[columnIndex] == null) {
4186
this.wasNullFlag = true;
4191
this.wasNullFlag = false;
4193
Field f = this.fields[columnIndex];
4195
switch (f.getMysqlType()) {
4197
case MysqlDefs.FIELD_TYPE_TINY:
4198
byte tinyintVal = getNativeByte(columnIndex + 1, false);
4200
if (!f.isUnsigned() || tinyintVal >= 0) {
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];
4209
short asShort = (short) ((bits[0] & 0xff) | ((bits[1] & 0xff) << 8));
4211
if (!f.isUnsigned()) {
4215
int valueAsInt = asShort & 0xffff;
4217
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
4218
valueAsInt > Short.MAX_VALUE) {
4219
throwRangeException(String.valueOf(valueAsInt),
4220
columnIndex + 1, Types.SMALLINT);
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);
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);
4236
return (short)valueAsInt;
4239
long valueAsLong = getNativeLong(columnIndex + 1, false, true);
4241
if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
4242
valueAsLong > Short.MAX_VALUE) {
4243
throwRangeException(String.valueOf(valueAsLong),
4244
columnIndex + 1, Types.SMALLINT);
4247
return (short)valueAsLong;
4249
case MysqlDefs.FIELD_TYPE_LONGLONG:
4250
valueAsLong = getNativeLong(columnIndex + 1, false, false);
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);
4261
return (short) valueAsLong;
4264
BigInteger asBigInt = convertLongToUlong(valueAsLong);
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);
4273
return (short)getIntFromString(asBigInt.toString(), columnIndex + 1);
4275
case MysqlDefs.FIELD_TYPE_DOUBLE:
4276
double valueAsDouble = getNativeDouble(columnIndex + 1);
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);
4286
return (short) valueAsDouble;
4287
case MysqlDefs.FIELD_TYPE_FLOAT:
4288
float valueAsFloat = getNativeFloat(columnIndex + 1);
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);
4298
return (short) valueAsFloat;
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 });
4312
String stringVal = getNativeString(columnIndex + 1);
4314
return getShortFromString(stringVal, columnIndex + 1);
4319
* Get the value of a column in the current row as a Java String
4321
* @param columnIndex
4322
* the first column is 1, the second is 2...
4324
* @return the column value, null for SQL NULL
4326
* @exception SQLException
4327
* if a database access error occurs
4329
protected String getNativeString(int columnIndex) throws SQLException {
4331
checkColumnBounds(columnIndex);
4333
if (this.fields == null) {
4334
throw SQLError.createSQLException(
4336
.getString("ResultSet.Query_generated_no_fields_for_ResultSet_133"), //$NON-NLS-1$
4337
SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
4341
if (this.thisRow[columnIndex - 1] == null) {
4342
this.wasNullFlag = true;
4347
this.wasNullFlag = false;
4348
} catch (NullPointerException E) {
4349
this.wasNullFlag = true;
4354
String stringVal = null;
4356
if (this.thisRow[columnIndex - 1] instanceof String) {
4357
return (String) this.thisRow[columnIndex - 1];
4360
Field field = this.fields[columnIndex - 1];
4362
// TODO: Check Types Here.
4363
stringVal = getNativeConvertToString(columnIndex, field);
4365
if (field.isZeroFill() && (stringVal != null)) {
4366
int origLength = stringVal.length();
4368
StringBuffer zeroFillBuf = new StringBuffer(origLength);
4370
long numZeros = field.getLength() - origLength;
4372
for (long i = 0; i < numZeros; i++) {
4373
zeroFillBuf.append('0');
4376
zeroFillBuf.append(stringVal);
4378
stringVal = zeroFillBuf.toString();
4385
private Time getNativeTime(int columnIndex, Calendar targetCalendar,
4386
TimeZone tz, boolean rollForward)
4387
throws SQLException {
4389
checkColumnBounds(columnIndex);
4391
if (this.thisRow[columnIndex - 1] == null) {
4392
this.wasNullFlag = true;
4396
this.wasNullFlag = false;
4399
int mysqlType = this.fields[columnIndex - 1].getMysqlType();
4401
if (mysqlType == MysqlDefs.FIELD_TYPE_TIME) {
4403
byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
4405
int length = bits.length;
4411
// bits[0] // skip tm->neg
4412
// binaryData.readLong(); // skip daysPart
4418
Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
4420
synchronized (sessionCalendar) {
4421
Time time = TimeUtil
4422
.fastTimeCreate(sessionCalendar, hour,
4425
Time adjustedTime = TimeUtil.changeTimezone(this.connection,
4429
this.connection.getServerTimezoneTZ(), tz, rollForward);
4431
return adjustedTime;
4435
return (Time)getNativeDateTimeValue(columnIndex, targetCalendar,
4436
Types.TIME, mysqlType,
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 });
4448
String strTime = getNativeString(columnIndex);
4450
return getTimeFromString(strTime, targetCalendar, columnIndex, tz, rollForward);
4453
private Timestamp getNativeTimestamp(int columnIndex,
4454
Calendar targetCalendar,
4456
boolean rollForward) throws SQLException {
4458
checkColumnBounds(columnIndex);
4460
if (this.thisRow[columnIndex - 1] == null) {
4461
this.wasNullFlag = true;
4466
this.wasNullFlag = false;
4468
int mysqlType = this.fields[columnIndex - 1].getMysqlType();
4470
switch (mysqlType) {
4471
case MysqlDefs.FIELD_TYPE_DATETIME:
4472
case MysqlDefs.FIELD_TYPE_TIMESTAMP:
4473
byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
4475
int length = bits.length;
4488
year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
4499
nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8)
4500
| ((bits[9] & 0xff) << 16)
4501
| ((bits[10] & 0xff) << 24);
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;
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);
4523
Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
4524
this.connection.getUtcCalendar() :
4525
getCalendarInstanceForSessionOrNew();
4527
synchronized (sessionCalendar) {
4528
Timestamp ts = fastTimestampCreate(
4529
sessionCalendar, year, month, day,
4530
hour, minute, seconds, nanos);
4532
Timestamp adjustedTs = TimeUtil.changeTimezone(
4533
this.connection, sessionCalendar,
4536
this.connection.getServerTimezoneTZ(), tz, rollForward);
4542
return (Timestamp)getNativeDateTimeValue(columnIndex, targetCalendar,
4543
Types.TIMESTAMP, mysqlType,
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 });
4557
String strTimestamp = getNativeString(columnIndex);
4559
return getTimestampFromString(columnIndex, targetCalendar, strTimestamp, tz,
4563
// ---------------------------------------------------------------------
4565
// ---------------------------------------------------------------------
4568
* A column value can also be retrieved as a stream of Unicode characters.
4569
* We implement this as a binary stream.
4571
* @param columnIndex
4572
* the first column is 1, the second is 2...
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
4578
* @exception SQLException
4579
* if a database access error occurs
4581
* @see getAsciiStream
4582
* @see getBinaryStream
4584
protected InputStream getNativeUnicodeStream(int columnIndex)
4585
throws SQLException {
4588
return getBinaryStream(columnIndex);
4592
* @see ResultSet#getURL(int)
4594
protected URL getNativeURL(int colIndex) throws SQLException {
4595
String val = getString(colIndex);
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$
4613
* @return Returns the nextResultSet, if any, null if none exists.
4615
protected ResultSet getNextResultSet() {
4616
return this.nextResultSet;
4620
* Get the value of a column in the current row as a Java object
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.
4630
* This method may also be used to read database specific abstract data
4634
* @param columnIndex
4635
* the first column is 1, the second is 2...
4637
* @return a Object holding the column value
4639
* @exception SQLException
4640
* if a database access error occurs
4642
public Object getObject(int columnIndex) throws SQLException {
4646
if (this.thisRow[columnIndex - 1] == null) {
4647
this.wasNullFlag = true;
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$
4659
this.wasNullFlag = false;
4662
field = this.fields[columnIndex - 1];
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.
4670
if (this.isBinaryEncoded
4671
&& !(this.thisRow[columnIndex - 1] instanceof byte[])) {
4674
// Special case here...If this is a 'bit' type, it will actually
4676
// been returned as an Integer by the server...
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
4682
return new Boolean(getBoolean(columnIndex));
4685
Object columnValue = this.thisRow[columnIndex - 1];
4687
if (columnValue == null) {
4688
this.wasNullFlag = true;
4696
switch (field.getSQLType()) {
4699
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT
4700
&& !field.isSingleBit()) {
4701
return getBytes(columnIndex);
4704
// valueOf would be nicer here, but it isn't
4705
// present in JDK-1.3.1, which is what the CTS
4707
return new Boolean(getBoolean(columnIndex));
4710
if (!field.isUnsigned()) {
4711
return new Integer(getByte(columnIndex));
4714
return new Integer(getInt(columnIndex));
4716
case Types.SMALLINT:
4718
return new Integer(getInt(columnIndex));
4722
if (!field.isUnsigned() ||
4723
field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
4724
return new Integer(getInt(columnIndex));
4727
return new Long(getLong(columnIndex));
4731
if (!field.isUnsigned()) {
4732
return new Long(getLong(columnIndex));
4735
String stringVal = getString(columnIndex);
4737
if (stringVal == null) {
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$
4752
stringVal = getString(columnIndex);
4756
if (stringVal != null) {
4757
if (stringVal.length() == 0) {
4758
val = new BigDecimal(0);
4764
val = new BigDecimal(stringVal);
4765
} catch (NumberFormatException ex) {
4766
throw SQLError.createSQLException(
4768
.getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
4771
.getString("ResultSet.___in_column__87")
4772
+ columnIndex + "(" //$NON-NLS-1$
4773
+ this.fields[columnIndex - 1] + ").",
4774
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
4783
return new Float(getFloat(columnIndex));
4787
return new Double(getDouble(columnIndex));
4791
if (!field.isOpaqueBinary()) {
4792
return getString(columnIndex);
4795
return getBytes(columnIndex);
4796
case Types.LONGVARCHAR:
4797
if (!field.isOpaqueBinary()) {
4798
return getStringForClob(columnIndex);
4801
return getBytes(columnIndex);
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);
4811
if (this.connection.getAutoDeserialize()) {
4814
if ((data != null) && (data.length >= 2)) {
4815
if ((data[0] == -84) && (data[1] == -19)) {
4816
// Serialized object?
4818
ByteArrayInputStream bytesIn = new ByteArrayInputStream(
4820
ObjectInputStream objIn = new ObjectInputStream(
4822
obj = objIn.readObject();
4825
} catch (ClassNotFoundException cnfe) {
4826
throw SQLError.createSQLException(
4828
.getString("ResultSet.Class_not_found___91") //$NON-NLS-1$
4831
.getString("ResultSet._while_reading_serialized_object_92")); //$NON-NLS-1$
4832
} catch (IOException ex) {
4833
obj = data; // not serialized?
4836
return getString(columnIndex);
4847
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR
4848
&& !this.connection.getYearIsDateType()) {
4849
return new Short(getShort(columnIndex));
4852
return getDate(columnIndex);
4855
return getTime(columnIndex);
4857
case Types.TIMESTAMP:
4858
return getTimestamp(columnIndex);
4861
return getString(columnIndex);
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
4871
* the first column is 1, the second is 2, ...
4873
* the mapping from SQL type names to Java classes
4875
* @return an object representing the SQL value
4877
* @throws SQLException
4878
* because this is not implemented
4880
public Object getObject(int i, java.util.Map map) throws SQLException {
4881
return getObject(i);
4885
* Get the value of a column in the current row as a Java object
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.
4895
* This method may also be used to read database specific abstract data
4900
* is the SQL name of the column
4902
* @return a Object holding the column value
4904
* @exception SQLException
4905
* if a database access error occurs
4907
public Object getObject(String columnName) throws SQLException {
4908
return getObject(findColumn(columnName));
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
4919
* the mapping from SQL type names to Java classes
4921
* @return an object representing the SQL value
4923
* @throws SQLException
4924
* as this is not implemented
4926
public Object getObject(String colName, java.util.Map map)
4927
throws SQLException {
4928
return getObject(findColumn(colName), map);
4931
protected Object getObjectStoredProc(int columnIndex, int desiredSqlType)
4932
throws SQLException {
4936
if (this.thisRow[columnIndex - 1] == null) {
4937
this.wasNullFlag = true;
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$
4949
this.wasNullFlag = false;
4952
field = this.fields[columnIndex - 1];
4954
switch (desiredSqlType) {
4957
// valueOf would be nicer here, but it isn't
4958
// present in JDK-1.3.1, which is what the CTS
4960
return new Boolean(getBoolean(columnIndex));
4963
return new Integer(getInt(columnIndex));
4965
case Types.SMALLINT:
4966
return new Integer(getInt(columnIndex));
4970
if (!field.isUnsigned() ||
4971
field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) {
4972
return new Integer(getInt(columnIndex));
4975
return new Long(getLong(columnIndex));
4979
if (field.isUnsigned()) {
4980
return getBigDecimal(columnIndex);
4983
return new Long(getLong(columnIndex));
4988
String stringVal = getString(columnIndex);
4991
if (stringVal != null) {
4992
if (stringVal.length() == 0) {
4993
val = new BigDecimal(0);
4999
val = new BigDecimal(stringVal);
5000
} catch (NumberFormatException ex) {
5001
throw SQLError.createSQLException(
5003
.getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$
5006
.getString("ResultSet.___in_column__87")
5007
+ columnIndex + "(" //$NON-NLS-1$
5008
+ this.fields[columnIndex - 1] + ").",
5009
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5018
return new Float(getFloat(columnIndex));
5022
if (!this.connection.getRunningCTS13()) {
5023
return new Double(getFloat(columnIndex));
5025
return new Float(getFloat(columnIndex)); // NB - bug in JDBC
5028
// to JDBC spec, FLOAT type should return DOUBLE
5029
// but causes ClassCastException in CTS :(
5032
return new Double(getDouble(columnIndex));
5036
return getString(columnIndex);
5037
case Types.LONGVARCHAR:
5038
return getStringForClob(columnIndex);
5040
case Types.VARBINARY:
5041
case Types.LONGVARBINARY:
5042
return getBytes(columnIndex);
5045
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR
5046
&& !this.connection.getYearIsDateType()) {
5047
return new Short(getShort(columnIndex));
5050
return getDate(columnIndex);
5053
return getTime(columnIndex);
5055
case Types.TIMESTAMP:
5056
return getTimestamp(columnIndex);
5059
return getString(columnIndex);
5063
protected Object getObjectStoredProc(int i, java.util.Map map,
5064
int desiredSqlType) throws SQLException {
5065
return getObjectStoredProc(i, desiredSqlType);
5068
protected Object getObjectStoredProc(String columnName, int desiredSqlType)
5069
throws SQLException {
5070
return getObjectStoredProc(findColumn(columnName), desiredSqlType);
5073
protected Object getObjectStoredProc(String colName, java.util.Map map,
5074
int desiredSqlType) throws SQLException {
5075
return getObjectStoredProc(findColumn(colName), map, desiredSqlType);
5079
* JDBC 2.0 Get a REF(<structured-type>) column.
5082
* the first column is 1, the second is 2, ...
5084
* @return an object representing data of an SQL REF type
5086
* @throws SQLException
5087
* as this is not implemented
5088
* @throws NotImplemented
5091
public java.sql.Ref getRef(int i) throws SQLException {
5092
checkColumnBounds(i);
5093
throw new NotImplemented();
5097
* JDBC 2.0 Get a REF(<structured-type>) column.
5102
* @return an object representing data of an SQL REF type
5104
* @throws SQLException
5105
* as this method is not implemented.
5106
* @throws NotImplemented
5109
public java.sql.Ref getRef(String colName) throws SQLException {
5110
return getRef(findColumn(colName));
5117
* Determine the current row number. The first row is number 1, the second
5121
* @return the current row number, else return 0 if there is no current row
5123
* @exception SQLException
5124
* if a database-access error occurs.
5126
public int getRow() throws SQLException {
5129
int currentRowNumber = this.rowData.getCurrentRowNumber();
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()) {
5139
row = currentRowNumber + 1;
5142
// dynamic (streaming) can not
5143
row = currentRowNumber + 1;
5150
* Returns the server info (if any), or null if none.
5152
* @return server info created for this ResultSet
5154
protected String getServerInfo() {
5155
return this.serverInfo;
5158
private long getNumericRepresentationOfSQLBitType(int columnIndex) throws SQLException {
5160
if (this.fields[columnIndex - 1].isSingleBit() ||
5161
((byte[])this.thisRow[columnIndex - 1]).length == 1) {
5162
return ((byte[])this.thisRow[columnIndex - 1])[0];
5166
byte[] asBytes = (byte[])this.thisRow[columnIndex - 1];
5171
long[] steps = new long[asBytes.length];
5173
for (int i = asBytes.length - 1; i >= 0; i--) {
5174
steps[i] = (long)(asBytes[i] & 0xff) << shift;
5178
long valueAsLong = 0;
5180
for (int i = 0; i < asBytes.length; i++) {
5181
valueAsLong |= steps[i];
5188
* Get the value of a column in the current row as a Java short.
5190
* @param columnIndex
5191
* the first column is 1, the second is 2,...
5193
* @return the column value; 0 if SQL NULL
5195
* @exception SQLException
5196
* if a database access error occurs
5198
public short getShort(int columnIndex) throws SQLException {
5199
if (!this.isBinaryEncoded) {
5202
if (this.connection.getUseFastIntParsing()) {
5204
checkColumnBounds(columnIndex);
5207
if (this.thisRow[columnIndex - 1] == null) {
5208
this.wasNullFlag = true;
5210
this.wasNullFlag = false;
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$
5222
if (this.wasNullFlag) {
5226
byte[] shortAsBytes = (byte[]) this.thisRow[columnIndex - 1];
5228
if (shortAsBytes.length == 0) {
5229
return (short) convertToZeroWithEmptyCheck();
5232
boolean needsFullParse = false;
5234
for (int i = 0; i < shortAsBytes.length; i++) {
5235
if (((char) shortAsBytes[i] == 'e')
5236
|| ((char) shortAsBytes[i] == 'E')) {
5237
needsFullParse = true;
5243
if (!needsFullParse) {
5245
return parseShortWithOverflowCheck(columnIndex,
5246
shortAsBytes, null);
5247
} catch (NumberFormatException nfe) {
5249
// To do: Warn of over/underflow???
5250
return parseShortAsDouble(columnIndex, new String(
5252
} catch (NumberFormatException newNfe) {
5253
; // ignore, it's not a number
5256
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5257
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
5259
if (this.connection.getJdbcCompliantTruncationForReads() &&
5260
(valueAsLong < Short.MIN_VALUE
5261
|| valueAsLong > Short.MAX_VALUE)) {
5262
throwRangeException(String.valueOf(valueAsLong), columnIndex,
5266
return (short)valueAsLong;
5269
throw SQLError.createSQLException(
5271
.getString("ResultSet.Invalid_value_for_getShort()_-____96")
5272
+ new String(shortAsBytes) //$NON-NLS-1$
5274
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5282
val = getString(columnIndex);
5284
if ((val != null)) {
5286
if (val.length() == 0) {
5287
return (short) convertToZeroWithEmptyCheck();
5290
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
5291
&& (val.indexOf(".") == -1)) {
5292
return parseShortWithOverflowCheck(columnIndex, null,
5296
// Convert floating point
5297
return parseShortAsDouble(columnIndex, val);
5300
return 0; // for NULL
5301
} catch (NumberFormatException nfe) {
5303
return parseShortAsDouble(columnIndex, val);
5304
} catch (NumberFormatException newNfe) {
5305
; // ignore, it's not a number
5308
if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5309
long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex);
5311
if (this.connection.getJdbcCompliantTruncationForReads() &&
5312
(valueAsLong < Short.MIN_VALUE
5313
|| valueAsLong > Short.MAX_VALUE)) {
5314
throwRangeException(String.valueOf(valueAsLong), columnIndex,
5318
return (short)valueAsLong;
5321
throw SQLError.createSQLException(
5323
.getString("ResultSet.Invalid_value_for_getShort()_-____96")
5325
+ "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5329
return getNativeShort(columnIndex);
5338
* @return DOCUMENT ME!
5340
* @throws SQLException
5343
public short getShort(String columnName) throws SQLException {
5344
return getShort(findColumn(columnName));
5347
private final short getShortFromString(String val, int columnIndex)
5348
throws SQLException {
5350
if ((val != null)) {
5352
if (val.length() == 0) {
5353
return (short) convertToZeroWithEmptyCheck();
5356
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
5357
&& (val.indexOf(".") == -1)) {
5358
return parseShortWithOverflowCheck(columnIndex, null, val);
5361
// Convert floating point
5362
return parseShortAsDouble(columnIndex, val);
5365
return 0; // for NULL
5366
} catch (NumberFormatException nfe) {
5368
return parseShortAsDouble(columnIndex, val);
5369
} catch (NumberFormatException newNfe) {
5370
; // ignore, it's not a number
5373
throw SQLError.createSQLException(
5375
.getString("ResultSet.Invalid_value_for_getShort()_-____217")
5377
+ Messages.getString("ResultSet.___in_column__218")
5378
+ columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
5383
* JDBC 2.0 Return the Statement that produced the ResultSet.
5385
* @return the Statment that produced the result set, or null if the result
5386
* was produced some other way.
5388
* @exception SQLException
5389
* if a database-access error occurs
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);
5401
if (this.wrapperStatement != null) {
5402
return this.wrapperStatement;
5405
return this.owningStatement;
5409
* Get the value of a column in the current row as a Java String
5411
* @param columnIndex
5412
* the first column is 1, the second is 2...
5414
* @return the column value, null for SQL NULL
5416
* @exception SQLException
5417
* if a database access error occurs
5419
public String getString(int columnIndex) throws SQLException {
5420
return getStringInternal(columnIndex, true);
5424
* The following routines simply convert the columnName into a columnIndex
5425
* and then call the appropriate routine above.
5428
* is the SQL name of the column
5430
* @return the column value
5432
* @exception SQLException
5433
* if a database access error occurs
5435
public String getString(String columnName) throws SQLException {
5436
return getString(findColumn(columnName));
5439
private String getStringForClob(int columnIndex) throws SQLException {
5440
String asString = null;
5442
String forcedEncoding =
5443
this.connection.getClobCharacterEncoding();
5445
if (forcedEncoding == null) {
5446
if (!this.isBinaryEncoded) {
5447
asString = getString(columnIndex);
5449
asString = getNativeString(columnIndex);
5453
byte[] asBytes = null;
5455
if (!this.isBinaryEncoded) {
5456
asBytes = getBytes(columnIndex);
5458
asBytes = getNativeBytes(columnIndex, true);
5461
if (asBytes != null) {
5462
asString = new String(asBytes, forcedEncoding);
5464
} catch (UnsupportedEncodingException uee) {
5465
throw SQLError.createSQLException("Unsupported character encoding " +
5466
forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5473
protected String getStringInternal(int columnIndex, boolean checkDateTypes)
5474
throws SQLException {
5475
if (!this.isBinaryEncoded) {
5477
checkColumnBounds(columnIndex);
5479
if (this.fields == null) {
5480
throw SQLError.createSQLException(
5482
.getString("ResultSet.Query_generated_no_fields_for_ResultSet_99"), //$NON-NLS-1$
5483
SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
5487
if (this.thisRow[columnIndex - 1] == null) {
5488
this.wasNullFlag = true;
5493
this.wasNullFlag = false;
5494
} catch (NullPointerException E) {
5495
this.wasNullFlag = true;
5500
String stringVal = null;
5501
columnIndex--; // JDBC is 1-based, Java is not !?
5503
if (this.fields[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) {
5504
if (this.fields[columnIndex].isSingleBit()) {
5505
byte[] asBytes = (byte[])this.thisRow[columnIndex];
5507
if (asBytes.length == 0) {
5508
return String.valueOf(convertToZeroWithEmptyCheck());
5511
return String.valueOf(asBytes[0]);
5514
return String.valueOf(getNumericRepresentationOfSQLBitType(columnIndex + 1));
5517
String encoding = this.fields[columnIndex].getCharacterSet();
5519
if ((this.connection != null) && this.connection.getUseUnicode()) {
5521
if (encoding == null) {
5522
stringVal = new String(
5523
(byte[]) this.thisRow[columnIndex]);
5525
SingleByteCharsetConverter converter = this.connection
5526
.getCharsetConverter(encoding);
5528
if (converter != null) {
5529
stringVal = converter
5530
.toString((byte[]) this.thisRow[columnIndex]);
5532
stringVal = new String(
5533
(byte[]) this.thisRow[columnIndex],
5537
} catch (java.io.UnsupportedEncodingException E) {
5538
throw SQLError.createSQLException(
5540
.getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
5541
+ encoding + "'.", "0S100");
5544
stringVal = StringUtils
5545
.toAsciiString((byte[]) this.thisRow[columnIndex]);
5549
// Special handling for YEAR type from mysql, some people
5550
// want it as a DATE, others want to treat it as a SHORT
5553
if (this.fields[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
5554
if (!this.connection.getYearIsDateType()) {
5558
Date dt = getDateFromString(stringVal, columnIndex + 1);
5561
this.wasNullFlag = true;
5566
this.wasNullFlag = false;
5568
return dt.toString();
5571
// Handles timezone conversion and zero-date behavior
5573
if (checkDateTypes && !this.connection.getNoDatetimeStringSync()) {
5574
switch (this.fields[columnIndex].getSQLType()) {
5576
Time tm = getTimeFromString(stringVal, null, columnIndex + 1,
5577
this.getDefaultTimeZone(), false);
5580
this.wasNullFlag = true;
5585
this.wasNullFlag = false;
5587
return tm.toString();
5590
Date dt = getDateFromString(stringVal, columnIndex + 1);
5593
this.wasNullFlag = true;
5598
this.wasNullFlag = false;
5600
return dt.toString();
5601
case Types.TIMESTAMP:
5602
Timestamp ts = getTimestampFromString(columnIndex + 1,
5603
null, stringVal, this.getDefaultTimeZone(), false);
5606
this.wasNullFlag = true;
5611
this.wasNullFlag = false;
5613
return ts.toString();
5622
return getNativeString(columnIndex);
5626
* Get the value of a column in the current row as a java.sql.Time object
5628
* @param columnIndex
5629
* the first column is 1, the second is 2...
5631
* @return the column value; null if SQL NULL
5633
* @throws java.sql.SQLException
5634
* if a database access error occurs
5636
public Time getTime(int columnIndex) throws java.sql.SQLException {
5637
return getTimeInternal(columnIndex, null, this.getDefaultTimeZone(), false);
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.
5645
* @param columnIndex
5646
* the first column is 1, the second is 2, ...
5648
* the calendar to use in constructing the time
5650
* @return the column value; if the value is SQL NULL, the result is null
5652
* @exception SQLException
5653
* if a database-access error occurs.
5655
public java.sql.Time getTime(int columnIndex, Calendar cal)
5656
throws SQLException {
5657
return getTimeInternal(columnIndex, cal, cal.getTimeZone(), true);
5661
* Get the value of a column in the current row as a java.sql.Time object.
5664
* is the SQL name of the column
5666
* @return the column value; if the value is SQL NULL, the result is null
5668
* @throws java.sql.SQLException
5669
* if a database-access error occurs.
5671
public Time getTime(String columnName) throws java.sql.SQLException {
5672
return getTime(findColumn(columnName));
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.
5681
* is the SQL name of the column
5683
* the calendar to use in constructing the time
5685
* @return the column value; if the value is SQL NULL, the result is null
5687
* @exception SQLException
5688
* if a database-access error occurs.
5690
public java.sql.Time getTime(String columnName, Calendar cal)
5691
throws SQLException {
5692
return getTime(findColumn(columnName), cal);
5695
private Time getTimeFromString(String timeAsString, Calendar targetCalendar,
5698
boolean rollForward) throws SQLException {
5705
if (timeAsString == null) {
5706
this.wasNullFlag = true;
5712
// JDK-6 doesn't like trailing whitespace
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
5719
timeAsString = timeAsString.trim();
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;
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);
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);
5742
this.wasNullFlag = false;
5744
Field timeColField = this.fields[columnIndex - 1];
5746
if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
5748
int length = timeAsString.length();
5753
hr = Integer.parseInt(timeAsString.substring(length - 6,
5755
min = Integer.parseInt(timeAsString.substring(length - 4,
5757
sec = Integer.parseInt(timeAsString.substring(length - 2,
5764
hr = Integer.parseInt(timeAsString.substring(6, 8));
5765
min = Integer.parseInt(timeAsString.substring(8, 10));
5772
throw SQLError.createSQLException(
5774
.getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
5777
+ this.fields[columnIndex - 1] + ").",
5778
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5781
SQLWarning precisionLost = new SQLWarning(
5783
.getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
5786
+ this.fields[columnIndex - 1] + ").");
5788
if (this.warningChain == null) {
5789
this.warningChain = precisionLost;
5791
this.warningChain.setNextWarning(precisionLost);
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));
5798
SQLWarning precisionLost = new SQLWarning(
5800
.getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
5803
+ this.fields[columnIndex - 1] + ").");
5805
if (this.warningChain == null) {
5806
this.warningChain = precisionLost;
5808
this.warningChain.setNextWarning(precisionLost);
5810
} else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
5811
return fastTimeCreate(null, 0, 0, 0); // midnight on the given
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$
5820
+ Messages.getString("ResultSet.___in_column__268")
5821
+ columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
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));
5830
Calendar sessionCalendar = this.getCalendarInstanceForSessionOrNew();
5832
synchronized (sessionCalendar) {
5833
return TimeUtil.changeTimezone(this.connection,
5837
sessionCalendar, hr, min, sec),
5838
this.connection.getServerTimezoneTZ(),
5841
} catch (Exception ex) {
5842
throw SQLError.createSQLException(ex.toString(),
5843
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
5848
* Get the value of a column in the current row as a java.sql.Time object in
5849
* the given timezone
5851
* @param columnIndex
5852
* the first column is 1, the second is 2...
5854
* the Timezone to use
5856
* @return the column value; null if SQL NULL
5858
* @exception java.sql.SQLException
5859
* if a database access error occurs
5861
private Time getTimeInternal(int columnIndex, Calendar targetCalendar,
5863
boolean rollForward) throws java.sql.SQLException {
5864
if (this.isBinaryEncoded) {
5865
return getNativeTime(columnIndex, targetCalendar, tz, rollForward);
5868
String timeAsString = getStringInternal(columnIndex, false);
5870
return getTimeFromString(timeAsString, targetCalendar,
5871
columnIndex, tz, rollForward);
5875
* Get the value of a column in the current row as a java.sql.Timestamp
5878
* @param columnIndex
5879
* the first column is 1, the second is 2...
5881
* @return the column value; null if SQL NULL
5883
* @exception java.sql.SQLException
5884
* if a database access error occurs
5886
public Timestamp getTimestamp(int columnIndex) throws java.sql.SQLException {
5887
return getTimestampInternal(columnIndex, null, this.getDefaultTimeZone(),
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
5897
* @param columnIndex
5898
* the first column is 1, the second is 2, ...
5900
* the calendar to use in constructing the timestamp
5902
* @return the column value; if the value is SQL NULL, the result is null
5904
* @exception SQLException
5905
* if a database-access error occurs.
5907
public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal)
5908
throws SQLException {
5909
return getTimestampInternal(columnIndex, cal, cal.getTimeZone(), true);
5918
* @return DOCUMENT ME!
5920
* @throws java.sql.SQLException
5923
public Timestamp getTimestamp(String columnName)
5924
throws java.sql.SQLException {
5925
return getTimestamp(findColumn(columnName));
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
5935
* is the SQL name of the column
5937
* the calendar to use in constructing the timestamp
5939
* @return the column value; if the value is SQL NULL, the result is null
5941
* @exception SQLException
5942
* if a database-access error occurs.
5944
public java.sql.Timestamp getTimestamp(String columnName, Calendar cal)
5945
throws SQLException {
5946
return getTimestamp(findColumn(columnName), cal);
5949
private Timestamp getTimestampFromString(int columnIndex,
5950
Calendar targetCalendar,
5951
String timestampValue, TimeZone tz, boolean rollForward)
5952
throws java.sql.SQLException {
5954
this.wasNullFlag = false;
5956
if (timestampValue == null) {
5957
this.wasNullFlag = true;
5963
// JDK-6 doesn't like trailing whitespace
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
5970
timestampValue = timestampValue.trim();
5972
int length = timestampValue.length();
5974
Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
5975
this.connection.getUtcCalendar() :
5976
getCalendarInstanceForSessionOrNew();
5978
synchronized (sessionCalendar) {
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
5986
if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
5987
.equals(this.connection.getZeroDateTimeBehavior())) {
5988
this.wasNullFlag = true;
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);
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);
6002
} else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
6004
return TimeUtil.changeTimezone(this.connection,
6007
fastTimestampCreate(sessionCalendar,
6009
.parseInt(timestampValue.substring(0, 4)), 1,
6010
1, 0, 0, 0, 0), this.connection
6011
.getServerTimezoneTZ(), tz, rollForward);
6014
if (timestampValue.endsWith(".")) {
6015
timestampValue = timestampValue.substring(0, timestampValue
6019
// Convert from TIMESTAMP or DATE
6029
int year = Integer.parseInt(timestampValue.substring(0, 4));
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,
6037
int seconds = Integer.parseInt(timestampValue.substring(17,
6043
int decimalIndex = timestampValue.lastIndexOf('.');
6045
if (decimalIndex != -1) {
6046
if ((decimalIndex + 2) <= timestampValue.length()) {
6047
nanos = Integer.parseInt(timestampValue
6048
.substring(decimalIndex + 1));
6050
throw new IllegalArgumentException(); // re-thrown
6055
// much better error message
6060
return TimeUtil.changeTimezone(this.connection,
6063
fastTimestampCreate(sessionCalendar, year, month, day, hour,
6064
minutes, seconds, nanos), this.connection
6065
.getServerTimezoneTZ(), tz, rollForward);
6069
int year = Integer.parseInt(timestampValue.substring(0, 4));
6071
.parseInt(timestampValue.substring(4, 6));
6072
int day = Integer.parseInt(timestampValue.substring(6, 8));
6074
.parseInt(timestampValue.substring(8, 10));
6075
int minutes = Integer.parseInt(timestampValue.substring(10,
6077
int seconds = Integer.parseInt(timestampValue.substring(12,
6080
return TimeUtil.changeTimezone(this.connection,
6083
fastTimestampCreate(sessionCalendar, year, month, day, hour,
6084
minutes, seconds, 0), this.connection
6085
.getServerTimezoneTZ(), tz, rollForward);
6089
int year = Integer.parseInt(timestampValue.substring(0, 2));
6092
year = (year + 100);
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,
6101
int seconds = Integer.parseInt(timestampValue.substring(10,
6104
return TimeUtil.changeTimezone(this.connection,
6107
fastTimestampCreate(sessionCalendar, year + 1900, month, day,
6108
hour, minutes, seconds, 0), this.connection
6109
.getServerTimezoneTZ(), tz, rollForward);
6119
if ((this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
6120
|| (timestampValue.indexOf("-") != -1)) {
6121
year = Integer.parseInt(timestampValue.substring(0, 4));
6123
.parseInt(timestampValue.substring(5, 7));
6124
day = Integer.parseInt(timestampValue.substring(8, 10));
6128
year = Integer.parseInt(timestampValue.substring(0, 2));
6131
year = (year + 100);
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,
6141
year += 1900; // two-digit year
6144
return TimeUtil.changeTimezone(this.connection,
6147
fastTimestampCreate(sessionCalendar, year, month, day, hour,
6148
minutes, 0, 0), this.connection
6149
.getServerTimezoneTZ(), tz, rollForward);
6153
if (timestampValue.indexOf(":") != -1) {
6154
int hour = Integer.parseInt(timestampValue.substring(0,
6156
int minutes = Integer.parseInt(timestampValue
6158
int seconds = Integer.parseInt(timestampValue
6162
.changeTimezone(this.connection,
6165
fastTimestampCreate(sessionCalendar, 70, 0, 1,
6166
hour, minutes, seconds, 0),
6167
this.connection.getServerTimezoneTZ(),
6172
int year = Integer.parseInt(timestampValue.substring(0, 4));
6174
.parseInt(timestampValue.substring(4, 6));
6175
int day = Integer.parseInt(timestampValue.substring(6, 8));
6177
return TimeUtil.changeTimezone(this.connection,
6180
fastTimestampCreate(sessionCalendar, year - 1900, month - 1,
6181
day, 0, 0, 0, 0), this.connection
6182
.getServerTimezoneTZ(), tz, rollForward);
6186
int year = Integer.parseInt(timestampValue.substring(0, 2));
6189
year = (year + 100);
6193
.parseInt(timestampValue.substring(2, 4));
6194
int day = Integer.parseInt(timestampValue.substring(4, 6));
6196
return TimeUtil.changeTimezone(this.connection,
6199
fastTimestampCreate(sessionCalendar, year + 1900, month, day,
6200
0, 0, 0, 0), this.connection
6201
.getServerTimezoneTZ(), tz, rollForward);
6205
int year = Integer.parseInt(timestampValue.substring(0, 2));
6208
year = (year + 100);
6212
.parseInt(timestampValue.substring(2, 4));
6214
return TimeUtil.changeTimezone(this.connection,
6217
fastTimestampCreate(sessionCalendar, year + 1900, month, 1, 0,
6218
0, 0, 0), this.connection
6219
.getServerTimezoneTZ(), tz, rollForward);
6223
int year = Integer.parseInt(timestampValue.substring(0, 2));
6226
year = (year + 100);
6229
return TimeUtil.changeTimezone(this.connection,
6232
fastTimestampCreate(null, year + 1900, 1, 1, 0, 0,
6233
0, 0), this.connection
6234
.getServerTimezoneTZ(), tz, rollForward);
6238
throw new java.sql.SQLException(
6239
"Bad format for Timestamp '" + timestampValue
6240
+ "' in column " + columnIndex + ".",
6241
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
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);
6254
* Get the value of a column in the current row as a java.sql.Timestamp
6255
* object in the given timezone
6257
* @param columnIndex
6258
* the first column is 1, the second is 2...
6260
* the timezone to use
6262
* @return the column value; null if SQL NULL
6264
* @exception java.sql.SQLException
6265
* if a database access error occurs
6267
private Timestamp getTimestampInternal(int columnIndex, Calendar targetCalendar,
6269
boolean rollForward) throws java.sql.SQLException {
6270
if (this.isBinaryEncoded) {
6271
return getNativeTimestamp(columnIndex, targetCalendar, tz, rollForward);
6274
String timestampValue = getStringInternal(columnIndex, false);
6276
return getTimestampFromString(columnIndex, targetCalendar,
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.
6285
* @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
6286
* TYPE_SCROLL_SENSITIVE
6288
* @exception SQLException
6289
* if a database-access error occurs
6291
public int getType() throws SQLException {
6292
return this.resultSetType;
6296
* A column value can also be retrieved as a stream of Unicode characters.
6297
* We implement this as a binary stream.
6299
* @param columnIndex
6300
* the first column is 1, the second is 2...
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
6306
* @exception SQLException
6307
* if a database access error occurs
6309
* @see getAsciiStream
6310
* @see getBinaryStream
6313
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
6314
if (!this.isBinaryEncoded) {
6317
return getBinaryStream(columnIndex);
6320
return getNativeBinaryStream(columnIndex);
6329
* @return DOCUMENT ME!
6331
* @throws SQLException
6336
public InputStream getUnicodeStream(String columnName) throws SQLException {
6337
return getUnicodeStream(findColumn(columnName));
6340
long getUpdateCount() {
6341
return this.updateCount;
6344
long getUpdateID() {
6345
return this.updateId;
6349
* @see ResultSet#getURL(int)
6351
public URL getURL(int colIndex) throws SQLException {
6352
String val = getString(colIndex);
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$
6368
* @see ResultSet#getURL(String)
6370
public URL getURL(String colName) throws SQLException {
6371
String val = getString(colName);
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$
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.
6392
* The warning chain is automatically cleared each time a new row is read.
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.
6401
* @return the first java.sql.SQLWarning or null;
6403
* @exception SQLException
6404
* if a database access error occurs.
6406
public java.sql.SQLWarning getWarnings() throws SQLException {
6407
return this.warningChain;
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.
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
6421
public void insertRow() throws SQLException {
6422
throw new NotUpdatable();
6429
* Determine if the cursor is after the last row in the result set.
6432
* @return true if after the last row, false otherwise. Returns false when
6433
* the result set contains no rows.
6435
* @exception SQLException
6436
* if a database-access error occurs.
6438
public boolean isAfterLast() throws SQLException {
6441
boolean b = this.rowData.isAfterLast();
6450
* Determine if the cursor is before the first row in the result set.
6453
* @return true if before the first row, false otherwise. Returns false when
6454
* the result set contains no rows.
6456
* @exception SQLException
6457
* if a database-access error occurs.
6459
public boolean isBeforeFirst() throws SQLException {
6462
return this.rowData.isBeforeFirst();
6469
* Determine if the cursor is on the first row of the result set.
6472
* @return true if on the first row, false otherwise.
6474
* @exception SQLException
6475
* if a database-access error occurs.
6477
public boolean isFirst() throws SQLException {
6480
return this.rowData.isFirst();
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.
6493
* @return true if on the last row, false otherwise.
6495
* @exception SQLException
6496
* if a database-access error occurs.
6498
public boolean isLast() throws SQLException {
6501
return this.rowData.isLast();
6509
private void issueConversionViaParsingWarning(String methodName,
6510
int columnIndex, Object value, Field fieldInfo,
6511
int[] typesWithNoParseConversion) throws SQLException {
6512
StringBuffer message = new StringBuffer();
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");
6526
.append(((com.mysql.jdbc.PreparedStatement) this.owningStatement).originalSql);
6527
message.append("\n\n");
6529
message.append(". ");
6532
message.append("Java class of column type is '");
6534
if (value != null) {
6535
message.append(value.getClass().getName());
6537
message.append(ResultSetMetaData.getClassNameForJavaType(fieldInfo.getSQLType(),
6538
fieldInfo.isUnsigned(),
6539
fieldInfo.getMysqlType(),
6540
fieldInfo.isBinary() || fieldInfo.isBlob(),
6541
fieldInfo.isOpaqueBinary()));
6544
message.append("', MySQL field type is ");
6545
message.append(MysqlDefs.typeToName(fieldInfo.getMysqlType()));
6547
.append(".\n\nTypes that could be converted directly without parsing are:\n");
6549
for (int i = 0; i < typesWithNoParseConversion.length; i++) {
6550
message.append(MysqlDefs.typeToName(typesWithNoParseConversion[i]));
6551
message.append("\n");
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()));
6564
private void issueDataTruncationWarningIfConfigured(int columnIndex,
6565
int readSize, int truncatedToSize) {
6566
DataTruncation dt = new DataTruncation(columnIndex, false, true,
6567
readSize, truncatedToSize);
6574
* Moves to the last row in the result set.
6577
* @return true if on a valid row, false if no rows in the result set.
6579
* @exception SQLException
6580
* if a database-access error occurs, or result set type is
6581
* TYPE_FORWARD_ONLY.
6583
public boolean last() throws SQLException {
6586
if (this.rowData.size() == 0) {
6590
if (this.onInsertRow) {
6591
this.onInsertRow = false;
6594
if (this.doingUpdates) {
6595
this.doingUpdates = false;
6598
this.rowData.beforeLast();
6599
this.thisRow = this.rowData.next();
6604
// /////////////////////////////////////////
6606
// These number conversion routines save
6607
// a ton of "new()s", especially for the heavily
6608
// used getInt() and getDouble() methods
6610
// /////////////////////////////////////////
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.
6616
* @exception SQLException
6617
* if a database-access error occurs, or the result set is
6619
* @throws NotUpdatable
6622
public void moveToCurrentRow() throws SQLException {
6623
throw new NotUpdatable();
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.
6637
* @exception SQLException
6638
* if a database-access error occurs, or the result set is
6640
* @throws NotUpdatable
6643
public void moveToInsertRow() throws SQLException {
6644
throw new NotUpdatable();
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.
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
6657
* @return true if the new current is valid; false if there are no more rows
6659
* @exception SQLException
6660
* if a database access error occurs
6662
public boolean next() throws SQLException {
6665
if (this.onInsertRow) {
6666
this.onInsertRow = false;
6669
if (this.doingUpdates) {
6670
this.doingUpdates = false;
6675
if (!reallyResult()) {
6676
throw SQLError.createSQLException(
6678
.getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"),
6679
SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
6682
if (this.rowData.size() == 0) {
6685
if (!this.rowData.hasNext()) {
6686
// force scroll past end
6687
this.rowData.next();
6691
this.thisRow = this.rowData.next();
6699
private int parseIntAsDouble(int columnIndex, String val)
6700
throws NumberFormatException, SQLException {
6705
double valueAsDouble = Double.parseDouble(val);
6707
if (this.connection.getJdbcCompliantTruncationForReads()) {
6708
if (valueAsDouble < Integer.MIN_VALUE
6709
|| valueAsDouble > Integer.MAX_VALUE) {
6710
throwRangeException(String.valueOf(valueAsDouble), columnIndex,
6715
return (int) valueAsDouble;
6718
private int parseIntWithOverflowCheck(int columnIndex, byte[] valueAsBytes,
6719
String valueAsString) throws NumberFormatException, SQLException {
6723
if (valueAsBytes == null && valueAsString == null) {
6727
if (valueAsBytes != null) {
6728
intValue = StringUtils.getInt(valueAsBytes);
6731
// JDK-6 doesn't like trailing whitespace
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
6738
valueAsString = valueAsString.trim();
6740
intValue = Integer.parseInt(valueAsString);
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);
6749
if (valueAsLong < Integer.MIN_VALUE
6750
|| valueAsLong > Integer.MAX_VALUE) {
6751
throwRangeException(valueAsString == null ? new String(
6752
valueAsBytes) : valueAsString, columnIndex,
6761
private long parseLongAsDouble(int columnIndex, String val)
6762
throws NumberFormatException, SQLException {
6767
double valueAsDouble = Double.parseDouble(val);
6769
if (this.connection.getJdbcCompliantTruncationForReads()) {
6770
if (valueAsDouble < Long.MIN_VALUE
6771
|| valueAsDouble > Long.MAX_VALUE) {
6772
throwRangeException(val, columnIndex, Types.BIGINT);
6776
return (long) valueAsDouble;
6779
private long parseLongWithOverflowCheck(int columnIndex,
6780
byte[] valueAsBytes, String valueAsString, boolean doCheck)
6781
throws NumberFormatException, SQLException {
6785
if (valueAsBytes == null && valueAsString == null) {
6789
if (valueAsBytes != null) {
6790
longValue = StringUtils.getLong(valueAsBytes);
6793
// JDK-6 doesn't like trailing whitespace
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
6800
valueAsString = valueAsString.trim();
6802
longValue = Long.parseLong(valueAsString);
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);
6812
if (valueAsDouble < Long.MIN_VALUE
6813
|| valueAsDouble > Long.MAX_VALUE) {
6814
throwRangeException(valueAsString == null ? new String(
6815
valueAsBytes) : valueAsString, columnIndex,
6824
private short parseShortAsDouble(int columnIndex, String val)
6825
throws NumberFormatException, SQLException {
6830
double valueAsDouble = Double.parseDouble(val);
6832
if (this.connection.getJdbcCompliantTruncationForReads()) {
6833
if (valueAsDouble < Short.MIN_VALUE
6834
|| valueAsDouble > Short.MAX_VALUE) {
6835
throwRangeException(String.valueOf(valueAsDouble), columnIndex,
6840
return (short) valueAsDouble;
6843
private short parseShortWithOverflowCheck(int columnIndex,
6844
byte[] valueAsBytes, String valueAsString)
6845
throws NumberFormatException, SQLException {
6847
short shortValue = 0;
6849
if (valueAsBytes == null && valueAsString == null) {
6853
if (valueAsBytes != null) {
6854
shortValue = StringUtils.getShort(valueAsBytes);
6857
// JDK-6 doesn't like trailing whitespace
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
6864
valueAsString = valueAsString.trim();
6866
shortValue = Short.parseShort(valueAsString);
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);
6875
if (valueAsLong < Short.MIN_VALUE
6876
|| valueAsLong > Short.MAX_VALUE) {
6877
throwRangeException(valueAsString == null ? new String(
6878
valueAsBytes) : valueAsString, columnIndex,
6887
// --------------------------JDBC 2.0-----------------------------------
6888
// ---------------------------------------------------------------------
6889
// Getter's and Setter's
6890
// ---------------------------------------------------------------------
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
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
6902
* @return true if the new current is valid; false if there are no more rows
6904
* @exception java.sql.SQLException
6905
* if a database access error occurs
6907
public boolean prev() throws java.sql.SQLException {
6910
int rowIndex = this.rowData.getCurrentRowNumber();
6912
if ((rowIndex - 1) >= 0) {
6914
this.rowData.setCurrentRow(rowIndex);
6915
this.thisRow = this.rowData.getAt(rowIndex);
6918
} else if ((rowIndex - 1) == -1) {
6920
this.rowData.setCurrentRow(rowIndex);
6921
this.thisRow = null;
6933
* Moves to the previous row in the result set.
6937
* Note: previous() is not the same as relative(-1) since it makes sense to
6938
* call previous() when there is no current row.
6941
* @return true if on a valid row, false if off the result set.
6943
* @exception SQLException
6944
* if a database-access error occurs, or result set type is
6945
* TYPE_FORWAR_DONLY.
6947
public boolean previous() throws SQLException {
6948
if (this.onInsertRow) {
6949
this.onInsertRow = false;
6952
if (this.doingUpdates) {
6953
this.doingUpdates = false;
6960
* Closes this ResultSet and releases resources.
6962
* @param calledExplicitly
6963
* was this called by close()?
6965
* @throws SQLException
6966
* if an error occurs
6968
protected void realClose(boolean calledExplicitly) throws SQLException {
6969
if (this.isClosed) {
6974
if (this.useUsageAdvisor) {
6975
if (!calledExplicitly) {
6976
String message = Messages
6977
.getString("ResultSet.ResultSet_implicitly_closed_by_driver._150") //$NON-NLS-1$
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$
6981
this.eventSink.consumeEvent(new ProfilerEvent(
6982
ProfilerEvent.TYPE_WARN, "",
6983
(this.owningStatement == null) ? "N/A"
6984
: this.owningStatement.currentCatalog,
6986
(this.owningStatement == null) ? (-1)
6987
: this.owningStatement.getId(),
6988
this.resultId, System.currentTimeMillis(), 0, null,
6989
this.pointOfOrigin, message));
6992
if (this.rowData instanceof RowDataStatic && !isLast()
6993
&& !isAfterLast() && (this.rowData.size() != 0)) {
6994
StringBuffer messageBuf = new StringBuffer(
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());
7002
.getString("ResultSet._rows_when_it_was_closed._156")); //$NON-NLS-1$
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$
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$
7013
(this.owningStatement == null) ? (-1)
7014
: this.owningStatement.getId(),
7015
this.resultId, System.currentTimeMillis(), 0, null,
7016
this.pointOfOrigin, messageBuf.toString()));
7020
// Report on any columns that were selected but
7023
if (this.columnUsed.length > 0) {
7024
StringBuffer buf = new StringBuffer(
7026
.getString("ResultSet.The_following_columns_were__160")); //$NON-NLS-1$
7029
.getString("ResultSet._part_of_the_SELECT_statement_for_this_result_set,_but_were_161")); //$NON-NLS-1$
7031
.getString("ResultSet._never_referenced___162")); //$NON-NLS-1$
7033
boolean issueWarn = false;
7035
for (int i = 0; i < this.columnUsed.length; i++) {
7036
if (!this.columnUsed[i]) {
7043
buf.append(this.fields[i].getFullName());
7048
this.eventSink.consumeEvent(new ProfilerEvent(
7049
ProfilerEvent.TYPE_WARN, "",
7050
(this.owningStatement == null) ? "N/A"
7051
: this.owningStatement.currentCatalog,
7053
(this.owningStatement == null) ? (-1)
7054
: this.owningStatement.getId(), 0,
7055
System.currentTimeMillis(), 0, null,
7056
this.pointOfOrigin, buf.toString()));
7061
SQLException exceptionDuringClose = null;
7063
if (this.rowData != null) {
7065
this.rowData.close();
7066
} catch (SQLException sqlEx) {
7067
exceptionDuringClose = sqlEx;
7071
this.rowData = null;
7072
this.defaultTimeZone = null;
7074
this.columnNameToIndex = null;
7075
this.fullColumnNameToIndex = null;
7076
this.eventSink = null;
7077
this.warningChain = null;
7079
if (!this.retainOwningStatement) {
7080
this.owningStatement = null;
7083
this.catalog = null;
7084
this.serverInfo = null;
7085
this.thisRow = null;
7086
this.fastDateCal = null;
7087
this.connection = null;
7089
this.isClosed = true;
7091
if (exceptionDuringClose != null) {
7092
throw exceptionDuringClose;
7097
boolean reallyResult() {
7098
if (this.rowData != null) {
7102
return this.reallyResult;
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
7119
* @exception SQLException
7120
* if a database-access error occurs, or if called when on
7122
* @throws NotUpdatable
7125
public void refreshRow() throws SQLException {
7126
throw new NotUpdatable();
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.
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
7147
* the number of relative rows to move the cursor.
7149
* @return true if on a row, false otherwise.
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.
7155
public boolean relative(int rows) throws SQLException {
7158
if (this.rowData.size() == 0) {
7162
this.rowData.moveRowRelative(rows);
7163
this.thisRow = this.rowData.getAt(this.rowData.getCurrentRowNumber());
7165
return (!this.rowData.isAfterLast() && !this.rowData.isBeforeFirst());
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.
7174
* @return true if deleted and deletes are detected
7176
* @exception SQLException
7177
* if a database-access error occurs
7178
* @throws NotImplemented
7181
* @see DatabaseMetaData#deletesAreDetected
7183
public boolean rowDeleted() throws SQLException {
7184
throw new NotImplemented();
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
7192
* @return true if inserted and inserts are detected
7194
* @exception SQLException
7195
* if a database-access error occurs
7196
* @throws NotImplemented
7199
* @see DatabaseMetaData#insertsAreDetected
7201
public boolean rowInserted() throws SQLException {
7202
throw new NotImplemented();
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.
7209
* @return true if the row has been visibly updated by the owner or another,
7210
* and updates are detected
7212
* @exception SQLException
7213
* if a database-access error occurs
7214
* @throws NotImplemented
7217
* @see DatabaseMetaData#updatesAreDetected
7219
public boolean rowUpdated() throws SQLException {
7220
throw new NotImplemented();
7224
* Flag that this result set is 'binary' encoded (from a PreparedStatement),
7225
* not stored as strings.
7227
protected void setBinaryEncoded() {
7228
this.isBinaryEncoded = true;
7231
private void setDefaultTimeZone(TimeZone defaultTimeZone) {
7232
this.defaultTimeZone = defaultTimeZone;
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
7242
* the direction to fetch rows in.
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.
7250
public void setFetchDirection(int direction) throws SQLException {
7251
if ((direction != FETCH_FORWARD) && (direction != FETCH_REVERSE)
7252
&& (direction != FETCH_UNKNOWN)) {
7253
throw SQLError.createSQLException(
7255
.getString("ResultSet.Illegal_value_for_fetch_direction_64"),
7256
SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
7259
this.fetchDirection = direction;
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.
7271
* the number of rows to fetch
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.
7278
public void setFetchSize(int rows) throws SQLException {
7279
if (rows < 0) { /* || rows > getMaxRows() */
7280
throw SQLError.createSQLException(
7282
.getString("ResultSet.Value_must_be_between_0_and_getMaxRows()_66"), //$NON-NLS-1$
7283
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
7286
this.fetchSize = rows;
7290
* Sets the first character of the query that this result set was created
7294
* the first character of the query...uppercased
7296
protected void setFirstCharOfQuery(char c) {
7297
this.firstCharOfQuery = c;
7303
* @param nextResultSet
7304
* Sets the next result set in the result set chain for multiple
7307
protected void setNextResultSet(ResultSet nextResultSet) {
7308
this.nextResultSet = nextResultSet;
7311
protected void setOwningStatement(com.mysql.jdbc.Statement owningStatement) {
7312
this.owningStatement = owningStatement;
7316
* Sets the concurrency (JDBC2)
7318
* @param concurrencyFlag
7319
* CONCUR_UPDATABLE or CONCUR_READONLY
7321
protected void setResultSetConcurrency(int concurrencyFlag) {
7322
this.resultSetConcurrency = concurrencyFlag;
7326
* Sets the result set type for (JDBC2)
7329
* SCROLL_SENSITIVE or SCROLL_INSENSITIVE (we only support
7330
* SCROLL_INSENSITIVE)
7332
protected void setResultSetType(int typeFlag) {
7333
this.resultSetType = typeFlag;
7337
* Sets server info (if any)
7340
* the server info message
7342
protected void setServerInfo(String info) {
7343
this.serverInfo = info;
7346
void setStatementUsedForFetchingRows(PreparedStatement stmt) {
7347
this.statementUsedForFetchingRows = stmt;
7351
* @param wrapperStatement
7352
* The wrapperStatement to set.
7354
public void setWrapperStatement(java.sql.Statement wrapperStatement) {
7355
this.wrapperStatement = wrapperStatement;
7358
private void throwRangeException(String valueAsString, int columnIndex,
7359
int jdbcType) throws SQLException {
7360
String datatype = null;
7364
datatype = "TINYINT";
7366
case Types.SMALLINT:
7367
datatype = "SMALLINT";
7370
datatype = "INTEGER";
7373
datatype = "BIGINT";
7382
datatype = "DOUBLE";
7385
datatype = "DECIMAL";
7388
datatype = " (JDBC type '" + jdbcType + "')";
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);
7399
* @return DOCUMENT ME!
7401
public String toString() {
7402
if (this.reallyResult) {
7403
return super.toString();
7406
return "Result set representing update count of " + this.updateCount;
7410
* @see ResultSet#updateArray(int, Array)
7412
public void updateArray(int arg0, Array arg1) throws SQLException {
7413
throw new NotImplemented();
7417
* @see ResultSet#updateArray(String, Array)
7419
public void updateArray(String arg0, Array arg1) throws SQLException {
7420
throw new NotImplemented();
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.
7430
* @param columnIndex
7431
* the first column is 1, the second is 2, ...
7433
* the new column value
7435
* the length of the stream
7437
* @exception SQLException
7438
* if a database-access error occurs
7439
* @throws NotUpdatable
7442
public void updateAsciiStream(int columnIndex, java.io.InputStream x,
7443
int length) throws SQLException {
7444
throw new NotUpdatable();
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.
7455
* the name of the column
7457
* the new column value
7461
* @exception SQLException
7462
* if a database-access error occurs
7464
public void updateAsciiStream(String columnName, java.io.InputStream x,
7465
int length) throws SQLException {
7466
updateAsciiStream(findColumn(columnName), x, length);
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.
7475
* @param columnIndex
7476
* the first column is 1, the second is 2, ...
7478
* the new column value
7480
* @exception SQLException
7481
* if a database-access error occurs
7482
* @throws NotUpdatable
7485
public void updateBigDecimal(int columnIndex, BigDecimal x)
7486
throws SQLException {
7487
throw new NotUpdatable();
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.
7497
* the name of the column
7499
* the new column value
7501
* @exception SQLException
7502
* if a database-access error occurs
7504
public void updateBigDecimal(String columnName, BigDecimal x)
7505
throws SQLException {
7506
updateBigDecimal(findColumn(columnName), x);
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.
7516
* @param columnIndex
7517
* the first column is 1, the second is 2, ...
7519
* the new column value
7521
* the length of the stream
7523
* @exception SQLException
7524
* if a database-access error occurs
7525
* @throws NotUpdatable
7528
public void updateBinaryStream(int columnIndex, java.io.InputStream x,
7529
int length) throws SQLException {
7530
throw new NotUpdatable();
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.
7541
* the name of the column
7543
* the new column value
7547
* @exception SQLException
7548
* if a database-access error occurs
7550
public void updateBinaryStream(String columnName, java.io.InputStream x,
7551
int length) throws SQLException {
7552
updateBinaryStream(findColumn(columnName), x, length);
7556
* @see ResultSet#updateBlob(int, Blob)
7558
public void updateBlob(int arg0, java.sql.Blob arg1) throws SQLException {
7559
throw new NotUpdatable();
7563
* @see ResultSet#updateBlob(String, Blob)
7565
public void updateBlob(String arg0, java.sql.Blob arg1) throws SQLException {
7566
throw new NotUpdatable();
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.
7575
* @param columnIndex
7576
* the first column is 1, the second is 2, ...
7578
* the new column value
7580
* @exception SQLException
7581
* if a database-access error occurs
7582
* @throws NotUpdatable
7585
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
7586
throw new NotUpdatable();
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.
7596
* the name of the column
7598
* the new column value
7600
* @exception SQLException
7601
* if a database-access error occurs
7603
public void updateBoolean(String columnName, boolean x) throws SQLException {
7604
updateBoolean(findColumn(columnName), x);
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.
7613
* @param columnIndex
7614
* the first column is 1, the second is 2, ...
7616
* the new column value
7618
* @exception SQLException
7619
* if a database-access error occurs
7620
* @throws NotUpdatable
7623
public void updateByte(int columnIndex, byte x) throws SQLException {
7624
throw new NotUpdatable();
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.
7634
* the name of the column
7636
* the new column value
7638
* @exception SQLException
7639
* if a database-access error occurs
7641
public void updateByte(String columnName, byte x) throws SQLException {
7642
updateByte(findColumn(columnName), x);
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.
7651
* @param columnIndex
7652
* the first column is 1, the second is 2, ...
7654
* the new column value
7656
* @exception SQLException
7657
* if a database-access error occurs
7658
* @throws NotUpdatable
7661
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
7662
throw new NotUpdatable();
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.
7672
* the name of the column
7674
* the new column value
7676
* @exception SQLException
7677
* if a database-access error occurs
7679
public void updateBytes(String columnName, byte[] x) throws SQLException {
7680
updateBytes(findColumn(columnName), x);
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.
7690
* @param columnIndex
7691
* the first column is 1, the second is 2, ...
7693
* the new column value
7695
* the length of the stream
7697
* @exception SQLException
7698
* if a database-access error occurs
7699
* @throws NotUpdatable
7702
public void updateCharacterStream(int columnIndex, java.io.Reader x,
7703
int length) throws SQLException {
7704
throw new NotUpdatable();
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.
7715
* the name of the column
7717
* the stream to update the column with
7721
* @throws SQLException
7722
* if a database-access error occurs
7724
public void updateCharacterStream(String columnName, java.io.Reader reader,
7725
int length) throws SQLException {
7726
updateCharacterStream(findColumn(columnName), reader, length);
7730
* @see ResultSet#updateClob(int, Clob)
7732
public void updateClob(int arg0, java.sql.Clob arg1) throws SQLException {
7733
throw new NotImplemented();
7737
* @see ResultSet#updateClob(String, Clob)
7739
public void updateClob(String columnName, java.sql.Clob clob)
7740
throws SQLException {
7741
updateClob(findColumn(columnName), clob);
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.
7750
* @param columnIndex
7751
* the first column is 1, the second is 2, ...
7753
* the new column value
7755
* @exception SQLException
7756
* if a database-access error occurs
7757
* @throws NotUpdatable
7760
public void updateDate(int columnIndex, java.sql.Date x)
7761
throws SQLException {
7762
throw new NotUpdatable();
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.
7772
* the name of the column
7774
* the new column value
7776
* @exception SQLException
7777
* if a database-access error occurs
7779
public void updateDate(String columnName, java.sql.Date x)
7780
throws SQLException {
7781
updateDate(findColumn(columnName), x);
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.
7790
* @param columnIndex
7791
* the first column is 1, the second is 2, ...
7793
* the new column value
7795
* @exception SQLException
7796
* if a database-access error occurs
7797
* @throws NotUpdatable
7800
public void updateDouble(int columnIndex, double x) throws SQLException {
7801
throw new NotUpdatable();
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.
7811
* the name of the column
7813
* the new column value
7815
* @exception SQLException
7816
* if a database-access error occurs
7818
public void updateDouble(String columnName, double x) throws SQLException {
7819
updateDouble(findColumn(columnName), x);
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.
7828
* @param columnIndex
7829
* the first column is 1, the second is 2, ...
7831
* the new column value
7833
* @exception SQLException
7834
* if a database-access error occurs
7835
* @throws NotUpdatable
7838
public void updateFloat(int columnIndex, float x) throws SQLException {
7839
throw new NotUpdatable();
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.
7849
* the name of the column
7851
* the new column value
7853
* @exception SQLException
7854
* if a database-access error occurs
7856
public void updateFloat(String columnName, float x) throws SQLException {
7857
updateFloat(findColumn(columnName), x);
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.
7866
* @param columnIndex
7867
* the first column is 1, the second is 2, ...
7869
* the new column value
7871
* @exception SQLException
7872
* if a database-access error occurs
7873
* @throws NotUpdatable
7876
public void updateInt(int columnIndex, int x) throws SQLException {
7877
throw new NotUpdatable();
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.
7887
* the name of the column
7889
* the new column value
7891
* @exception SQLException
7892
* if a database-access error occurs
7894
public void updateInt(String columnName, int x) throws SQLException {
7895
updateInt(findColumn(columnName), x);
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.
7904
* @param columnIndex
7905
* the first column is 1, the second is 2, ...
7907
* the new column value
7909
* @exception SQLException
7910
* if a database-access error occurs
7911
* @throws NotUpdatable
7914
public void updateLong(int columnIndex, long x) throws SQLException {
7915
throw new NotUpdatable();
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.
7925
* the name of the column
7927
* the new column value
7929
* @exception SQLException
7930
* if a database-access error occurs
7932
public void updateLong(String columnName, long x) throws SQLException {
7933
updateLong(findColumn(columnName), x);
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.
7942
* @param columnIndex
7943
* the first column is 1, the second is 2, ...
7945
* @exception SQLException
7946
* if a database-access error occurs
7947
* @throws NotUpdatable
7950
public void updateNull(int columnIndex) throws SQLException {
7951
throw new NotUpdatable();
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.
7961
* the name of the column
7963
* @exception SQLException
7964
* if a database-access error occurs
7966
public void updateNull(String columnName) throws SQLException {
7967
updateNull(findColumn(columnName));
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.
7976
* @param columnIndex
7977
* the first column is 1, the second is 2, ...
7979
* the new column value
7981
* @exception SQLException
7982
* if a database-access error occurs
7983
* @throws NotUpdatable
7986
public void updateObject(int columnIndex, Object x) throws SQLException {
7987
throw new NotUpdatable();
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.
7996
* @param columnIndex
7997
* the first column is 1, the second is 2, ...
7999
* the new column value
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.
8005
* @exception SQLException
8006
* if a database-access error occurs
8007
* @throws NotUpdatable
8010
public void updateObject(int columnIndex, Object x, int scale)
8011
throws SQLException {
8012
throw new NotUpdatable();
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.
8022
* the name of the column
8024
* the new column value
8026
* @exception SQLException
8027
* if a database-access error occurs
8029
public void updateObject(String columnName, Object x) throws SQLException {
8030
updateObject(findColumn(columnName), x);
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.
8040
* the name of the column
8042
* the new column value
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.
8048
* @exception SQLException
8049
* if a database-access error occurs
8051
public void updateObject(String columnName, Object x, int scale)
8052
throws SQLException {
8053
updateObject(findColumn(columnName), x);
8057
* @see ResultSet#updateRef(int, Ref)
8059
public void updateRef(int arg0, Ref arg1) throws SQLException {
8060
throw new NotImplemented();
8064
* @see ResultSet#updateRef(String, Ref)
8066
public void updateRef(String arg0, Ref arg1) throws SQLException {
8067
throw new NotImplemented();
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.
8074
* @exception SQLException
8075
* if a database-access error occurs, or if called when on
8077
* @throws NotUpdatable
8080
public void updateRow() throws SQLException {
8081
throw new NotUpdatable();
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.
8090
* @param columnIndex
8091
* the first column is 1, the second is 2, ...
8093
* the new column value
8095
* @exception SQLException
8096
* if a database-access error occurs
8097
* @throws NotUpdatable
8100
public void updateShort(int columnIndex, short x) throws SQLException {
8101
throw new NotUpdatable();
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.
8111
* the name of the column
8113
* the new column value
8115
* @exception SQLException
8116
* if a database-access error occurs
8118
public void updateShort(String columnName, short x) throws SQLException {
8119
updateShort(findColumn(columnName), x);
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.
8128
* @param columnIndex
8129
* the first column is 1, the second is 2, ...
8131
* the new column value
8133
* @exception SQLException
8134
* if a database-access error occurs
8135
* @throws NotUpdatable
8138
public void updateString(int columnIndex, String x) throws SQLException {
8139
throw new NotUpdatable();
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.
8149
* the name of the column
8151
* the new column value
8153
* @exception SQLException
8154
* if a database-access error occurs
8156
public void updateString(String columnName, String x) throws SQLException {
8157
updateString(findColumn(columnName), x);
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.
8166
* @param columnIndex
8167
* the first column is 1, the second is 2, ...
8169
* the new column value
8171
* @exception SQLException
8172
* if a database-access error occurs
8173
* @throws NotUpdatable
8176
public void updateTime(int columnIndex, java.sql.Time x)
8177
throws SQLException {
8178
throw new NotUpdatable();
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.
8188
* the name of the column
8190
* the new column value
8192
* @exception SQLException
8193
* if a database-access error occurs
8195
public void updateTime(String columnName, java.sql.Time x)
8196
throws SQLException {
8197
updateTime(findColumn(columnName), x);
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.
8207
* @param columnIndex
8208
* the first column is 1, the second is 2, ...
8210
* the new column value
8212
* @exception SQLException
8213
* if a database-access error occurs
8214
* @throws NotUpdatable
8217
public void updateTimestamp(int columnIndex, java.sql.Timestamp x)
8218
throws SQLException {
8219
throw new NotUpdatable();
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.
8229
* the name of the column
8231
* the new column value
8233
* @exception SQLException
8234
* if a database-access error occurs
8236
public void updateTimestamp(String columnName, java.sql.Timestamp x)
8237
throws SQLException {
8238
updateTimestamp(findColumn(columnName), x);
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
8247
* @return true if the last column read was SQL NULL
8249
* @exception SQLException
8250
* if a database access error occurred
8252
public boolean wasNull() throws SQLException {
8253
return this.wasNullFlag;
8256
protected Calendar getGmtCalendar() {
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"));
8264
return this.gmtCalendar;
8267
private Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
8269
int mysqlType, TimeZone tz, boolean rollForward)
8270
throws SQLException {
8282
byte[] bits = (byte[]) this.thisRow[columnIndex - 1];
8285
this.wasNullFlag = true;
8290
Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
8291
this.connection.getUtcCalendar() :
8292
getCalendarInstanceForSessionOrNew();
8294
this.wasNullFlag = false;
8296
boolean populatedFromDateTimeValue = false;
8298
switch (mysqlType) {
8299
case MysqlDefs.FIELD_TYPE_DATETIME:
8300
case MysqlDefs.FIELD_TYPE_TIMESTAMP:
8301
populatedFromDateTimeValue = true;
8303
int length = bits.length;
8306
year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
8317
nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8)
8318
| ((bits[9] & 0xff) << 16)
8319
| ((bits[10] & 0xff) << 24);
8324
case MysqlDefs.FIELD_TYPE_DATE:
8325
populatedFromDateTimeValue = true;
8327
if (bits.length != 0) {
8328
year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
8334
case MysqlDefs.FIELD_TYPE_TIME:
8335
populatedFromDateTimeValue = true;
8337
if (bits.length != 0) {
8338
// bits[0] // skip tm->neg
8339
// binaryData.readLong(); // skip daysPart
8351
populatedFromDateTimeValue = false;
8356
if (populatedFromDateTimeValue) {
8357
Time time = TimeUtil.fastTimeCreate(
8358
getCalendarInstanceForSessionOrNew(), hour, minute,
8361
Time adjustedTime = TimeUtil.changeTimezone(this.connection,
8364
time, this.connection.getServerTimezoneTZ(), tz,
8367
return adjustedTime;
8370
return getNativeTimeViaParseConversion(columnIndex, targetCalendar,
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;
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);
8393
return fastDateCreate(getCalendarInstanceForSessionOrNew(),
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;
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);
8418
Timestamp ts = fastTimestampCreate(
8419
getCalendarInstanceForSessionOrNew(), year, month, day,
8420
hour, minute, seconds, nanos);
8422
Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection,
8425
ts, this.connection.getServerTimezoneTZ(), tz,
8431
return getNativeTimestampViaParseConversion(columnIndex, targetCalendar, tz, rollForward);
8434
throw new SQLException("Internal error - conversion method doesn't support this type",
8435
SQLError.SQL_STATE_GENERAL_ERROR);