List:Commits« Previous MessageNext Message »
From:mmatthews Date:April 3 2006 9:43pm
Subject:Connector/J commit: r5127 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_5_0/connector-j branch_5_0/connector-...
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()