From: Date: April 3 2006 9:43pm Subject: Connector/J commit: r5127 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_5_0/connector-j branch_5_0/connector-j/src/com/mysql/jdbc branch_5_1/connector-j branch_5_1/connector-j/src/com/mysql/jdbc List-Archive: http://lists.mysql.com/commits/4426 X-Bug: 18496 Message-Id: <200604031943.k33Jhbxt019926@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/branch_3_1/connector-j/CHANGES branches/branch_3_1/connector-j/src/com/mysql/jdbc/ResultSet.java branches/branch_5_0/connector-j/CHANGES branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java branches/branch_5_1/connector-j/CHANGES branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java Log: Improved performance of retrieving BigDecimal, Time, Timestamp and Date values from server-side prepared statements by creating fewer short-lived instances of Strings when the native type is not an exact match for the requested type. Fixes BUG#18496 for BigDecimals. Modified: branches/branch_3_1/connector-j/CHANGES =================================================================== --- branches/branch_3_1/connector-j/CHANGES 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_3_1/connector-j/CHANGES 2006-04-03 19:43:33 UTC (rev 5127) @@ -85,7 +85,7 @@ - Improved performance of retrieving BigDecimal, Time, Timestamp and Date values from server-side prepared statements by creating fewer short-lived instances of Strings when the native type is not an exact match for - the requested type. + the requested type. Fixes BUG#18496 for BigDecimals. - Fixed BUG#18554 - Aliased column names where length of name > 251 are corrupted. Modified: branches/branch_3_1/connector-j/src/com/mysql/jdbc/ResultSet.java =================================================================== --- branches/branch_3_1/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_3_1/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 19:43:33 UTC (rev 5127) @@ -1257,7 +1257,23 @@ if (stringVal.length() == 0) { bdVal = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); - return bdVal; + try { + return bdVal.setScale(scale); + } catch (ArithmeticException ex) { + try { + return bdVal.setScale(scale, BigDecimal.ROUND_HALF_UP); + } catch (ArithmeticException arEx) { + throw new SQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__125") + + columnIndex + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + } } try { @@ -2734,11 +2750,12 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex) throws SQLException { - String stringVal = getNativeString(columnIndex); + checkColumnBounds(columnIndex); + int scale = this.fields[columnIndex - 1].getDecimals(); - - return getBigDecimalFromString(stringVal, columnIndex, scale); + + return getNativeBigDecimal(columnIndex, scale); } /** @@ -2757,65 +2774,31 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex, int scale) throws SQLException { - String stringVal = getNativeString(columnIndex); - BigDecimal val; - - if (stringVal != null) { - if (stringVal.length() == 0) { - val = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); - - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw new SQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } - - try { - val = new BigDecimal(stringVal); - } catch (NumberFormatException ex) { - throw new SQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____119") //$NON-NLS-1$ - + stringVal - + "' in column " - + columnIndex - + "(" + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw new SQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } + checkColumnBounds(columnIndex); + + String stringVal = null; + + Field f = this.fields[columnIndex - 1]; + + if (this.thisRow[columnIndex - 1] == null) { + this.wasNullFlag = true; + + return null; } + + this.wasNullFlag = false; + + switch (f.getSQLType()) { + case Types.DECIMAL: + case Types.NUMERIC: + stringVal = StringUtils + .toAsciiString((byte[]) this.thisRow[columnIndex - 1]); + break; + default: + stringVal = getNativeString(columnIndex); + } - return null; + return getBigDecimalFromString(stringVal, columnIndex, scale); } /** @@ -3365,7 +3348,9 @@ checkRowPos(); checkColumnBounds(columnIndex); - if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) { + int mysqlType = this.fields[columnIndex - 1].getMysqlType(); + + if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) { byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; if (bits == null) { @@ -3414,7 +3399,14 @@ return fastDateCreate( getCalendarInstanceForSessionOrNew(), year, month, day); } + + boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone())); + + return (Date)getNativeDateTimeValue(columnIndex, Types.DATE, mysqlType, + tz, rollForward); + } + private java.sql.Date getNativeDateViaParseConversion(int columnIndex) throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getDate()", columnIndex, this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], @@ -3424,7 +3416,6 @@ String stringVal = getNativeString(columnIndex); return getDateFromString(stringVal, columnIndex); - } /** @@ -3690,7 +3681,12 @@ return adjustedTime; } + + return (Time)getNativeDateTimeValue(columnIndex, Types.TIME, mysqlType, + tz, rollForward); + } + private Time getNativeTimeViaParseConversion(int columnIndex, TimeZone tz, boolean rollForward) throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getTime()", columnIndex, this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], @@ -3780,19 +3776,23 @@ return adjustedTs; default: + return (Timestamp)getNativeDateTimeValue(columnIndex, Types.TIMESTAMP, mysqlType, + tz, rollForward); + } + } - if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getTimestamp()", columnIndex, - this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], - new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP, - MysqlDefs.FIELD_TYPE_DATETIME }); - } + private Timestamp getNativeTimestampViaParseConversion(int columnIndex, TimeZone tz, boolean rollForward) throws SQLException { + if (this.useUsageAdvisor) { + issueConversionViaParsingWarning("getTimestamp()", columnIndex, + this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], + new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP, + MysqlDefs.FIELD_TYPE_DATETIME }); + } - String strTimestamp = getNativeString(columnIndex); + String strTimestamp = getNativeString(columnIndex); - return getTimestampFromString(columnIndex, strTimestamp, tz, - rollForward); - } + return getTimestampFromString(columnIndex, strTimestamp, tz, + rollForward); } // --------------------------------------------------------------------- @@ -7828,4 +7828,166 @@ return getShortFromString(stringVal, columnIndex + 1); } } + + private Object getNativeDateTimeValue(int columnIndex, int jdbcType, + int mysqlType, TimeZone tz, boolean rollForward) + throws SQLException { + + int year = 0; + int month = 0; + int day = 0; + + int hour = 0; + int minute = 0; + int seconds = 0; + + int nanos = 0; + + byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; + + if (bits == null) { + this.wasNullFlag = true; + + return null; + } + + this.wasNullFlag = false; + + boolean populatedFromDateTimeValue = false; + + switch (mysqlType) { + case MysqlDefs.FIELD_TYPE_DATETIME: + case MysqlDefs.FIELD_TYPE_TIMESTAMP: + populatedFromDateTimeValue = true; + + int length = bits.length; + + if (length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + + if (length > 4) { + hour = bits[4]; + minute = bits[5]; + seconds = bits[6]; + } + + if (length > 7) { + nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8) + | ((bits[9] & 0xff) << 16) + | ((bits[10] & 0xff) << 24); + } + } + + break; + case MysqlDefs.FIELD_TYPE_DATE: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + } + + break; + case MysqlDefs.FIELD_TYPE_TIME: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + // bits[0] // skip tm->neg + // binaryData.readLong(); // skip daysPart + hour = bits[5]; + minute = bits[6]; + seconds = bits[7]; + } + + year = 1970; + month = 1; + day = 1; + + break; + default: + populatedFromDateTimeValue = false; + } + + switch (jdbcType) { + case Types.TIME: + if (populatedFromDateTimeValue) { + Time time = TimeUtil.fastTimeCreate( + getCalendarInstanceForSessionOrNew(), hour, minute, + seconds); + + Time adjustedTime = TimeUtil.changeTimezone(this.connection, + time, this.connection.getServerTimezoneTZ(), tz, + rollForward); + + return adjustedTime; + } + + return getNativeTimeViaParseConversion(columnIndex, tz, rollForward); + + case Types.DATE: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Date", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + return fastDateCreate(getCalendarInstanceForSessionOrNew(), + year, month, day); + } + + return getNativeDateViaParseConversion(columnIndex); + case Types.TIMESTAMP: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Timestamp", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + Timestamp ts = fastTimestampCreate( + getCalendarInstanceForSessionOrNew(), year, month, day, + hour, minute, seconds, nanos); + + Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection, + ts, this.connection.getServerTimezoneTZ(), tz, + rollForward); + + return adjustedTs; + } + + return getNativeTimestampViaParseConversion(columnIndex, tz, rollForward); + + default: + throw new SQLException("Internal error - conversion method doesn't support this type", + SQLError.SQL_STATE_GENERAL_ERROR); + } + } } Modified: branches/branch_5_0/connector-j/CHANGES =================================================================== --- branches/branch_5_0/connector-j/CHANGES 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_5_0/connector-j/CHANGES 2006-04-03 19:43:33 UTC (rev 5127) @@ -188,7 +188,7 @@ - Improved performance of retrieving BigDecimal, Time, Timestamp and Date values from server-side prepared statements by creating fewer short-lived instances of Strings when the native type is not an exact match for - the requested type. + the requested type. Fixes BUG#18496 for BigDecimals. - Fixed BUG#18554 - Aliased column names where length of name > 251 are corrupted. Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java =================================================================== --- branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 19:43:33 UTC (rev 5127) @@ -1260,8 +1260,24 @@ bdVal = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); + try { return bdVal.setScale(scale); + } catch (ArithmeticException ex) { + try { + return bdVal.setScale(scale, BigDecimal.ROUND_HALF_UP); + } catch (ArithmeticException arEx) { + throw new SQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__125") + + columnIndex + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } + } + } try { try { @@ -2776,11 +2792,12 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex) throws SQLException { - String stringVal = getNativeString(columnIndex); + checkColumnBounds(columnIndex); + int scale = this.fields[columnIndex - 1].getDecimals(); - - return getBigDecimalFromString(stringVal, columnIndex, scale); + + return getNativeBigDecimal(columnIndex, scale); } /** @@ -2799,66 +2816,31 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex, int scale) throws SQLException { - String stringVal = getNativeString(columnIndex); - BigDecimal val; - - if (stringVal != null) { - if (stringVal.length() == 0) { - - val = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); - - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } - - try { - val = new BigDecimal(stringVal); - } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____119") //$NON-NLS-1$ - + stringVal - + "' in column " - + columnIndex - + "(" + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } + checkColumnBounds(columnIndex); + + String stringVal = null; + + Field f = this.fields[columnIndex - 1]; + + if (this.thisRow[columnIndex - 1] == null) { + this.wasNullFlag = true; + + return null; } + + this.wasNullFlag = false; + + switch (f.getSQLType()) { + case Types.DECIMAL: + case Types.NUMERIC: + stringVal = StringUtils + .toAsciiString((byte[]) this.thisRow[columnIndex - 1]); + break; + default: + stringVal = getNativeString(columnIndex); + } - return null; + return getBigDecimalFromString(stringVal, columnIndex, scale); } /** @@ -3560,7 +3542,9 @@ checkRowPos(); checkColumnBounds(columnIndex); - if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) { + int mysqlType = this.fields[columnIndex - 1].getMysqlType(); + + if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) { byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; if (bits == null) { @@ -3610,6 +3594,13 @@ getCalendarInstanceForSessionOrNew(), year, month, day); } + boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone())); + + return (Date)getNativeDateTimeValue(columnIndex, null, Types.DATE, mysqlType, + tz, rollForward); + } + + private java.sql.Date getNativeDateViaParseConversion(int columnIndex) throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getDate()", columnIndex, this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], @@ -3619,7 +3610,6 @@ String stringVal = getNativeString(columnIndex); return getDateFromString(stringVal, columnIndex); - } /** @@ -4358,14 +4348,21 @@ } } + return (Time)getNativeDateTimeValue(columnIndex, targetCalendar, + Types.TIME, mysqlType, + tz, rollForward); + } + + private Time getNativeTimeViaParseConversion(int columnIndex, Calendar targetCalendar, + TimeZone tz, boolean rollForward) throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getTime()", columnIndex, this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], new int[] { MysqlDefs.FIELD_TYPE_TIME }); } - + String strTime = getNativeString(columnIndex); - + return getTimeFromString(strTime, targetCalendar, columnIndex, tz, rollForward); } @@ -4458,20 +4455,25 @@ } default: + return (Timestamp)getNativeDateTimeValue(columnIndex, targetCalendar, + Types.TIMESTAMP, mysqlType, + tz, rollForward); + } + } - if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getTimestamp()", columnIndex, - this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], - new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP, - MysqlDefs.FIELD_TYPE_DATETIME }); - } + private Timestamp getNativeTimestampViaParseConversion(int columnIndex, Calendar targetCalendar, + TimeZone tz, boolean rollForward) throws SQLException { + if (this.useUsageAdvisor) { + issueConversionViaParsingWarning("getTimestamp()", columnIndex, + this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], + new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP, + MysqlDefs.FIELD_TYPE_DATETIME }); + } - String strTimestamp = getNativeString(columnIndex); + String strTimestamp = getNativeString(columnIndex); - return getTimestampFromString(columnIndex, targetCalendar, - strTimestamp, tz, - rollForward); - } + return getTimestampFromString(columnIndex, targetCalendar, strTimestamp, tz, + rollForward); } // --------------------------------------------------------------------- @@ -8105,4 +8107,176 @@ return this.gmtCalendar; } + + private Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar, + int jdbcType, + int mysqlType, TimeZone tz, boolean rollForward) + throws SQLException { + + int year = 0; + int month = 0; + int day = 0; + + int hour = 0; + int minute = 0; + int seconds = 0; + + int nanos = 0; + + byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; + + if (bits == null) { + this.wasNullFlag = true; + + return null; + } + + Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? + this.connection.getUtcCalendar() : + getCalendarInstanceForSessionOrNew(); + + this.wasNullFlag = false; + + boolean populatedFromDateTimeValue = false; + + switch (mysqlType) { + case MysqlDefs.FIELD_TYPE_DATETIME: + case MysqlDefs.FIELD_TYPE_TIMESTAMP: + populatedFromDateTimeValue = true; + + int length = bits.length; + + if (length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + + if (length > 4) { + hour = bits[4]; + minute = bits[5]; + seconds = bits[6]; + } + + if (length > 7) { + nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8) + | ((bits[9] & 0xff) << 16) + | ((bits[10] & 0xff) << 24); + } + } + + break; + case MysqlDefs.FIELD_TYPE_DATE: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + } + + break; + case MysqlDefs.FIELD_TYPE_TIME: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + // bits[0] // skip tm->neg + // binaryData.readLong(); // skip daysPart + hour = bits[5]; + minute = bits[6]; + seconds = bits[7]; + } + + year = 1970; + month = 1; + day = 1; + + break; + default: + populatedFromDateTimeValue = false; + } + + switch (jdbcType) { + case Types.TIME: + if (populatedFromDateTimeValue) { + Time time = TimeUtil.fastTimeCreate( + getCalendarInstanceForSessionOrNew(), hour, minute, + seconds); + + Time adjustedTime = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + time, this.connection.getServerTimezoneTZ(), tz, + rollForward); + + return adjustedTime; + } + + return getNativeTimeViaParseConversion(columnIndex, targetCalendar, + tz, rollForward); + + case Types.DATE: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Date", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + return fastDateCreate(getCalendarInstanceForSessionOrNew(), + year, month, day); + } + + return getNativeDateViaParseConversion(columnIndex); + case Types.TIMESTAMP: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Timestamp", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + Timestamp ts = fastTimestampCreate( + getCalendarInstanceForSessionOrNew(), year, month, day, + hour, minute, seconds, nanos); + + Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + ts, this.connection.getServerTimezoneTZ(), tz, + rollForward); + + return adjustedTs; + } + + return getNativeTimestampViaParseConversion(columnIndex, targetCalendar, tz, rollForward); + + default: + throw new SQLException("Internal error - conversion method doesn't support this type", + SQLError.SQL_STATE_GENERAL_ERROR); + } + } } Modified: branches/branch_5_1/connector-j/CHANGES =================================================================== --- branches/branch_5_1/connector-j/CHANGES 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_5_1/connector-j/CHANGES 2006-04-03 19:43:33 UTC (rev 5127) @@ -187,10 +187,10 @@ - Fixed BUG#18740 - Data truncation and getWarnings() only returns last warning in set. - - Improved performance of retrieving BigDecimal, Time, Timestamp and Date + - Improved performance of retrieving BigDecimal, Time, Timestamp and Date values from server-side prepared statements by creating fewer short-lived instances of Strings when the native type is not an exact match for - the requested type. + the requested type. Fixes BUG#18496 for BigDecimals. - Fixed BUG#18554 - Aliased column names where length of name > 251 are corrupted. Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java =================================================================== --- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 18:24:43 UTC (rev 5126) +++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java 2006-04-03 19:43:33 UTC (rev 5127) @@ -114,7 +114,8 @@ *

* * @author Mark Matthews - * @version $Id$ + * @version $Id: ResultSet.java 5053 2006-03-10 20:01:51 -0600 (Fri, 10 Mar + * 2006) mmatthews $ * * @see ResultSetMetaData * @see java.sql.ResultSet @@ -152,10 +153,11 @@ /** The Connection instance that created us */ protected com.mysql.jdbc.Connection connection; // The connection that - // created us + // created us + protected long connectionId = 0; - + /** The current row #, -1 == before start of result set */ protected int currentRow = -1; // Cursor to current row; @@ -294,13 +296,13 @@ this.connection = conn; this.owningStatement = creatorStmt; - + this.retainOwningStatement = false; - + if (this.connection != null) { - this.retainOwningStatement = - this.connection.getRetainStatementAfterResultSetClose(); - + this.retainOwningStatement = this.connection + .getRetainStatementAfterResultSetClose(); + this.connectionId = this.connection.getId(); } } @@ -387,7 +389,8 @@ if (tableName != null) { if (this.connection.lowerCaseTableNames()) { - tableName = tableName.toLowerCase(); // on windows, table + tableName = tableName.toLowerCase(); // on windows, + // table // names are not case-sens. } @@ -397,12 +400,12 @@ this.connection.reportNumberOfTablesAccessed(tableNamesMap.size()); } - + this.retainOwningStatement = false; - + if (this.connection != null) { - retainOwningStatement = - this.connection.getRetainStatementAfterResultSetClose(); + retainOwningStatement = this.connection + .getRetainStatementAfterResultSetClose(); } } @@ -453,10 +456,11 @@ b = false; } else { if (row == 0) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Cannot_absolute_position_to_row_0_110"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Cannot_absolute_position_to_row_0_110"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } if (this.onInsertRow) { @@ -647,10 +651,11 @@ */ protected final synchronized void checkClosed() throws SQLException { if (this.isClosed) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Operation_not_allowed_after_ResultSet_closed_144"), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR); } } @@ -688,10 +693,11 @@ checkClosed(); if (!this.rowData.isDynamic() && (this.rowData.size() == 0)) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Illegal_operation_on_empty_result_set"), - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Illegal_operation_on_empty_result_set"), + SQLError.SQL_STATE_GENERAL_ERROR); } if (this.rowData.isBeforeFirst()) { @@ -748,16 +754,17 @@ } private String convertToZeroLiteralStringWithEmptyCheck() - throws SQLException { - + throws SQLException { + if (this.connection.getEmptyStringsConvertToZero()) { return "0"; } - throw SQLError.createSQLException("Can't convert empty string ('') to numeric", + throw SQLError.createSQLException( + "Can't convert empty string ('') to numeric", SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST); } - + /** * @return */ @@ -766,7 +773,8 @@ return 0; } - throw SQLError.createSQLException("Can't convert empty string ('') to numeric", + throw SQLError.createSQLException( + "Can't convert empty string ('') to numeric", SQLError.SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST); } @@ -837,16 +845,18 @@ } } } catch (java.io.UnsupportedEncodingException E) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Unsupported_character_encoding____138") //$NON-NLS-1$ - + this.connection.getEncoding() + "'.", "0S100"); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Unsupported_character_encoding____138") //$NON-NLS-1$ + + this.connection.getEncoding() + "'.", + "0S100"); } } else { stringVal = StringUtils .toAsciiString((byte[]) this.thisRow[columnIndexMinusOne]); } - + return stringVal; } @@ -862,10 +872,9 @@ } boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes(); - + return TimeUtil.fastDateCreate(useGmtMillis, - useGmtMillis ? getGmtCalendar() : null, - cal, year, month, day); + useGmtMillis ? getGmtCalendar() : null, cal, year, month, day); } private synchronized Time fastTimeCreate(Calendar cal, int hour, @@ -895,11 +904,10 @@ } boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes(); - + return TimeUtil.fastTimestampCreate(useGmtMillis, - useGmtMillis ? getGmtCalendar() : null, - cal, year, month, day, hour, - minute, seconds, secondsPart); + useGmtMillis ? getGmtCalendar() : null, cal, year, month, day, + hour, minute, seconds, secondsPart); } /** @@ -941,30 +949,26 @@ } } - throw SQLError.createSQLException(Messages.getString("ResultSet.Column____112") + throw SQLError.createSQLException(Messages + .getString("ResultSet.Column____112") + columnName + Messages.getString("ResultSet.___not_found._113"), //$NON-NLS-1$ //$NON-NLS-2$ SQLError.SQL_STATE_COLUMN_NOT_FOUND); } /* - /** - * Required by JDBC spec + * /** Required by JDBC spec */ /* - protected void finalize() throws Throwable { - if (!this.isClosed) { - realClose(false); - } - } - */ + * protected void finalize() throws Throwable { if (!this.isClosed) { + * realClose(false); } } + */ // --------------------------JDBC 2.0----------------------------------- // --------------------------------------------------------------------- // Getter's and Setter's // --------------------------------------------------------------------- - /** * JDBC 2.0 * @@ -1014,7 +1018,7 @@ */ public java.sql.Array getArray(int i) throws SQLException { checkColumnBounds(i); - + throw new NotImplemented(); } @@ -1105,7 +1109,7 @@ if (stringVal != null) { if (stringVal.length() == 0) { - + val = new BigDecimal( convertToZeroLiteralStringWithEmptyCheck()); @@ -1165,17 +1169,18 @@ return val .setScale(scale, BigDecimal.ROUND_HALF_UP); } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex - + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] - + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__125") + + columnIndex + + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -1253,10 +1258,27 @@ if (stringVal != null) { if (stringVal.length() == 0) { - - bdVal = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); - return bdVal.setScale(scale); + bdVal = new BigDecimal( + convertToZeroLiteralStringWithEmptyCheck()); + + try { + return bdVal.setScale(scale); + } catch (ArithmeticException ex) { + try { + return bdVal.setScale(scale, BigDecimal.ROUND_HALF_UP); + } catch (ArithmeticException arEx) { + throw new SQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__125") + + columnIndex + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + } } try { @@ -1267,7 +1289,23 @@ return new BigDecimal(stringVal).setScale(scale, BigDecimal.ROUND_HALF_UP); } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____166") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__167") + + columnIndex + + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + } + } catch (NumberFormatException ex) { + throw SQLError + .createSQLException( Messages .getString("ResultSet.Bad_format_for_BigDecimal____166") //$NON-NLS-1$ + stringVal @@ -1276,18 +1314,6 @@ + columnIndex + "(" //$NON-NLS-1$ + this.fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____166") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__167") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } @@ -1358,7 +1384,7 @@ checkRowPos(); checkColumnBounds(columnIndex); - + if ((columnIndex < 1) || (columnIndex > this.fields.length)) { throw SQLError.createSQLException(Messages.getString( "ResultSet.Column_Index_out_of_range", new Object[] { @@ -1544,9 +1570,9 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - - stringVal = stringVal.trim(); - + + stringVal = stringVal.trim(); + try { int decimalIndex = stringVal.indexOf("."); @@ -1576,12 +1602,13 @@ return (byte) valueAsLong; } catch (NumberFormatException NFE) { - throw SQLError.createSQLException( - Messages.getString("ResultSet.Value____173") - + stringVal //$NON-NLS-1$ - + Messages - .getString("ResultSet.___is_out_of_range_[-127,127]_174"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages.getString("ResultSet.Value____173") + + stringVal //$NON-NLS-1$ + + Messages + .getString("ResultSet.___is_out_of_range_[-127,127]_174"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } @@ -1608,9 +1635,9 @@ throws SQLException { if (!this.isBinaryEncoded) { checkRowPos(); - + checkColumnBounds(columnIndex); - + try { if (this.thisRow[columnIndex - 1] == null) { this.wasNullFlag = true; @@ -1750,7 +1777,7 @@ public java.sql.Clob getClob(int i) throws SQLException { if (!this.isBinaryEncoded) { String asString = getStringForClob(i); - + if (asString == null) { return null; } @@ -1780,12 +1807,12 @@ int columnIndex) throws SQLException { return new com.mysql.jdbc.Clob(stringVal); } - - private final java.sql.NClob getNClobFromString(String stringVal, - int columnIndex) throws SQLException { - return new com.mysql.jdbc.NClob(stringVal); - } + private final java.sql.NClob getNClobFromString(String stringVal, + int columnIndex) throws SQLException { + return new com.mysql.jdbc.NClob(stringVal); + } + /** * JDBC 2.0 Return the concurrency of this result set. The concurrency used * is determined by the statement that created the result set. @@ -1927,7 +1954,7 @@ return null; } - + // // JDK-6 doesn't like trailing whitespace // @@ -1935,7 +1962,7 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - + stringVal = stringVal.trim(); if (stringVal.equals("0") || stringVal.equals("0000-00-00") @@ -2053,9 +2080,10 @@ month = Integer.parseInt(stringVal.substring(5, 7)); day = Integer.parseInt(stringVal.substring(8, 10)); } else { - // JDK-1.3 timestamp format, not real easy to parse positionally :p + // JDK-1.3 timestamp format, not real easy to parse + // positionally :p StringTokenizer st = new StringTokenizer(stringVal, "- "); - + year = Integer.parseInt(st.nextToken()); month = Integer.parseInt(st.nextToken()); day = Integer.parseInt(st.nextToken()); @@ -2310,28 +2338,32 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getFloat()_-____200") - + val //$NON-NLS-1$ - + Messages.getString("ResultSet.___in_column__201") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getFloat()_-____200") + + val //$NON-NLS-1$ + + Messages + .getString("ResultSet.___in_column__201") + + columnIndex, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } protected synchronized Calendar getGmtCalendar() { - + if (this.gmtCalendar == null) { - this.gmtCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + this.gmtCalendar = Calendar + .getInstance(TimeZone.getTimeZone("GMT")); } - + return this.gmtCalendar; } public int getHoldability() throws SQLException { throw new ToBeImplementedException(); } - + /** * Get the value of a column in the current row as a Java int. * @@ -2349,7 +2381,7 @@ checkRowPos(); checkColumnBounds(columnIndex); - + try { if (this.thisRow[columnIndex - 1] == null) { this.wasNullFlag = true; @@ -2400,12 +2432,13 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getInt()_-____74") - + new String(intAsBytes) //$NON-NLS-1$ - + "'", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getInt()_-____74") + + new String(intAsBytes) //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -2437,11 +2470,13 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getInt()_-____74") - + val //$NON-NLS-1$ - + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getInt()_-____74") + + val //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } @@ -2481,9 +2516,9 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - - val = val.trim(); - + + val = val.trim(); + int valueAsInt = Integer.parseInt(val); if (this.connection.getJdbcCompliantTruncation()) { @@ -2561,7 +2596,7 @@ checkRowPos(); checkColumnBounds(columnIndex); - + try { if (this.thisRow[columnIndex - 1] == null) { this.wasNullFlag = true; @@ -2612,12 +2647,13 @@ // ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getLong()_-____79") - + new String(longAsBytes) //$NON-NLS-1$ - + "'", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getLong()_-____79") + + new String(longAsBytes) //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -2649,11 +2685,13 @@ // ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getLong()_-____79") - + val //$NON-NLS-1$ - + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getLong()_-____79") + + val //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } @@ -2701,12 +2739,15 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getLong()_-____211") - + val //$NON-NLS-1$ - + Messages.getString("ResultSet.___in_column__212") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getLong()_-____211") + + val //$NON-NLS-1$ + + Messages + .getString("ResultSet.___in_column__212") + + columnIndex, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } @@ -2789,11 +2830,12 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex) throws SQLException { - String stringVal = getNativeString(columnIndex); + checkColumnBounds(columnIndex); + int scale = this.fields[columnIndex - 1].getDecimals(); - return getBigDecimalFromString(stringVal, columnIndex, scale); + return getNativeBigDecimal(columnIndex, scale); } /** @@ -2812,66 +2854,31 @@ */ protected BigDecimal getNativeBigDecimal(int columnIndex, int scale) throws SQLException { - String stringVal = getNativeString(columnIndex); - BigDecimal val; + checkColumnBounds(columnIndex); - if (stringVal != null) { - if (stringVal.length() == 0) { - - val = new BigDecimal(convertToZeroLiteralStringWithEmptyCheck()); + String stringVal = null; - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } + Field f = this.fields[columnIndex - 1]; - try { - val = new BigDecimal(stringVal); - } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____119") //$NON-NLS-1$ - + stringVal - + "' in column " - + columnIndex - + "(" + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } + if (this.thisRow[columnIndex - 1] == null) { + this.wasNullFlag = true; - try { - return val.setScale(scale); - } catch (ArithmeticException ex) { - try { - return val.setScale(scale, BigDecimal.ROUND_HALF_UP); - } catch (ArithmeticException arEx) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____124") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__125") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } + return null; } - return null; + this.wasNullFlag = false; + + switch (f.getSQLType()) { + case Types.DECIMAL: + case Types.NUMERIC: + stringVal = StringUtils + .toAsciiString((byte[]) this.thisRow[columnIndex - 1]); + break; + default: + stringVal = getNativeString(columnIndex); + } + + return getBigDecimalFromString(stringVal, columnIndex, scale); } /** @@ -3010,8 +3017,7 @@ if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getBoolean()", columnIndex, this.thisRow[columnIndex], this.fields[columnIndex], - new int[] { - MysqlDefs.FIELD_TYPE_BIT, + new int[] { MysqlDefs.FIELD_TYPE_BIT, MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, @@ -3019,7 +3025,7 @@ MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } - + String stringVal = getNativeConvertToString(columnIndex, field); return getBooleanFromString(stringVal, columnIndex); @@ -3040,8 +3046,9 @@ protected byte getNativeByte(int columnIndex) throws SQLException { return getNativeByte(columnIndex, true); } - - protected byte getNativeByte(int columnIndex, boolean overflowCheck) throws SQLException { + + protected byte getNativeByte(int columnIndex, boolean overflowCheck) + throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -3073,23 +3080,23 @@ switch (field.getMysqlType()) { case MysqlDefs.FIELD_TYPE_TINY: byte valueAsByte = ((byte[]) this.thisRow[columnIndex])[0]; - + if (!field.isUnsigned()) { return valueAsByte; } - short valueAsShort = (valueAsByte >= 0) ? - valueAsByte : (short)(valueAsByte + (short)256); - + short valueAsShort = (valueAsByte >= 0) ? valueAsByte + : (short) (valueAsByte + (short) 256); + if (overflowCheck && this.connection.getJdbcCompliantTruncation()) { if (valueAsShort > Byte.MAX_VALUE) { throwRangeException(String.valueOf(valueAsShort), columnIndex + 1, Types.TINYINT); } } - - return (byte)valueAsShort; + return (byte) valueAsShort; + case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: valueAsShort = getNativeShort(columnIndex + 1); @@ -3209,7 +3216,7 @@ } Field field = this.fields[columnIndex - 1]; - + int mysqlType = field.getMysqlType(); // Workaround for emulated locators in servers > 4.1, @@ -3228,11 +3235,11 @@ default: int sqlType = field.getSQLType(); - + if (sqlType == Types.VARBINARY || sqlType == Types.BINARY) { return (byte[]) this.thisRow[columnIndex - 1]; } - + return getBytesFromString(getNativeString(columnIndex), columnIndex); } } @@ -3255,7 +3262,7 @@ protected java.io.Reader getNativeCharacterStream(int columnIndex) throws SQLException { String asString = null; - + asString = getStringForClob(columnIndex); if (asString == null) { @@ -3284,33 +3291,32 @@ return getClobFromString(stringVal, columnIndex); } - - /** - * JDBC 4.0 Get a NCLOB column. - * - * @param columnIndex - * the first column is 1, the second is 2, ... - * - * @return an object representing a NCLOB - * - * @throws SQLException - * if an error occurs - */ - protected java.sql.NClob getNativeNClob(int columnIndex) throws SQLException { - String stringVal = getStringForNClob(columnIndex); - if (stringVal == null) { - return null; - } + /** + * JDBC 4.0 Get a NCLOB column. + * + * @param columnIndex + * the first column is 1, the second is 2, ... + * + * @return an object representing a NCLOB + * + * @throws SQLException + * if an error occurs + */ + protected java.sql.NClob getNativeNClob(int columnIndex) + throws SQLException { + String stringVal = getStringForNClob(columnIndex); - return getNClobFromString(stringVal, columnIndex); - } + if (stringVal == null) { + return null; + } - private String getNativeConvertToString(int columnIndex, - Field field) + return getNClobFromString(stringVal, columnIndex); + } + + private String getNativeConvertToString(int columnIndex, Field field) throws SQLException { - int sqlType = field.getSQLType(); int mysqlType = field.getMysqlType(); @@ -3428,15 +3434,18 @@ try { val = new BigDecimal(stringVal); } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__87") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__87") + + columnIndex + + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } return val.toString(); @@ -3473,8 +3482,8 @@ objIn.close(); bytesIn.close(); } catch (ClassNotFoundException cnfe) { - throw SQLError.createSQLException( - Messages + throw SQLError + .createSQLException(Messages .getString("ResultSet.Class_not_found___91") //$NON-NLS-1$ + cnfe.toString() + Messages @@ -3527,7 +3536,8 @@ return String.valueOf(dt); case Types.TIME: - Time tm = getNativeTime(columnIndex, null, this.defaultTimeZone, false); + Time tm = getNativeTime(columnIndex, null, this.defaultTimeZone, + false); if (tm == null) { return null; @@ -3536,8 +3546,8 @@ return String.valueOf(tm); case Types.TIMESTAMP: - Timestamp tstamp = getNativeTimestamp(columnIndex, - null, this.defaultTimeZone, false); + Timestamp tstamp = getNativeTimestamp(columnIndex, null, + this.defaultTimeZone, false); if (tstamp == null) { return null; @@ -3594,7 +3604,9 @@ checkRowPos(); checkColumnBounds(columnIndex); - if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) { + int mysqlType = this.fields[columnIndex - 1].getMysqlType(); + + if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) { byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; if (bits == null) { @@ -3630,9 +3642,10 @@ return null; } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION .equals(this.connection.getZeroDateTimeBehavior())) { - throw SQLError.createSQLException( - "Value '0000-00-00' can not be represented as java.sql.Date", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + "Value '0000-00-00' can not be represented as java.sql.Date", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } year = 1; @@ -3640,20 +3653,29 @@ day = 1; } - return fastDateCreate( - getCalendarInstanceForSessionOrNew(), year, month, day); + return fastDateCreate(getCalendarInstanceForSessionOrNew(), year, + month, day); } + boolean rollForward = (tz != null && !tz.equals(this + .getDefaultTimeZone())); + + return (Date) getNativeDateTimeValue(columnIndex, null, Types.DATE, + mysqlType, tz, rollForward); + } + + private java.sql.Date getNativeDateViaParseConversion(int columnIndex) + throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getDate()", columnIndex, - this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], + this.thisRow[columnIndex - 1], + this.fields[columnIndex - 1], new int[] { MysqlDefs.FIELD_TYPE_DATE }); } String stringVal = getNativeString(columnIndex); return getDateFromString(stringVal, columnIndex); - } /** @@ -3681,8 +3703,8 @@ this.wasNullFlag = false; - Field f= this.fields[columnIndex]; - + Field f = this.fields[columnIndex]; + switch (f.getMysqlType()) { case MysqlDefs.FIELD_TYPE_DOUBLE: byte[] bits = (byte[]) this.thisRow[columnIndex]; @@ -3701,33 +3723,33 @@ if (!f.isUnsigned()) { return (double) getNativeByte(columnIndex + 1); } - + return (double) getNativeShort(columnIndex + 1); case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: if (!f.isUnsigned()) { return (double) getNativeShort(columnIndex + 1); } - + return (double) getNativeInt(columnIndex + 1); case MysqlDefs.FIELD_TYPE_INT24: case MysqlDefs.FIELD_TYPE_LONG: if (!f.isUnsigned()) { return (double) getNativeInt(columnIndex + 1); } - + return (double) getNativeLong(columnIndex + 1); case MysqlDefs.FIELD_TYPE_LONGLONG: valueAsLong = getNativeLong(columnIndex + 1); - + if (!f.isUnsigned()) { return (double) valueAsLong; } - + BigInteger asBigInt = convertLongToUlong(valueAsLong); - + // TODO: Check for overflow - + return asBigInt.doubleValue(); case MysqlDefs.FIELD_TYPE_FLOAT: return (double) getNativeFloat(columnIndex + 1); @@ -3777,50 +3799,49 @@ this.wasNullFlag = false; Field f = this.fields[columnIndex]; - + switch (f.getMysqlType()) { case MysqlDefs.FIELD_TYPE_DOUBLE: double valueAsDouble = getNativeDouble(columnIndex + 1); - - if (this.connection.getJdbcCompliantTruncation() && - (valueAsDouble < Float.MIN_VALUE || - valueAsDouble > Float.MAX_VALUE)) { - throwRangeException(String.valueOf(valueAsDouble), + + if (this.connection.getJdbcCompliantTruncation() + && (valueAsDouble < Float.MIN_VALUE || valueAsDouble > Float.MAX_VALUE)) { + throwRangeException(String.valueOf(valueAsDouble), columnIndex + 1, Types.FLOAT); } - + return (float) getNativeDouble(columnIndex + 1); case MysqlDefs.FIELD_TYPE_TINY: if (!f.isUnsigned()) { return (float) getNativeByte(columnIndex + 1); } - + return (float) getNativeShort(columnIndex + 1); case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: if (!f.isUnsigned()) { return (float) getNativeShort(columnIndex + 1); } - + return (float) getNativeInt(columnIndex + 1); case MysqlDefs.FIELD_TYPE_INT24: case MysqlDefs.FIELD_TYPE_LONG: if (!f.isUnsigned()) { return (float) getNativeInt(columnIndex + 1); } - + return (float) getNativeLong(columnIndex + 1); case MysqlDefs.FIELD_TYPE_LONGLONG: long valueAsLong = getNativeLong(columnIndex + 1); - + if (!f.isUnsigned()) { return (float) valueAsLong; } - + BigInteger asBigInt = convertLongToUlong(valueAsLong); - + // TODO: Check for overflow - + return asBigInt.floatValue(); case MysqlDefs.FIELD_TYPE_FLOAT: byte[] bits = (byte[]) this.thisRow[columnIndex]; @@ -3863,8 +3884,9 @@ protected int getNativeInt(int columnIndex) throws SQLException { return getNativeInt(columnIndex, false); } - - protected int getNativeInt(int columnIndex, boolean overflowCheck) throws SQLException { + + protected int getNativeInt(int columnIndex, boolean overflowCheck) + throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -3884,7 +3906,7 @@ case MysqlDefs.FIELD_TYPE_TINY: byte tinyintVal = getNativeByte(columnIndex + 1, false); - + if (!f.isUnsigned() || tinyintVal >= 0) { return tinyintVal; } @@ -3893,7 +3915,7 @@ case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: short asShort = getNativeShort(columnIndex + 1, false); - + if (!f.isUnsigned() || asShort >= 0) { return asShort; } @@ -3906,20 +3928,20 @@ int valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8) | ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24); - if (!f.isUnsigned()) { + if (!f.isUnsigned()) { return valueAsInt; } - - long valueAsLong = (valueAsInt >= 0) ? - valueAsInt : valueAsInt + 4294967296L; - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - valueAsLong > Integer.MAX_VALUE) { + + long valueAsLong = (valueAsInt >= 0) ? valueAsInt + : valueAsInt + 4294967296L; + + if (overflowCheck && this.connection.getJdbcCompliantTruncation() + && valueAsLong > Integer.MAX_VALUE) { throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.INTEGER); } - - return (int)valueAsLong; + + return (int) valueAsLong; case MysqlDefs.FIELD_TYPE_LONGLONG: valueAsLong = getNativeLong(columnIndex + 1, false, true); @@ -3990,8 +4012,8 @@ protected long getNativeLong(int columnIndex) throws SQLException { return getNativeLong(columnIndex, false, true); } - - protected long getNativeLong(int columnIndex, boolean overflowCheck, + + protected long getNativeLong(int columnIndex, boolean overflowCheck, boolean expandUnsignedLong) throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -4027,7 +4049,7 @@ case MysqlDefs.FIELD_TYPE_INT24: case MysqlDefs.FIELD_TYPE_LONG: int asInt = getNativeInt(columnIndex + 1); - + if (!f.isUnsigned() || asInt >= 0) { return asInt; } @@ -4049,16 +4071,19 @@ if (!f.isUnsigned() || !expandUnsignedLong) { return valueAsLong; } - + BigInteger asBigInt = convertLongToUlong(valueAsLong); - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - ((asBigInt.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0 ) || - (asBigInt.compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0))) { - throwRangeException(asBigInt.toString(), - columnIndex + 1, Types.BIGINT); + + if (overflowCheck + && this.connection.getJdbcCompliantTruncation() + && ((asBigInt.compareTo(new BigInteger(String + .valueOf(Long.MAX_VALUE))) > 0) || (asBigInt + .compareTo(new BigInteger(String + .valueOf(Long.MIN_VALUE))) < 0))) { + throwRangeException(asBigInt.toString(), columnIndex + 1, + Types.BIGINT); } - + return getLongFromString(asBigInt.toString(), columnIndex + 1); case MysqlDefs.FIELD_TYPE_DOUBLE: @@ -4135,8 +4160,9 @@ protected short getNativeShort(int columnIndex) throws SQLException { return getNativeShort(columnIndex, true); } - - protected short getNativeShort(int columnIndex, boolean overflowCheck) throws SQLException { + + protected short getNativeShort(int columnIndex, boolean overflowCheck) + throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -4156,82 +4182,88 @@ case MysqlDefs.FIELD_TYPE_TINY: byte tinyintVal = getNativeByte(columnIndex + 1); - + if (!f.isUnsigned()) { return tinyintVal; } - return (short)(tinyintVal + (short)256); + return (short) (tinyintVal + (short) 256); case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: byte[] bits = (byte[]) this.thisRow[columnIndex]; - + short asShort = (short) ((bits[0] & 0xff) | ((bits[1] & 0xff) << 8)); if (!f.isUnsigned()) { return asShort; } - + int valueAsInt = asShort & 0xffff; - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - valueAsInt > Short.MAX_VALUE) { + + if (overflowCheck && this.connection.getJdbcCompliantTruncation() + && valueAsInt > Short.MAX_VALUE) { throwRangeException(String.valueOf(valueAsInt), columnIndex + 1, Types.SMALLINT); } - - return (short)valueAsInt; + + return (short) valueAsInt; case MysqlDefs.FIELD_TYPE_INT24: case MysqlDefs.FIELD_TYPE_LONG: if (!f.isUnsigned()) { valueAsInt = getNativeInt(columnIndex + 1, false); - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - valueAsInt > Short.MAX_VALUE || - valueAsInt < Short.MIN_VALUE) { + + if (overflowCheck + && this.connection.getJdbcCompliantTruncation() + && valueAsInt > Short.MAX_VALUE + || valueAsInt < Short.MIN_VALUE) { throwRangeException(String.valueOf(valueAsInt), columnIndex + 1, Types.SMALLINT); } - - return (short)valueAsInt; + + return (short) valueAsInt; } - + long valueAsLong = getNativeLong(columnIndex + 1, false, true); - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - valueAsLong > Short.MAX_VALUE) { + + if (overflowCheck && this.connection.getJdbcCompliantTruncation() + && valueAsLong > Short.MAX_VALUE) { throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.SMALLINT); } - - return (short)valueAsLong; - + + return (short) valueAsLong; + case MysqlDefs.FIELD_TYPE_LONGLONG: valueAsLong = getNativeLong(columnIndex + 1, false, false); - + if (!f.isUnsigned()) { - if (overflowCheck && this.connection.getJdbcCompliantTruncation()) { + if (overflowCheck + && this.connection.getJdbcCompliantTruncation()) { if (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE) { throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.SMALLINT); } } - + return (short) valueAsLong; } - + BigInteger asBigInt = convertLongToUlong(valueAsLong); - - if (overflowCheck && this.connection.getJdbcCompliantTruncation() && - ((asBigInt.compareTo(new BigInteger(String.valueOf(Short.MAX_VALUE))) > 0 ) || - (asBigInt.compareTo(new BigInteger(String.valueOf(Short.MIN_VALUE))) < 0))) { - throwRangeException(asBigInt.toString(), - columnIndex + 1, Types.SMALLINT); + + if (overflowCheck + && this.connection.getJdbcCompliantTruncation() + && ((asBigInt.compareTo(new BigInteger(String + .valueOf(Short.MAX_VALUE))) > 0) || (asBigInt + .compareTo(new BigInteger(String + .valueOf(Short.MIN_VALUE))) < 0))) { + throwRangeException(asBigInt.toString(), columnIndex + 1, + Types.SMALLINT); } - - return (short)getIntFromString(asBigInt.toString(), columnIndex + 1); + return (short) getIntFromString(asBigInt.toString(), + columnIndex + 1); + case MysqlDefs.FIELD_TYPE_DOUBLE: double valueAsDouble = getNativeDouble(columnIndex + 1); @@ -4291,10 +4323,11 @@ checkColumnBounds(columnIndex); if (this.fields == null) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Query_generated_no_fields_for_ResultSet_133"), //$NON-NLS-1$ - SQLError.SQL_STATE_INVALID_COLUMN_NUMBER); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Query_generated_no_fields_for_ResultSet_133"), //$NON-NLS-1$ + SQLError.SQL_STATE_INVALID_COLUMN_NUMBER); } try { @@ -4343,8 +4376,7 @@ } private Time getNativeTime(int columnIndex, Calendar targetCalendar, - TimeZone tz, boolean rollForward) - throws SQLException { + TimeZone tz, boolean rollForward) throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -4376,37 +4408,42 @@ } Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); - + synchronized (sessionCalendar) { - Time time = TimeUtil - .fastTimeCreate(sessionCalendar, hour, - minute, seconds); - - Time adjustedTime = TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - time, - this.connection.getServerTimezoneTZ(), tz, rollForward); + Time time = TimeUtil.fastTimeCreate(sessionCalendar, hour, + minute, seconds); + Time adjustedTime = TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, time, this.connection + .getServerTimezoneTZ(), tz, rollForward); + return adjustedTime; } } + return (Time) getNativeDateTimeValue(columnIndex, targetCalendar, + Types.TIME, mysqlType, tz, rollForward); + } + + private Time getNativeTimeViaParseConversion(int columnIndex, + Calendar targetCalendar, TimeZone tz, boolean rollForward) + throws SQLException { if (this.useUsageAdvisor) { issueConversionViaParsingWarning("getTime()", columnIndex, - this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], + this.thisRow[columnIndex - 1], + this.fields[columnIndex - 1], new int[] { MysqlDefs.FIELD_TYPE_TIME }); } String strTime = getNativeString(columnIndex); - return getTimeFromString(strTime, targetCalendar, columnIndex, tz, rollForward); + return getTimeFromString(strTime, targetCalendar, columnIndex, tz, + rollForward); } - private Timestamp getNativeTimestamp(int columnIndex, - Calendar targetCalendar, - TimeZone tz, - boolean rollForward) throws SQLException { + private Timestamp getNativeTimestamp(int columnIndex, + Calendar targetCalendar, TimeZone tz, boolean rollForward) + throws SQLException { checkRowPos(); checkColumnBounds(columnIndex); @@ -4463,9 +4500,10 @@ return null; } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION .equals(this.connection.getZeroDateTimeBehavior())) { - throw SQLError.createSQLException( - "Value '0000-00-00' can not be represented as java.sql.Timestamp", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + "Value '0000-00-00' can not be represented as java.sql.Timestamp", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } year = 1; @@ -4473,39 +4511,42 @@ day = 1; } - Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? - this.connection.getUtcCalendar() : - getCalendarInstanceForSessionOrNew(); - + Calendar sessionCalendar = this.connection + .getUseJDBCCompliantTimezoneShift() ? this.connection + .getUtcCalendar() : getCalendarInstanceForSessionOrNew(); + synchronized (sessionCalendar) { - Timestamp ts = fastTimestampCreate( - sessionCalendar, year, month, day, - hour, minute, seconds, nanos); - - Timestamp adjustedTs = TimeUtil.changeTimezone( - this.connection, sessionCalendar, - targetCalendar, - ts, - this.connection.getServerTimezoneTZ(), tz, rollForward); - + Timestamp ts = fastTimestampCreate(sessionCalendar, year, + month, day, hour, minute, seconds, nanos); + + Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, ts, this.connection + .getServerTimezoneTZ(), tz, rollForward); + return adjustedTs; } default: + return (Timestamp) getNativeDateTimeValue(columnIndex, + targetCalendar, Types.TIMESTAMP, mysqlType, tz, rollForward); + } + } - if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getTimestamp()", columnIndex, - this.thisRow[columnIndex - 1], this.fields[columnIndex - 1], - new int[] { MysqlDefs.FIELD_TYPE_TIMESTAMP, - MysqlDefs.FIELD_TYPE_DATETIME }); - } + private Timestamp getNativeTimestampViaParseConversion(int columnIndex, + Calendar targetCalendar, TimeZone tz, boolean rollForward) + throws SQLException { + if (this.useUsageAdvisor) { + issueConversionViaParsingWarning("getTimestamp()", columnIndex, + this.thisRow[columnIndex - 1], + this.fields[columnIndex - 1], new int[] { + MysqlDefs.FIELD_TYPE_TIMESTAMP, + MysqlDefs.FIELD_TYPE_DATETIME }); + } - String strTimestamp = getNativeString(columnIndex); + String strTimestamp = getNativeString(columnIndex); - return getTimestampFromString(columnIndex, targetCalendar, - strTimestamp, tz, - rollForward); - } + return getTimestampFromString(columnIndex, targetCalendar, + strTimestamp, tz, rollForward); } // --------------------------------------------------------------------- @@ -4555,90 +4596,90 @@ } } - /** - * JDBC 4.0 - * - *

- * Get the value of a column in the current row as a java.io.Reader. - *

- * - * @param columnIndex - * the column to get the value from - * - * @return the value in the column as a java.io.Reader. - * - * @throws SQLException - * if an error occurs - */ + /** + * JDBC 4.0 + * + *

+ * Get the value of a column in the current row as a java.io.Reader. + *

+ * + * @param columnIndex + * the column to get the value from + * + * @return the value in the column as a java.io.Reader. + * + * @throws SQLException + * if an error occurs + */ public Reader getNCharacterStream(int columnIndex) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException( - "Can not call getNCharacterStream() when field's charset isn't UTF-8"); - } + String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException( + "Can not call getNCharacterStream() when field's charset isn't UTF-8"); + } return getCharacterStream(columnIndex); } - /** - * JDBC 4.0 - * - *

- * Get the value of a column in the current row as a java.io.Reader. - *

- * - * @param columnName - * the column name to retrieve the value from - * - * @return the value as a java.io.Reader - * - * @throws SQLException - * if an error occurs - */ + /** + * JDBC 4.0 + * + *

+ * Get the value of a column in the current row as a java.io.Reader. + *

+ * + * @param columnName + * the column name to retrieve the value from + * + * @return the value as a java.io.Reader + * + * @throws SQLException + * if an error occurs + */ public Reader getNCharacterStream(String columnName) throws SQLException { return getNCharacterStream(findColumn(columnName)); } - /** - * JDBC 4.0 Get a NCLOB column. - * - * @param i - * the first column is 1, the second is 2, ... - * - * @return an object representing a NCLOB - * - * @throws SQLException - * if an error occurs - */ + /** + * JDBC 4.0 Get a NCLOB column. + * + * @param i + * the first column is 1, the second is 2, ... + * + * @return an object representing a NCLOB + * + * @throws SQLException + * if an error occurs + */ public NClob getNClob(int columnIndex) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException( - "Can not call getNClob() when field's charset isn't UTF-8"); - } - if (!this.isBinaryEncoded) { - String asString = getStringForNClob(columnIndex); - - if (asString == null) { - return null; - } + String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException( + "Can not call getNClob() when field's charset isn't UTF-8"); + } + if (!this.isBinaryEncoded) { + String asString = getStringForNClob(columnIndex); - return new com.mysql.jdbc.NClob(asString); - } + if (asString == null) { + return null; + } - return getNativeNClob(columnIndex); - } + return new com.mysql.jdbc.NClob(asString); + } - /** - * JDBC 4.0 Get a NCLOB column. - * - * @param colName - * the column name - * - * @return an object representing a NCLOB - * - * @throws SQLException - * if an error occurs - */ + return getNativeNClob(columnIndex); + } + + /** + * JDBC 4.0 Get a NCLOB column. + * + * @param colName + * the column name + * + * @return an object representing a NCLOB + * + * @throws SQLException + * if an error occurs + */ public NClob getNClob(String columnName) throws SQLException { return getNClob(findColumn(columnName)); } @@ -4651,43 +4692,43 @@ protected ResultSet getNextResultSet() { return this.nextResultSet; } - - /** - * JDBC 4.0 - * - * Get the value of a column in the current row as a Java String - * - * @param columnIndex - * the first column is 1, the second is 2... - * - * @return the column value, null for SQL NULL - * - * @exception SQLException - * if a database access error occurs - */ + + /** + * JDBC 4.0 + * + * Get the value of a column in the current row as a Java String + * + * @param columnIndex + * the first column is 1, the second is 2... + * + * @return the column value, null for SQL NULL + * + * @exception SQLException + * if a database access error occurs + */ public String getNString(int columnIndex) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException( - "Can not call getNString() when field's charset isn't UTF-8"); - } + String fieldEncoding = this.fields[columnIndex - 1].getCharacterSet(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException( + "Can not call getNString() when field's charset isn't UTF-8"); + } return getString(columnIndex); } - /** - * JDBC 4.0 - * - * The following routines simply convert the columnName into a columnIndex - * and then call the appropriate routine above. - * - * @param columnName - * is the SQL name of the column - * - * @return the column value - * - * @exception SQLException - * if a database access error occurs - */ + /** + * JDBC 4.0 + * + * The following routines simply convert the columnName into a columnIndex + * and then call the appropriate routine above. + * + * @param columnName + * is the SQL name of the column + * + * @return the column value + * + * @exception SQLException + * if a database access error occurs + */ public String getNString(String columnName) throws SQLException { return getNString(findColumn(columnName)); } @@ -4795,13 +4836,13 @@ case Types.INTEGER: - if (!field.isUnsigned() || - field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) { + if (!field.isUnsigned() + || field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) { return new Integer(getInt(columnIndex)); } return new Long(getLong(columnIndex)); - + case Types.BIGINT: if (!field.isUnsigned()) { @@ -4839,15 +4880,18 @@ try { val = new BigDecimal(stringVal); } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__87") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__87") + + columnIndex + + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } return val; @@ -4899,8 +4943,8 @@ objIn.close(); bytesIn.close(); } catch (ClassNotFoundException cnfe) { - throw SQLError.createSQLException( - Messages + throw SQLError + .createSQLException(Messages .getString("ResultSet.Class_not_found___91") //$NON-NLS-1$ + cnfe.toString() + Messages @@ -5043,8 +5087,8 @@ case Types.INTEGER: - if (!field.isUnsigned() || - field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) { + if (!field.isUnsigned() + || field.getMysqlType() == MysqlDefs.FIELD_TYPE_INT24) { return new Integer(getInt(columnIndex)); } @@ -5074,15 +5118,18 @@ try { val = new BigDecimal(stringVal); } catch (NumberFormatException ex) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__87") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ + + stringVal + + Messages + .getString("ResultSet.___in_column__87") + + columnIndex + + "(" //$NON-NLS-1$ + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } return val; @@ -5099,8 +5146,8 @@ return new Double(getFloat(columnIndex)); } else { return new Float(getFloat(columnIndex)); // NB - bug in JDBC - // compliance test, - // according + // compliance test, + // according // to JDBC spec, FLOAT type should return DOUBLE // but causes ClassCastException in CTS :( } @@ -5256,7 +5303,7 @@ checkRowPos(); checkColumnBounds(columnIndex); - + try { if (this.thisRow[columnIndex - 1] == null) { this.wasNullFlag = true; @@ -5307,12 +5354,13 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getShort()_-____96") - + new String(shortAsBytes) //$NON-NLS-1$ - + "'", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getShort()_-____96") + + new String(shortAsBytes) //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -5346,11 +5394,13 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getShort()_-____96") - + val //$NON-NLS-1$ - + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getShort()_-____96") + + val //$NON-NLS-1$ + + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } @@ -5398,12 +5448,15 @@ ; // ignore, it's not a number } - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Invalid_value_for_getShort()_-____217") - + val //$NON-NLS-1$ - + Messages.getString("ResultSet.___in_column__218") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Invalid_value_for_getShort()_-____217") + + val //$NON-NLS-1$ + + Messages + .getString("ResultSet.___in_column__218") + + columnIndex, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } @@ -5426,14 +5479,15 @@ */ public java.sql.Statement getStatement() throws SQLException { if (this.isClosed && !this.retainOwningStatement) { - throw SQLError.createSQLException( - "Operation not allowed on closed ResultSet. Statements " - + "can be retained over result set closure by setting the connection property " - + "\"retainStatementAfterResultSetClose\" to \"true\".", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError + .createSQLException( + "Operation not allowed on closed ResultSet. Statements " + + "can be retained over result set closure by setting the connection property " + + "\"retainStatementAfterResultSetClose\" to \"true\".", + SQLError.SQL_STATE_GENERAL_ERROR); } - + if (this.wrapperStatement != null) { return this.wrapperStatement; } @@ -5474,10 +5528,9 @@ private String getStringForClob(int columnIndex) throws SQLException { String asString = null; - - String forcedEncoding = - this.connection.getClobCharacterEncoding(); - + + String forcedEncoding = this.connection.getClobCharacterEncoding(); + if (forcedEncoding == null) { if (!this.isBinaryEncoded) { asString = getString(columnIndex); @@ -5487,50 +5540,51 @@ } else { try { byte[] asBytes = null; - + if (!this.isBinaryEncoded) { asBytes = getBytes(columnIndex); } else { asBytes = getNativeBytes(columnIndex, true); } - + if (asBytes != null) { asString = new String(asBytes, forcedEncoding); } } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException("Unsupported character encoding " + - forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError.createSQLException( + "Unsupported character encoding " + forcedEncoding, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } - + return asString; } - - private String getStringForNClob(int columnIndex) throws SQLException { - String asString = null; - - String forcedEncoding = "UTF-8"; - - try { - byte[] asBytes = null; - - if (!this.isBinaryEncoded) { - asBytes = getBytes(columnIndex); - } else { - asBytes = getNativeBytes(columnIndex, true); - } - - if (asBytes != null) { - asString = new String(asBytes, forcedEncoding); - } - } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException("Unsupported character encoding " + - forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - return asString; - } + private String getStringForNClob(int columnIndex) throws SQLException { + String asString = null; + + String forcedEncoding = "UTF-8"; + + try { + byte[] asBytes = null; + + if (!this.isBinaryEncoded) { + asBytes = getBytes(columnIndex); + } else { + asBytes = getNativeBytes(columnIndex, true); + } + + if (asBytes != null) { + asString = new String(asBytes, forcedEncoding); + } + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException("Unsupported character encoding " + + forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + return asString; + } + protected String getStringInternal(int columnIndex, boolean checkDateTypes) throws SQLException { if (!this.isBinaryEncoded) { @@ -5538,10 +5592,11 @@ checkColumnBounds(columnIndex); if (this.fields == null) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Query_generated_no_fields_for_ResultSet_99"), //$NON-NLS-1$ - SQLError.SQL_STATE_INVALID_COLUMN_NUMBER); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Query_generated_no_fields_for_ResultSet_99"), //$NON-NLS-1$ + SQLError.SQL_STATE_INVALID_COLUMN_NUMBER); } try { @@ -5582,10 +5637,11 @@ } } } catch (java.io.UnsupportedEncodingException E) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$ - + encoding + "'.", "0S100"); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$ + + encoding + "'.", "0S100"); } } else { stringVal = StringUtils @@ -5620,8 +5676,8 @@ if (checkDateTypes && !this.connection.getNoDatetimeStringSync()) { switch (this.fields[columnIndex].getSQLType()) { case Types.TIME: - Time tm = getTimeFromString(stringVal, null, columnIndex + 1, - this.getDefaultTimeZone(), false); + Time tm = getTimeFromString(stringVal, null, + columnIndex + 1, this.getDefaultTimeZone(), false); if (tm == null) { this.wasNullFlag = true; @@ -5681,7 +5737,8 @@ * if a database access error occurs */ public Time getTime(int columnIndex) throws java.sql.SQLException { - return getTimeInternal(columnIndex, null, this.getDefaultTimeZone(), false); + return getTimeInternal(columnIndex, null, this.getDefaultTimeZone(), + false); } /** @@ -5739,22 +5796,21 @@ return getTime(findColumn(columnName), cal); } - private Time getTimeFromString(String timeAsString, Calendar targetCalendar, - int columnIndex, - TimeZone tz, + private Time getTimeFromString(String timeAsString, + Calendar targetCalendar, int columnIndex, TimeZone tz, boolean rollForward) throws SQLException { int hr = 0; int min = 0; int sec = 0; try { - + if (timeAsString == null) { this.wasNullFlag = true; return null; - } - + } + // // JDK-6 doesn't like trailing whitespace // @@ -5762,11 +5818,10 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - + timeAsString = timeAsString.trim(); - - if (timeAsString.equals("0") - || timeAsString.equals("0000-00-00") + + if (timeAsString.equals("0") || timeAsString.equals("0000-00-00") || timeAsString.equals("0000-00-00 00:00:00") || timeAsString.equals("00000000000000")) { if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL @@ -5816,13 +5871,15 @@ break; default: - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$ - + columnIndex - + "(" - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$ + + columnIndex + + "(" + + this.fields[columnIndex - 1] + + ").", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } /* endswitch */ SQLWarning precisionLost = new SQLWarning( @@ -5856,7 +5913,7 @@ } } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) { return fastTimeCreate(null, 0, 0, 0); // midnight on the given - // date + // date } else { // convert a String to a Time if ((timeAsString.length() != 5) @@ -5874,16 +5931,14 @@ .parseInt(timeAsString.substring(6)); } - Calendar sessionCalendar = this.getCalendarInstanceForSessionOrNew(); - + Calendar sessionCalendar = this + .getCalendarInstanceForSessionOrNew(); + synchronized (sessionCalendar) { - return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimeCreate( - sessionCalendar, hr, min, sec), - this.connection.getServerTimezoneTZ(), - tz, rollForward); + return TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, fastTimeCreate( + sessionCalendar, hr, min, sec), this.connection + .getServerTimezoneTZ(), tz, rollForward); } } catch (Exception ex) { throw SQLError.createSQLException(ex.toString(), @@ -5906,16 +5961,15 @@ * if a database access error occurs */ private Time getTimeInternal(int columnIndex, Calendar targetCalendar, - TimeZone tz, - boolean rollForward) throws java.sql.SQLException { + TimeZone tz, boolean rollForward) throws java.sql.SQLException { if (this.isBinaryEncoded) { return getNativeTime(columnIndex, targetCalendar, tz, rollForward); } String timeAsString = getStringInternal(columnIndex, false); - return getTimeFromString(timeAsString, targetCalendar, - columnIndex, tz, rollForward); + return getTimeFromString(timeAsString, targetCalendar, columnIndex, tz, + rollForward); } /** @@ -5931,8 +5985,8 @@ * if a database access error occurs */ public Timestamp getTimestamp(int columnIndex) throws java.sql.SQLException { - return getTimestampInternal(columnIndex, null, this.getDefaultTimeZone(), - false); + return getTimestampInternal(columnIndex, null, this + .getDefaultTimeZone(), false); } /** @@ -5994,15 +6048,14 @@ } private Timestamp getTimestampFromString(int columnIndex, - Calendar targetCalendar, - String timestampValue, TimeZone tz, boolean rollForward) - throws java.sql.SQLException { + Calendar targetCalendar, String timestampValue, TimeZone tz, + boolean rollForward) throws java.sql.SQLException { try { this.wasNullFlag = false; - + if (timestampValue == null) { this.wasNullFlag = true; - + return null; } @@ -6013,15 +6066,15 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - + timestampValue = timestampValue.trim(); - + int length = timestampValue.length(); - - Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? - this.connection.getUtcCalendar() : - getCalendarInstanceForSessionOrNew(); - + + Calendar sessionCalendar = this.connection + .getUseJDBCCompliantTimezoneShift() ? this.connection + .getUtcCalendar() : getCalendarInstanceForSessionOrNew(); + synchronized (sessionCalendar) { if ((length > 0) && (timestampValue.charAt(0) == '0') @@ -6029,40 +6082,41 @@ || timestampValue.equals("0000-00-00 00:00:00") || timestampValue.equals("00000000000000") || timestampValue .equals("0"))) { - + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL .equals(this.connection.getZeroDateTimeBehavior())) { this.wasNullFlag = true; - + return null; } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION .equals(this.connection.getZeroDateTimeBehavior())) { - throw SQLError.createSQLException("Value '" + timestampValue - + " can not be represented as java.sql.Timestamp", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + "Value '" + + timestampValue + + " can not be represented as java.sql.Timestamp", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } - + // We're left with the case of 'round' to a date Java _can_ // represent, which is '0001-01-01'. return fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0); - + } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) { - + return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, - Integer - .parseInt(timestampValue.substring(0, 4)), 1, - 1, 0, 0, 0, 0), this.connection + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, Integer + .parseInt(timestampValue.substring(0, 4)), + 1, 1, 0, 0, 0, 0), this.connection .getServerTimezoneTZ(), tz, rollForward); - + } else { if (timestampValue.endsWith(".")) { - timestampValue = timestampValue.substring(0, timestampValue - .length() - 1); + timestampValue = timestampValue.substring(0, + timestampValue.length() - 1); } - + // Convert from TIMESTAMP or DATE switch (length) { case 26: @@ -6073,24 +6127,27 @@ case 21: case 20: case 19: { - int year = Integer.parseInt(timestampValue.substring(0, 4)); - int month = Integer - .parseInt(timestampValue.substring(5, 7)); - int day = Integer.parseInt(timestampValue.substring(8, 10)); - int hour = Integer.parseInt(timestampValue - .substring(11, 13)); - int minutes = Integer.parseInt(timestampValue.substring(14, - 16)); - int seconds = Integer.parseInt(timestampValue.substring(17, - 19)); - + int year = Integer.parseInt(timestampValue.substring(0, + 4)); + int month = Integer.parseInt(timestampValue.substring( + 5, 7)); + int day = Integer.parseInt(timestampValue.substring(8, + 10)); + int hour = Integer.parseInt(timestampValue.substring( + 11, 13)); + int minutes = Integer.parseInt(timestampValue + .substring(14, 16)); + int seconds = Integer.parseInt(timestampValue + .substring(17, 19)); + int nanos = 0; - + if (length > 19) { int decimalIndex = timestampValue.lastIndexOf('.'); - + if (decimalIndex != -1) { - if ((decimalIndex + 2) <= timestampValue.length()) { + if ((decimalIndex + 2) <= timestampValue + .length()) { nanos = Integer.parseInt(timestampValue .substring(decimalIndex + 1)); } else { @@ -6103,188 +6160,209 @@ } } } - - return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year, month, day, hour, - minutes, seconds, nanos), this.connection - .getServerTimezoneTZ(), tz, rollForward); + + return TimeUtil + .changeTimezone(this.connection, + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, + year, month, day, hour, + minutes, seconds, nanos), + this.connection.getServerTimezoneTZ(), + tz, rollForward); } - + case 14: { - int year = Integer.parseInt(timestampValue.substring(0, 4)); - int month = Integer - .parseInt(timestampValue.substring(4, 6)); - int day = Integer.parseInt(timestampValue.substring(6, 8)); - int hour = Integer - .parseInt(timestampValue.substring(8, 10)); - int minutes = Integer.parseInt(timestampValue.substring(10, - 12)); - int seconds = Integer.parseInt(timestampValue.substring(12, - 14)); - + int year = Integer.parseInt(timestampValue.substring(0, + 4)); + int month = Integer.parseInt(timestampValue.substring( + 4, 6)); + int day = Integer.parseInt(timestampValue.substring(6, + 8)); + int hour = Integer.parseInt(timestampValue.substring(8, + 10)); + int minutes = Integer.parseInt(timestampValue + .substring(10, 12)); + int seconds = Integer.parseInt(timestampValue + .substring(12, 14)); + return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year, month, day, hour, - minutes, seconds, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, year, + month, day, hour, minutes, seconds, 0), + this.connection.getServerTimezoneTZ(), tz, + rollForward); } - + case 12: { - int year = Integer.parseInt(timestampValue.substring(0, 2)); - + int year = Integer.parseInt(timestampValue.substring(0, + 2)); + if (year <= 69) { year = (year + 100); } - - int month = Integer - .parseInt(timestampValue.substring(2, 4)); - int day = Integer.parseInt(timestampValue.substring(4, 6)); - int hour = Integer.parseInt(timestampValue.substring(6, 8)); - int minutes = Integer.parseInt(timestampValue.substring(8, - 10)); - int seconds = Integer.parseInt(timestampValue.substring(10, - 12)); - - return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year + 1900, month, day, - hour, minutes, seconds, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + + int month = Integer.parseInt(timestampValue.substring( + 2, 4)); + int day = Integer.parseInt(timestampValue.substring(4, + 6)); + int hour = Integer.parseInt(timestampValue.substring(6, + 8)); + int minutes = Integer.parseInt(timestampValue + .substring(8, 10)); + int seconds = Integer.parseInt(timestampValue + .substring(10, 12)); + + return TimeUtil + .changeTimezone(this.connection, + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, + year + 1900, month, day, hour, + minutes, seconds, 0), + this.connection.getServerTimezoneTZ(), + tz, rollForward); } - + case 10: { int year; int month; int day; int hour; int minutes; - + if ((this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) || (timestampValue.indexOf("-") != -1)) { - year = Integer.parseInt(timestampValue.substring(0, 4)); - month = Integer - .parseInt(timestampValue.substring(5, 7)); - day = Integer.parseInt(timestampValue.substring(8, 10)); + year = Integer.parseInt(timestampValue.substring(0, + 4)); + month = Integer.parseInt(timestampValue.substring( + 5, 7)); + day = Integer.parseInt(timestampValue.substring(8, + 10)); hour = 0; minutes = 0; } else { - year = Integer.parseInt(timestampValue.substring(0, 2)); - + year = Integer.parseInt(timestampValue.substring(0, + 2)); + if (year <= 69) { year = (year + 100); } - - month = Integer - .parseInt(timestampValue.substring(2, 4)); - day = Integer.parseInt(timestampValue.substring(4, 6)); - hour = Integer.parseInt(timestampValue.substring(6, 8)); - minutes = Integer.parseInt(timestampValue.substring(8, - 10)); - + + month = Integer.parseInt(timestampValue.substring( + 2, 4)); + day = Integer.parseInt(timestampValue.substring(4, + 6)); + hour = Integer.parseInt(timestampValue.substring(6, + 8)); + minutes = Integer.parseInt(timestampValue + .substring(8, 10)); + year += 1900; // two-digit year } - + return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year, month, day, hour, - minutes, 0, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, year, + month, day, hour, minutes, 0, 0), + this.connection.getServerTimezoneTZ(), tz, + rollForward); } - + case 8: { if (timestampValue.indexOf(":") != -1) { - int hour = Integer.parseInt(timestampValue.substring(0, - 2)); + int hour = Integer.parseInt(timestampValue + .substring(0, 2)); int minutes = Integer.parseInt(timestampValue .substring(3, 5)); int seconds = Integer.parseInt(timestampValue .substring(6, 8)); - - return TimeUtil - .changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, 70, 0, 1, - hour, minutes, seconds, 0), - this.connection.getServerTimezoneTZ(), - tz, rollForward); - + + return TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, 70, 0, + 1, hour, minutes, seconds, 0), + this.connection.getServerTimezoneTZ(), tz, + rollForward); + } - - int year = Integer.parseInt(timestampValue.substring(0, 4)); - int month = Integer - .parseInt(timestampValue.substring(4, 6)); - int day = Integer.parseInt(timestampValue.substring(6, 8)); - - return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year - 1900, month - 1, - day, 0, 0, 0, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + + int year = Integer.parseInt(timestampValue.substring(0, + 4)); + int month = Integer.parseInt(timestampValue.substring( + 4, 6)); + int day = Integer.parseInt(timestampValue.substring(6, + 8)); + + return TimeUtil + .changeTimezone(this.connection, + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, + year - 1900, month - 1, day, 0, + 0, 0, 0), this.connection + .getServerTimezoneTZ(), tz, + rollForward); } - + case 6: { - int year = Integer.parseInt(timestampValue.substring(0, 2)); - + int year = Integer.parseInt(timestampValue.substring(0, + 2)); + if (year <= 69) { year = (year + 100); } - - int month = Integer - .parseInt(timestampValue.substring(2, 4)); - int day = Integer.parseInt(timestampValue.substring(4, 6)); - + + int month = Integer.parseInt(timestampValue.substring( + 2, 4)); + int day = Integer.parseInt(timestampValue.substring(4, + 6)); + return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year + 1900, month, day, - 0, 0, 0, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, + year + 1900, month, day, 0, 0, 0, 0), + this.connection.getServerTimezoneTZ(), tz, + rollForward); } - + case 4: { - int year = Integer.parseInt(timestampValue.substring(0, 2)); - + int year = Integer.parseInt(timestampValue.substring(0, + 2)); + if (year <= 69) { year = (year + 100); } - - int month = Integer - .parseInt(timestampValue.substring(2, 4)); - + + int month = Integer.parseInt(timestampValue.substring( + 2, 4)); + return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(sessionCalendar, year + 1900, month, 1, 0, - 0, 0, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + sessionCalendar, targetCalendar, + fastTimestampCreate(sessionCalendar, + year + 1900, month, 1, 0, 0, 0, 0), + this.connection.getServerTimezoneTZ(), tz, + rollForward); } - + case 2: { - int year = Integer.parseInt(timestampValue.substring(0, 2)); - + int year = Integer.parseInt(timestampValue.substring(0, + 2)); + if (year <= 69) { year = (year + 100); } - - return TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - fastTimestampCreate(null, year + 1900, 1, 1, 0, 0, - 0, 0), this.connection - .getServerTimezoneTZ(), tz, rollForward); + + return TimeUtil + .changeTimezone(this.connection, + sessionCalendar, targetCalendar, + fastTimestampCreate(null, year + 1900, + 1, 1, 0, 0, 0, 0), + this.connection.getServerTimezoneTZ(), + tz, rollForward); } - + default: throw new java.sql.SQLException( "Bad format for Timestamp '" + timestampValue - + "' in column " + columnIndex + ".", + + "' in column " + columnIndex + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } @@ -6294,7 +6372,7 @@ + timestampValue + "' from column " + columnIndex + " to TIMESTAMP.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } - + } /** @@ -6311,18 +6389,18 @@ * @exception java.sql.SQLException * if a database access error occurs */ - private Timestamp getTimestampInternal(int columnIndex, Calendar targetCalendar, - TimeZone tz, - boolean rollForward) throws java.sql.SQLException { + private Timestamp getTimestampInternal(int columnIndex, + Calendar targetCalendar, TimeZone tz, boolean rollForward) + throws java.sql.SQLException { if (this.isBinaryEncoded) { - return getNativeTimestamp(columnIndex, targetCalendar, tz, rollForward); + return getNativeTimestamp(columnIndex, targetCalendar, tz, + rollForward); } String timestampValue = getStringInternal(columnIndex, false); - return getTimestampFromString(columnIndex, targetCalendar, - timestampValue, tz, - rollForward); + return getTimestampFromString(columnIndex, targetCalendar, + timestampValue, tz, rollForward); } /** @@ -6581,17 +6659,17 @@ } message.append("Java class of column type is '"); - + if (value != null) { message.append(value.getClass().getName()); } else { - message.append(ResultSetMetaData.getClassNameForJavaType(fieldInfo.getSQLType(), - fieldInfo.isUnsigned(), - fieldInfo.getMysqlType(), - fieldInfo.isBinary() || fieldInfo.isBlob(), - fieldInfo.isOpaqueBinary())); + message.append(ResultSetMetaData.getClassNameForJavaType(fieldInfo + .getSQLType(), fieldInfo.isUnsigned(), fieldInfo + .getMysqlType(), + fieldInfo.isBinary() || fieldInfo.isBlob(), fieldInfo + .isOpaqueBinary())); } - + message.append("', MySQL field type is "); message.append(MysqlDefs.typeToName(fieldInfo.getMysqlType())); message @@ -6604,8 +6682,8 @@ this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" - : this.owningStatement.currentCatalog, - this.connectionId, (this.owningStatement == null) ? (-1) + : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System .currentTimeMillis(), 0, null, this.pointOfOrigin, message.toString())); @@ -6728,10 +6806,11 @@ boolean b; if (!reallyResult()) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"), - SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.ResultSet_is_from_UPDATE._No_Data_115"), + SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ } if (this.rowData.size() == 0) { @@ -6789,9 +6868,9 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - - valueAsString = valueAsString.trim(); - + + valueAsString = valueAsString.trim(); + intValue = Integer.parseInt(valueAsString); } @@ -6851,9 +6930,9 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - + valueAsString = valueAsString.trim(); - + longValue = Long.parseLong(valueAsString); } @@ -6915,9 +6994,9 @@ // than the iteration over the string, as String.trim() // will return a new string only if whitespace is present // - + valueAsString = valueAsString.trim(); - + shortValue = Short.parseShort(valueAsString); } @@ -7060,7 +7139,8 @@ .getString("ResultSet._n_nYou_should_consider_re-formulating_your_query_to_return_only_the_rows_you_are_interested_in_using._157")); //$NON-NLS-1$ this.eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, "", + ProfilerEvent.TYPE_WARN, + "", (this.owningStatement == null) ? Messages .getString("ResultSet.N/A_159") : this.owningStatement.currentCatalog, //$NON-NLS-1$ @@ -7130,11 +7210,11 @@ this.fullColumnNameToIndex = null; this.eventSink = null; this.warningChain = null; - + if (!this.retainOwningStatement) { this.owningStatement = null; } - + this.catalog = null; this.serverInfo = null; this.thisRow = null; @@ -7159,7 +7239,7 @@ protected void redefineFieldsForDBMD(Field[] f) { this.fields = f; - + for (int i = 0; i < this.fields.length; i++) { this.fields[i].setUseOldNameMetadata(true); } @@ -7313,10 +7393,11 @@ public void setFetchDirection(int direction) throws SQLException { if ((direction != FETCH_FORWARD) && (direction != FETCH_REVERSE) && (direction != FETCH_UNKNOWN)) { - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Illegal_value_for_fetch_direction_64"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Illegal_value_for_fetch_direction_64"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } this.fetchDirection = direction; @@ -7340,10 +7421,11 @@ */ public void setFetchSize(int rows) throws SQLException { if (rows < 0) { /* || rows > getMaxRows() */ - throw SQLError.createSQLException( - Messages - .getString("ResultSet.Value_must_be_between_0_and_getMaxRows()_66"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError + .createSQLException( + Messages + .getString("ResultSet.Value_must_be_between_0_and_getMaxRows()_66"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } this.fetchSize = rows; @@ -7451,9 +7533,12 @@ datatype = " (JDBC type '" + jdbcType + "')"; } - throw SQLError.createSQLException("'" + valueAsString + "' in column '" - + columnIndex + "' is outside valid range for the datatype " - + datatype + ".", SQLError.SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); + throw SQLError + .createSQLException("'" + valueAsString + "' in column '" + + columnIndex + + "' is outside valid range for the datatype " + + datatype + ".", + SQLError.SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); } /** @@ -8000,101 +8085,101 @@ updateLong(findColumn(columnName), x); } - /** - * JDBC 4.0 Update a column with a character stream value. The updateXXX() - * methods are used to update column values in the current row, or the - * insert row. The updateXXX() methods do not update the underlying - * database, instead the updateRow() or insertRow() methods are called to - * update the database. - * - * @param columnIndex - * the first column is 1, the second is 2, ... - * @param x - * the new column value - * @param length - * the length of the stream - * - * @exception SQLException - * if a database-access error occurs - * @throws NotUpdatable - * DOCUMENT ME! - */ + /** + * JDBC 4.0 Update a column with a character stream value. The updateXXX() + * methods are used to update column values in the current row, or the + * insert row. The updateXXX() methods do not update the underlying + * database, instead the updateRow() or insertRow() methods are called to + * update the database. + * + * @param columnIndex + * the first column is 1, the second is 2, ... + * @param x + * the new column value + * @param length + * the length of the stream + * + * @exception SQLException + * if a database-access error occurs + * @throws NotUpdatable + * DOCUMENT ME! + */ public void updateNCharacterStream(int columnIndex, Reader x, int length) throws SQLException { - throw new NotUpdatable(); + throw new NotUpdatable(); } - /** - * JDBC 4.0 Update a column with a character stream value. The updateXXX() - * methods are used to update column values in the current row, or the - * insert row. The updateXXX() methods do not update the underlying - * database, instead the updateRow() or insertRow() methods are called to - * update the database. - * - * @param columnName - * the name of the column - * @param reader - * the stream to update the column with - * @param length - * of the stream - * - * @throws SQLException - * if a database-access error occurs - */ + /** + * JDBC 4.0 Update a column with a character stream value. The updateXXX() + * methods are used to update column values in the current row, or the + * insert row. The updateXXX() methods do not update the underlying + * database, instead the updateRow() or insertRow() methods are called to + * update the database. + * + * @param columnName + * the name of the column + * @param reader + * the stream to update the column with + * @param length + * of the stream + * + * @throws SQLException + * if a database-access error occurs + */ public void updateNCharacterStream(String columnName, Reader reader, int length) throws SQLException { updateNCharacterStream(findColumn(columnName), reader, length); } - /** - * @see ResultSet#updateNClob(int, NClob) - */ + /** + * @see ResultSet#updateNClob(int, NClob) + */ public void updateNClob(int columnIndex, NClob nClob) throws SQLException { - throw new NotUpdatable(); + throw new NotUpdatable(); } - /** - * @see ResultSet#updateNClob(String, NClob) - */ + /** + * @see ResultSet#updateNClob(String, NClob) + */ public void updateNClob(String columnName, NClob nClob) throws SQLException { updateNClob(findColumn(columnName), nClob); } - - /** - * JDBC 4.0 Update a column with a String value. The updateXXX() methods are - * used to update column values in the current row, or the insert row. The - * updateXXX() methods do not update the underlying database, instead the - * updateRow() or insertRow() methods are called to update the database. - * - * @param columnIndex - * the first column is 1, the second is 2, ... - * @param nString - * the new column value - * - * @exception SQLException - * if a database-access error occurs - * @throws NotUpdatable - * DOCUMENT ME! - */ + + /** + * JDBC 4.0 Update a column with a String value. The updateXXX() methods are + * used to update column values in the current row, or the insert row. The + * updateXXX() methods do not update the underlying database, instead the + * updateRow() or insertRow() methods are called to update the database. + * + * @param columnIndex + * the first column is 1, the second is 2, ... + * @param nString + * the new column value + * + * @exception SQLException + * if a database-access error occurs + * @throws NotUpdatable + * DOCUMENT ME! + */ public void updateNString(int columnIndex, String nString) throws SQLException { - throw new NotUpdatable(); + throw new NotUpdatable(); } - /** - * JDBC 4.0 Update a column with a String value. The updateXXX() methods are - * used to update column values in the current row, or the insert row. The - * updateXXX() methods do not update the underlying database, instead the - * updateRow() or insertRow() methods are called to update the database. - * - * @param columnName - * the name of the column - * @param nString - * the new column value - * - * @exception SQLException - * if a database-access error occurs - */ + /** + * JDBC 4.0 Update a column with a String value. The updateXXX() methods are + * used to update column values in the current row, or the insert row. The + * updateXXX() methods do not update the underlying database, instead the + * updateRow() or insertRow() methods are called to update the database. + * + * @param columnName + * the name of the column + * @param nString + * the new column value + * + * @exception SQLException + * if a database-access error occurs + */ public void updateNString(String columnName, String nString) throws SQLException { updateNString(findColumn(columnName), nString); @@ -8363,7 +8448,6 @@ throw new NotUpdatable(); } - /** * JDBC 2.0 Update a column with a Time value. The updateXXX() methods are * used to update column values in the current row, or the insert row. The @@ -8382,7 +8466,7 @@ throws SQLException { updateTime(findColumn(columnName), x); } - + /** * JDBC 2.0 Update a column with a Timestamp value. The updateXXX() methods * are used to update column values in the current row, or the insert row. @@ -8437,4 +8521,174 @@ public boolean wasNull() throws SQLException { return this.wasNullFlag; } + + private Object getNativeDateTimeValue(int columnIndex, + Calendar targetCalendar, int jdbcType, int mysqlType, TimeZone tz, + boolean rollForward) throws SQLException { + + int year = 0; + int month = 0; + int day = 0; + + int hour = 0; + int minute = 0; + int seconds = 0; + + int nanos = 0; + + byte[] bits = (byte[]) this.thisRow[columnIndex - 1]; + + if (bits == null) { + this.wasNullFlag = true; + + return null; + } + + Calendar sessionCalendar = this.connection + .getUseJDBCCompliantTimezoneShift() ? this.connection + .getUtcCalendar() : getCalendarInstanceForSessionOrNew(); + + this.wasNullFlag = false; + + boolean populatedFromDateTimeValue = false; + + switch (mysqlType) { + case MysqlDefs.FIELD_TYPE_DATETIME: + case MysqlDefs.FIELD_TYPE_TIMESTAMP: + populatedFromDateTimeValue = true; + + int length = bits.length; + + if (length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + + if (length > 4) { + hour = bits[4]; + minute = bits[5]; + seconds = bits[6]; + } + + if (length > 7) { + nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8) + | ((bits[9] & 0xff) << 16) + | ((bits[10] & 0xff) << 24); + } + } + + break; + case MysqlDefs.FIELD_TYPE_DATE: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8); + month = bits[2]; + day = bits[3]; + } + + break; + case MysqlDefs.FIELD_TYPE_TIME: + populatedFromDateTimeValue = true; + + if (bits.length != 0) { + // bits[0] // skip tm->neg + // binaryData.readLong(); // skip daysPart + hour = bits[5]; + minute = bits[6]; + seconds = bits[7]; + } + + year = 1970; + month = 1; + day = 1; + + break; + default: + populatedFromDateTimeValue = false; + } + + switch (jdbcType) { + case Types.TIME: + if (populatedFromDateTimeValue) { + Time time = TimeUtil.fastTimeCreate( + getCalendarInstanceForSessionOrNew(), hour, minute, + seconds); + + Time adjustedTime = TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, time, this.connection + .getServerTimezoneTZ(), tz, rollForward); + + return adjustedTime; + } + + return getNativeTimeViaParseConversion(columnIndex, targetCalendar, + tz, rollForward); + + case Types.DATE: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Date", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + return fastDateCreate(getCalendarInstanceForSessionOrNew(), + year, month, day); + } + + return getNativeDateViaParseConversion(columnIndex); + case Types.TIMESTAMP: + if (populatedFromDateTimeValue) { + if ((year == 0) && (month == 0) && (day == 0)) { + if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + .equals(this.connection.getZeroDateTimeBehavior())) { + this.wasNullFlag = true; + + return null; + } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION + .equals(this.connection.getZeroDateTimeBehavior())) { + throw new SQLException( + "Value '0000-00-00' can not be represented as java.sql.Timestamp", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } + + year = 1; + month = 1; + day = 1; + } + + Timestamp ts = fastTimestampCreate( + getCalendarInstanceForSessionOrNew(), year, month, day, + hour, minute, seconds, nanos); + + Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection, + sessionCalendar, targetCalendar, ts, this.connection + .getServerTimezoneTZ(), tz, rollForward); + + return adjustedTs; + } + + return getNativeTimestampViaParseConversion(columnIndex, + targetCalendar, tz, rollForward); + + default: + throw new SQLException( + "Internal error - conversion method doesn't support this type", + SQLError.SQL_STATE_GENERAL_ERROR); + } + } + }