EMMA Coverage Report (generated Fri May 26 15:35:26 CDT 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [ResultSet.java]

nameclass, %method, %block, %line, %
ResultSet.java100% (1/1)65%  (157/243)64%  (7209/11247)69%  (1515.8/2183)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ResultSet100% (1/1)65%  (157/243)64%  (7209/11247)69%  (1515.8/2183)
addAWarning (SQLWarning): void 0%   (0/1)0%   (0/21)0%   (0/7)
cancelRowUpdates (): void 0%   (0/1)0%   (0/4)0%   (0/1)
deleteRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
getArray (String): Array 0%   (0/1)0%   (0/6)0%   (0/1)
getAsciiStream (String): InputStream 0%   (0/1)0%   (0/6)0%   (0/1)
getBinaryStream (String): InputStream 0%   (0/1)0%   (0/6)0%   (0/1)
getCharacterStream (String): Reader 0%   (0/1)0%   (0/6)0%   (0/1)
getClob (String): Clob 0%   (0/1)0%   (0/6)0%   (0/1)
getCursorName (): String 0%   (0/1)0%   (0/7)0%   (0/1)
getDate (String): Date 0%   (0/1)0%   (0/6)0%   (0/1)
getDate (String, Calendar): Date 0%   (0/1)0%   (0/7)0%   (0/1)
getDouble (String): double 0%   (0/1)0%   (0/6)0%   (0/1)
getFloat (String): float 0%   (0/1)0%   (0/6)0%   (0/1)
getGmtCalendar (): Calendar 0%   (0/1)0%   (0/11)0%   (0/3)
getLong (String): long 0%   (0/1)0%   (0/6)0%   (0/1)
getNativeArray (int): Array 0%   (0/1)0%   (0/4)0%   (0/1)
getNativeAsciiStream (int): InputStream 0%   (0/1)0%   (0/6)0%   (0/2)
getNativeRef (int): Ref 0%   (0/1)0%   (0/4)0%   (0/1)
getNativeURL (int): URL 0%   (0/1)0%   (0/30)0%   (0/6)
getNativeUnicodeStream (int): InputStream 0%   (0/1)0%   (0/6)0%   (0/2)
getObject (String, Map): Object 0%   (0/1)0%   (0/7)0%   (0/1)
getObject (int, Map): Object 0%   (0/1)0%   (0/4)0%   (0/1)
getObjectStoredProc (String, Map, int): Object 0%   (0/1)0%   (0/8)0%   (0/1)
getObjectStoredProc (String, int): Object 0%   (0/1)0%   (0/7)0%   (0/1)
getObjectStoredProc (int, Map, int): Object 0%   (0/1)0%   (0/5)0%   (0/1)
getRef (String): Ref 0%   (0/1)0%   (0/6)0%   (0/1)
getTime (String, Calendar): Time 0%   (0/1)0%   (0/7)0%   (0/1)
getTimestamp (String, Calendar): Timestamp 0%   (0/1)0%   (0/7)0%   (0/1)
getURL (String): URL 0%   (0/1)0%   (0/30)0%   (0/6)
getUnicodeStream (String): InputStream 0%   (0/1)0%   (0/6)0%   (0/1)
insertRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
issueDataTruncationWarningIfConfigured (int, int, int): void 0%   (0/1)0%   (0/10)0%   (0/2)
moveToCurrentRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
moveToInsertRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
refreshRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
rowDeleted (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
rowInserted (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
rowUpdated (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
setFetchDirection (int): void 0%   (0/1)0%   (0/20)0%   (0/4)
updateArray (String, Array): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateArray (int, Array): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateAsciiStream (String, InputStream, int): void 0%   (0/1)0%   (0/8)0%   (0/2)
updateAsciiStream (int, InputStream, int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBigDecimal (String, BigDecimal): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateBigDecimal (int, BigDecimal): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBinaryStream (String, InputStream, int): void 0%   (0/1)0%   (0/8)0%   (0/2)
updateBinaryStream (int, InputStream, int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBlob (String, Blob): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBlob (int, Blob): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBoolean (String, boolean): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateBoolean (int, boolean): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateByte (String, byte): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateByte (int, byte): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateBytes (String, byte []): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateBytes (int, byte []): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateCharacterStream (String, Reader, int): void 0%   (0/1)0%   (0/8)0%   (0/2)
updateCharacterStream (int, Reader, int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateClob (String, Clob): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateClob (int, Clob): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateDate (String, Date): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateDate (int, Date): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateDouble (String, double): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateDouble (int, double): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateFloat (String, float): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateFloat (int, float): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateInt (String, int): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateInt (int, int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateLong (String, long): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateLong (int, long): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateNull (String): void 0%   (0/1)0%   (0/6)0%   (0/2)
updateNull (int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateObject (String, Object): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateObject (String, Object, int): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateObject (int, Object): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateObject (int, Object, int): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateRef (String, Ref): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateRef (int, Ref): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateRow (): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateShort (String, short): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateShort (int, short): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateString (String, String): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateString (int, String): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateTime (String, Time): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateTime (int, Time): void 0%   (0/1)0%   (0/4)0%   (0/1)
updateTimestamp (String, Timestamp): void 0%   (0/1)0%   (0/7)0%   (0/2)
updateTimestamp (int, Timestamp): void 0%   (0/1)0%   (0/4)0%   (0/1)
getObjectStoredProc (int, int): Object 100% (1/1)15%  (37/239)22%  (9.4/43)
getBigDecimalFromString (String, int, int): BigDecimal 100% (1/1)16%  (31/190)28%  (7/25)
getDoubleInternal (String, int): double 100% (1/1)17%  (19/111)25%  (7/28)
getFloatFromString (String, int): float 100% (1/1)19%  (28/147)29%  (8/28)
getIntFromString (String, int): int 100% (1/1)25%  (32/126)28%  (7/25)
getBigDecimal (int, int): BigDecimal 100% (1/1)29%  (39/134)46%  (11/24)
getNumericRepresentationOfSQLBitType (int): long 100% (1/1)36%  (29/80)17%  (2/12)
toString (): String 100% (1/1)38%  (6/16)67%  (2/3)
getLongFromString (String, int): long 100% (1/1)43%  (25/58)45%  (5/11)
parseShortWithOverflowCheck (int, byte [], String): short 100% (1/1)46%  (27/59)67%  (8/12)
checkColumnBounds (int): void 100% (1/1)47%  (22/47)80%  (4/5)
parseLongWithOverflowCheck (int, byte [], String): long 100% (1/1)48%  (29/61)67%  (8/12)
getShortFromString (String, int): short 100% (1/1)48%  (30/63)45%  (5/11)
getObject (int): Object 100% (1/1)49%  (198/406)54%  (42.5/79)
getShort (int): short 100% (1/1)50%  (139/280)59%  (30.8/52)
getNativeShort (int, boolean): short 100% (1/1)53%  (204/386)69%  (39.8/58)
extractStringFromNativeColumn (int, int): String 100% (1/1)53%  (59/111)71%  (15/21)
getLong (int): long 100% (1/1)53%  (123/231)63%  (29.2/46)
getTimestampFromString (int, String, TimeZone, boolean): Timestamp 100% (1/1)55%  (370/668)57%  (50.6/89)
getInt (int): int 100% (1/1)56%  (153/273)66%  (34.2/52)
getBytes (int, boolean): byte [] 100% (1/1)57%  (41/72)68%  (10.2/15)
parseShortAsDouble (int, String): short 100% (1/1)59%  (17/29)57%  (4/7)
getDateFromString (String, int): Date 100% (1/1)59%  (220/375)60%  (36/60)
previous (): boolean 100% (1/1)60%  (9/15)60%  (3/5)
getNativeByte (int, boolean): byte 100% (1/1)60%  (201/334)70%  (39.4/56)
findColumn (String): int 100% (1/1)60%  (85/141)61%  (13.9/23)
getBigDecimal (int): BigDecimal 100% (1/1)61%  (33/54)83%  (10/12)
getNativeBoolean (int): boolean 100% (1/1)61%  (77/126)79%  (15/19)
throwRangeException (String, int, int): void 100% (1/1)63%  (39/62)55%  (11/20)
parseLongAsDouble (int, String): long 100% (1/1)63%  (17/27)57%  (4/7)
getByteFromString (String, int): byte 100% (1/1)65%  (54/83)75%  (12/16)
parseIntWithOverflowCheck (int, byte [], String): int 100% (1/1)66%  (39/59)72%  (8.6/12)
getNativeConvertToString (int, Field): String 100% (1/1)66%  (281/424)69%  (72.7/106)
getDefaultTimeZone (): TimeZone 100% (1/1)67%  (6/9)67%  (2/3)
getBlob (int): Blob 100% (1/1)68%  (61/90)82%  (14/17)
getNativeInt (int, boolean): int 100% (1/1)70%  (223/317)83%  (40/48)
parseIntAsDouble (int, String): int 100% (1/1)71%  (20/28)71%  (5/7)
absolute (int): boolean 100% (1/1)73%  (66/91)74%  (20/27)
beforeFirst (): void 100% (1/1)73%  (19/26)70%  (7/10)
first (): boolean 100% (1/1)73%  (22/30)70%  (7/10)
next (): boolean 100% (1/1)75%  (40/53)81%  (13/16)
afterLast (): void 100% (1/1)76%  (19/25)78%  (7/9)
getNativeLong (int, boolean, boolean): long 100% (1/1)77%  (258/335)86%  (37/43)
getStringInternal (int, boolean): String 100% (1/1)78%  (208/267)78%  (50/64)
getNativeDateTimeValue (int, int, int, TimeZone, boolean): Object 100% (1/1)78%  (249/319)86%  (63.3/74)
realClose (boolean): void 100% (1/1)79%  (234/298)90%  (47.7/53)
getTimeFromString (String, int, TimeZone, boolean): Time 100% (1/1)79%  (264/334)80%  (39.1/49)
getNativeString (int): String 100% (1/1)81%  (89/110)81%  (21/26)
getNativeDouble (int): double 100% (1/1)81%  (162/200)95%  (20/21)
getNativeTimestamp (int, TimeZone, boolean): Timestamp 100% (1/1)82%  (159/195)95%  (38/40)
getNativeBlob (int): Blob 100% (1/1)83%  (57/69)83%  (15/18)
getURL (int): URL 100% (1/1)83%  (25/30)83%  (5/6)
getNativeDate (int, TimeZone): Date 100% (1/1)85%  (116/136)84%  (26.9/32)
getStatement (): Statement 100% (1/1)86%  (18/21)80%  (4/5)
getCalendarInstanceForSessionOrNew (): Calendar 100% (1/1)87%  (13/15)80%  (4/5)
getBytesFromString (String, int): byte [] 100% (1/1)88%  (14/16)67%  (2/3)
getRow (): int 100% (1/1)89%  (32/36)89%  (8/9)
getDate (int, Calendar): Date 100% (1/1)89%  (25/28)95%  (5.7/6)
last (): boolean 100% (1/1)90%  (27/30)90%  (9/10)
fastDateCreate (Calendar, int, int, int): Date 100% (1/1)92%  (33/36)97%  (6.8/7)
getBoolean (int): boolean 100% (1/1)92%  (85/92)84%  (16/19)
fastTimestampCreate (Calendar, int, int, int, int, int, int, int): Timestamp 100% (1/1)92%  (37/40)98%  (6.9/7)
relative (int): boolean 100% (1/1)94%  (30/32)83%  (5/6)
issueConversionViaParsingWarning (String, int, Object, Field, int []): void 100% (1/1)95%  (139/147)95%  (22.9/24)
getNativeBytes (int, boolean): byte [] 100% (1/1)95%  (73/77)90%  (18/20)
prev (): boolean 100% (1/1)95%  (38/40)92%  (12/13)
<static initializer> 100% (1/1)100% (3/3)100% (1/1)
ResultSet (String, Field [], RowData, Connection, Statement): void 100% (1/1)100% (250/250)100% (69/69)
ResultSet (long, long, Connection, Statement): void 100% (1/1)100% (114/114)100% (38/38)
buildIndexMapping (): void 100% (1/1)100% (89/89)100% (17/17)
checkClosed (): void 100% (1/1)100% (11/11)100% (3/3)
checkRowPos (): void 100% (1/1)100% (40/40)100% (8/8)
clearNextResult (): void 100% (1/1)100% (4/4)100% (2/2)
clearWarnings (): void 100% (1/1)100% (4/4)100% (2/2)
close (): void 100% (1/1)100% (4/4)100% (2/2)
convertLongToUlong (long): BigInteger 100% (1/1)100% (73/73)100% (10/10)
convertToZeroLiteralStringWithEmptyCheck (): String 100% (1/1)100% (12/12)100% (3/3)
convertToZeroWithEmptyCheck (): int 100% (1/1)100% (12/12)100% (3/3)
copy (): ResultSet 100% (1/1)100% (16/16)100% (2/2)
fastTimeCreate (Calendar, int, int, int): Time 100% (1/1)100% (25/25)100% (6/6)
getArray (int): Array 100% (1/1)100% (7/7)100% (2/2)
getAsciiStream (int): InputStream 100% (1/1)100% (13/13)100% (4/4)
getBigDecimal (String): BigDecimal 100% (1/1)100% (6/6)100% (1/1)
getBigDecimal (String, int): BigDecimal 100% (1/1)100% (7/7)100% (1/1)
getBinaryStream (int): InputStream 100% (1/1)100% (22/22)100% (7/7)
getBlob (String): Blob 100% (1/1)100% (6/6)100% (1/1)
getBoolean (String): boolean 100% (1/1)100% (6/6)100% (1/1)
getBooleanFromString (String, int): boolean 100% (1/1)100% (29/29)100% (4/4)
getByte (String): byte 100% (1/1)100% (6/6)100% (1/1)
getByte (int): byte 100% (1/1)100% (23/23)100% (6/6)
getBytes (String): byte [] 100% (1/1)100% (6/6)100% (1/1)
getBytes (int): byte [] 100% (1/1)100% (5/5)100% (1/1)
getCharacterStream (int): Reader 100% (1/1)100% (20/20)100% (6/6)
getCharacterStreamFromString (String, int): Reader 100% (1/1)100% (9/9)100% (3/3)
getClob (int): Clob 100% (1/1)100% (20/20)100% (6/6)
getClobFromString (String, int): Clob 100% (1/1)100% (5/5)100% (1/1)
getConcurrency (): int 100% (1/1)100% (2/2)100% (1/1)
getDate (int): Date 100% (1/1)100% (5/5)100% (1/1)
getDouble (int): double 100% (1/1)100% (11/11)100% (3/3)
getDoubleFromString (String, int): double 100% (1/1)100% (5/5)100% (1/1)
getDoubleInternal (int): double 100% (1/1)100% (7/7)100% (1/1)
getFetchDirection (): int 100% (1/1)100% (3/3)100% (1/1)
getFetchSize (): int 100% (1/1)100% (3/3)100% (1/1)
getFirstCharOfQuery (): char 100% (1/1)100% (3/3)100% (1/1)
getFloat (int): float 100% (1/1)100% (18/18)100% (5/5)
getInt (String): int 100% (1/1)100% (6/6)100% (1/1)
getMetaData (): ResultSetMetaData 100% (1/1)100% (8/8)100% (2/2)
getNativeBigDecimal (int): BigDecimal 100% (1/1)100% (16/16)100% (3/3)
getNativeBigDecimal (int, int): BigDecimal 100% (1/1)100% (50/50)100% (12/12)
getNativeBinaryStream (int): InputStream 100% (1/1)100% (16/16)100% (5/5)
getNativeByte (int): byte 100% (1/1)100% (5/5)100% (1/1)
getNativeCharacterStream (int): Reader 100% (1/1)100% (9/9)100% (2/2)
getNativeClob (int): Clob 100% (1/1)100% (13/13)100% (4/4)
getNativeDate (int): Date 100% (1/1)100% (5/5)100% (1/1)
getNativeDateViaParseConversion (int): Date 100% (1/1)100% (34/34)100% (4/4)
getNativeFloat (int): float 100% (1/1)100% (162/162)100% (22/22)
getNativeInt (int): int 100% (1/1)100% (5/5)100% (1/1)
getNativeLong (int): long 100% (1/1)100% (6/6)100% (1/1)
getNativeShort (int): short 100% (1/1)100% (5/5)100% (1/1)
getNativeTime (int, TimeZone, boolean): Time 100% (1/1)100% (90/90)100% (21/21)
getNativeTimeViaParseConversion (int, TimeZone, boolean): Time 100% (1/1)100% (36/36)100% (4/4)
getNativeTimestampViaParseConversion (int, TimeZone, boolean): Timestamp 100% (1/1)100% (40/40)100% (4/4)
getNextResultSet (): ResultSet 100% (1/1)100% (3/3)100% (1/1)
getObject (String): Object 100% (1/1)100% (6/6)100% (1/1)
getRef (int): Ref 100% (1/1)100% (7/7)100% (2/2)
getServerInfo (): String 100% (1/1)100% (3/3)100% (1/1)
getShort (String): short 100% (1/1)100% (6/6)100% (1/1)
getString (String): String 100% (1/1)100% (6/6)100% (1/1)
getString (int): String 100% (1/1)100% (5/5)100% (1/1)
getTime (String): Time 100% (1/1)100% (6/6)100% (1/1)
getTime (int): Time 100% (1/1)100% (7/7)100% (1/1)
getTime (int, Calendar): Time 100% (1/1)100% (7/7)100% (1/1)
getTimeInternal (int, TimeZone, boolean): Time 100% (1/1)100% (21/21)100% (4/4)
getTimestamp (String): Timestamp 100% (1/1)100% (6/6)100% (1/1)
getTimestamp (int): Timestamp 100% (1/1)100% (7/7)100% (1/1)
getTimestamp (int, Calendar): Timestamp 100% (1/1)100% (7/7)100% (1/1)
getTimestampInternal (int, TimeZone, boolean): Timestamp 100% (1/1)100% (21/21)100% (4/4)
getType (): int 100% (1/1)100% (3/3)100% (1/1)
getUnicodeStream (int): InputStream 100% (1/1)100% (13/13)100% (4/4)
getUpdateCount (): long 100% (1/1)100% (3/3)100% (1/1)
getUpdateID (): long 100% (1/1)100% (3/3)100% (1/1)
getWarnings (): SQLWarning 100% (1/1)100% (3/3)100% (1/1)
isAfterLast (): boolean 100% (1/1)100% (8/8)100% (3/3)
isBeforeFirst (): boolean 100% (1/1)100% (6/6)100% (2/2)
isFirst (): boolean 100% (1/1)100% (6/6)100% (2/2)
isLast (): boolean 100% (1/1)100% (6/6)100% (2/2)
reallyResult (): boolean 100% (1/1)100% (8/8)100% (3/3)
setBinaryEncoded (): void 100% (1/1)100% (4/4)100% (2/2)
setDefaultTimeZone (TimeZone): void 100% (1/1)100% (4/4)100% (2/2)
setFetchSize (int): void 100% (1/1)100% (13/13)100% (4/4)
setFirstCharOfQuery (char): void 100% (1/1)100% (4/4)100% (2/2)
setNextResultSet (ResultSet): void 100% (1/1)100% (4/4)100% (2/2)
setResultSetConcurrency (int): void 100% (1/1)100% (4/4)100% (2/2)
setResultSetType (int): void 100% (1/1)100% (4/4)100% (2/2)
setServerInfo (String): void 100% (1/1)100% (4/4)100% (2/2)
setWrapperStatement (Statement): void 100% (1/1)100% (4/4)100% (2/2)
wasNull (): boolean 100% (1/1)100% (3/3)100% (1/1)

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

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov