List:Commits« Previous MessageNext Message »
From:mmatthews Date:December 12 2005 7:42pm
Subject:Connector/J commit: r4681 - branches/branch_5_0/connector-j/src/com/mysql/jdbc
View as plain text  
Modified:
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java
Log:
Fix for BUG#15677 - ResultSet.getShort() returns incorrect values when
column is of type TINYINT UNSIGNED and using server-side prepared statements.  

(merged from 3.1 branch)

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	2005-12-12 18:17:59 UTC (rev 4680)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java	2005-12-12 19:42:09 UTC (rev 4681)
@@ -3017,7 +3017,22 @@
 
 		switch (field.getMysqlType()) {
 		case MysqlDefs.FIELD_TYPE_TINY:
-			return (byte) ((byte[]) this.thisRow[columnIndex])[0];
+			byte valueAsByte = ((byte[]) this.thisRow[columnIndex])[0];
+			
+			if (!field.isUnsigned() || valueAsByte >= 0) {
+				short valueAsShort = (short)(valueAsByte + (short)256);
+				
+				if (this.connection.getJdbcCompliantTruncation()) {
+					if (valueAsShort > Byte.MAX_VALUE) {
+						throwRangeException(String.valueOf(valueAsShort),
+								columnIndex + 1, Types.TINYINT);
+					}
+				}
+				
+				return (byte)valueAsShort;
+			}
+			
+			return valueAsByte;
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
 			int valueAsShort = getNativeShort(columnIndex + 1);
@@ -3972,27 +3987,78 @@
 
 		this.wasNullFlag = false;
 
-		// TODO: Truncation warning?
-		switch (this.fields[columnIndex].getMysqlType()) {
-		case MysqlDefs.FIELD_TYPE_DOUBLE:
-			return (short) getNativeDouble(columnIndex + 1);
+		Field f = this.fields[columnIndex];
+
+		switch (f.getMysqlType()) {
+
 		case MysqlDefs.FIELD_TYPE_TINY:
-			return getNativeByte(columnIndex + 1);
+			byte tinyintVal = getNativeByte(columnIndex + 1);
+			
+			if (!f.isUnsigned() || tinyintVal >= 0) {
+				return tinyintVal;
+			}
+
+			return (short)(tinyintVal + (short)256);
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
+			short asShort = getNativeShort(columnIndex + 1);
+			
+			if (!f.isUnsigned() || asShort >= 0) {
+				return asShort;
+			}
+			
+			if (this.connection.getJdbcCompliantTruncation()) {
+				int valueAsInt = asShort + 65536;
+				
+				throwRangeException(String.valueOf(valueAsInt),
+						columnIndex + 1, Types.SMALLINT);
+			}
+			
+			return asShort;
+		case MysqlDefs.FIELD_TYPE_INT24:
+		case MysqlDefs.FIELD_TYPE_LONG:
 			byte[] bits = (byte[]) this.thisRow[columnIndex];
 
-			short shortVal = (short) ((bits[0] & 0xff) | ((bits[1] & 0xff) << 8));
+			int valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
+					| ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
 
-			return shortVal;
-		case MysqlDefs.FIELD_TYPE_INT24:
-		case MysqlDefs.FIELD_TYPE_LONG:
-			return (short) getNativeInt(columnIndex + 1);
+			return (short)valueAsInt;
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			return (short) getNativeLong(columnIndex + 1);
+			long valueAsLong = getNativeLong(columnIndex + 1);
+
+			if (this.connection.getJdbcCompliantTruncation()) {
+				if (valueAsLong < Integer.MIN_VALUE
+						|| valueAsLong > Integer.MAX_VALUE) {
+					throwRangeException(String.valueOf(valueAsLong),
+							columnIndex + 1, Types.INTEGER);
+				}
+			}
+
+			return (short) valueAsLong;
+		case MysqlDefs.FIELD_TYPE_DOUBLE:
+			double valueAsDouble = getNativeDouble(columnIndex + 1);
+
+			if (this.connection.getJdbcCompliantTruncation()) {
+				if (valueAsDouble < Short.MIN_VALUE
+						|| valueAsDouble > Short.MAX_VALUE) {
+					throwRangeException(String.valueOf(valueAsDouble),
+							columnIndex + 1, Types.SMALLINT);
+				}
+			}
+
+			return (short) valueAsDouble;
 		case MysqlDefs.FIELD_TYPE_FLOAT:
-			return (short) getNativeFloat(columnIndex + 1);
+			float valueAsFloat = getNativeFloat(columnIndex + 1);
 
+			if (this.connection.getJdbcCompliantTruncation()) {
+				if (valueAsFloat < Short.MIN_VALUE
+						|| valueAsFloat > Short.MAX_VALUE) {
+					throwRangeException(String.valueOf(valueAsFloat),
+							columnIndex + 1, Types.SMALLINT);
+				}
+			}
+
+			return (short) valueAsFloat;
 		default:
 
 			if (this.useUsageAdvisor) {

Thread
Connector/J commit: r4681 - branches/branch_5_0/connector-j/src/com/mysql/jdbcmmatthews12 Dec