MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:mmatthews Date:April 3 2006 7: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-...
View as plain text  
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 @@
  * </p>
  * 
  * @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
-     * 
-     * <p>
-     * Get the value of a column in the current row as a java.io.Reader.
-     * </p>
-     * 
-     * @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
+	 * 
+	 * <p>
+	 * Get the value of a column in the current row as a java.io.Reader.
+	 * </p>
+	 * 
+	 * @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
-     * 
-     * <p>
-     * Get the value of a column in the current row as a java.io.Reader.
-     * </p>
-     * 
-     * @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
+	 * 
+	 * <p>
+	 * Get the value of a column in the current row as a java.io.Reader.
+	 * </p>
+	 * 
+	 * @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);
+		}
+	}
+
 }

Thread
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-...mmatthews3 Apr