List:Commits« Previous MessageNext Message »
From:mmatthews Date:December 21 2005 10:51pm
Subject:Connector/J commit: r4728 - 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:
Fixups for UNSIGNED values with server-side prepared statements.

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-21 01:02:50 UTC (rev 4727)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java	2005-12-21 22:51:50 UTC (rev 4728)
@@ -2987,6 +2987,10 @@
 	 *                if a database access error occurs
 	 */
 	protected byte getNativeByte(int columnIndex) throws SQLException {
+		return getNativeByte(columnIndex, true);
+	}
+	
+	protected byte getNativeByte(int columnIndex, boolean overflowCheck) throws SQLException {
 		checkRowPos();
 
 		checkColumnBounds(columnIndex);
@@ -3019,25 +3023,27 @@
 		case MysqlDefs.FIELD_TYPE_TINY:
 			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);
-					}
+			if (!field.isUnsigned()) {
+				return valueAsByte;
+			}
+
+			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 valueAsByte;
+			return (byte)valueAsShort;
+
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
-			int valueAsShort = getNativeShort(columnIndex + 1);
+			valueAsShort = getNativeShort(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsShort < Byte.MIN_VALUE
 						|| valueAsShort > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsShort),
@@ -3048,9 +3054,9 @@
 			return (byte) valueAsShort;
 		case MysqlDefs.FIELD_TYPE_INT24:
 		case MysqlDefs.FIELD_TYPE_LONG:
-			int valueAsInt = getNativeInt(columnIndex + 1);
+			int valueAsInt = getNativeInt(columnIndex + 1, false);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsInt < Byte.MIN_VALUE || valueAsInt > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsInt),
 							columnIndex + 1, Types.TINYINT);
@@ -3062,7 +3068,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			float valueAsFloat = getNativeFloat(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsFloat < Byte.MIN_VALUE
 						|| valueAsFloat > Byte.MAX_VALUE) {
 
@@ -3076,7 +3082,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Byte.MIN_VALUE
 						|| valueAsDouble > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3087,9 +3093,9 @@
 			return (byte) valueAsDouble;
 
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			long valueAsLong = getNativeLong(columnIndex + 1);
+			long valueAsLong = getNativeLong(columnIndex + 1, false, true);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsLong < Byte.MIN_VALUE
 						|| valueAsLong > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsLong),
@@ -3248,7 +3254,7 @@
 			return String.valueOf(booleanVal);
 
 		case Types.TINYINT:
-			byte tinyintVal = getNativeByte(columnIndex);
+			byte tinyintVal = getNativeByte(columnIndex, false);
 
 			if (this.wasNullFlag) {
 				return null;
@@ -3264,7 +3270,7 @@
 
 		case Types.SMALLINT:
 
-			int intVal = getNativeInt(columnIndex);
+			int intVal = getNativeInt(columnIndex, false);
 
 			if (this.wasNullFlag) {
 				return null;
@@ -3279,7 +3285,7 @@
 			return String.valueOf(intVal);
 
 		case Types.INTEGER:
-			intVal = getNativeInt(columnIndex);
+			intVal = getNativeInt(columnIndex, false);
 
 			if (this.wasNullFlag) {
 				return null;
@@ -3298,7 +3304,7 @@
 		case Types.BIGINT:
 
 			if (!field.isUnsigned()) {
-				longVal = getNativeLong(columnIndex);
+				longVal = getNativeLong(columnIndex, false, true);
 
 				if (this.wasNullFlag) {
 					return null;
@@ -3307,7 +3313,7 @@
 				return String.valueOf(longVal);
 			}
 
-			longVal = getNativeLong(columnIndex);
+			longVal = getNativeLong(columnIndex, false, false);
 
 			if (this.wasNullFlag) {
 				return null;
@@ -3603,7 +3609,9 @@
 
 		this.wasNullFlag = false;
 
-		switch (this.fields[columnIndex].getMysqlType()) {
+		Field f= this.fields[columnIndex];
+		
+		switch (f.getMysqlType()) {
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			byte[] bits = (byte[]) this.thisRow[columnIndex];
 
@@ -3618,15 +3626,37 @@
 
 			return Double.longBitsToDouble(valueAsLong);
 		case MysqlDefs.FIELD_TYPE_TINY:
-			return (double) getNativeByte(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (double) getNativeByte(columnIndex + 1);
+			}
+			
+			return (double) getNativeShort(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
-			return (double) getNativeShort(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (double) getNativeShort(columnIndex + 1);
+			}
+			
+			return (double) getNativeInt(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_INT24:
 		case MysqlDefs.FIELD_TYPE_LONG:
-			return (double) getNativeInt(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (double) getNativeInt(columnIndex + 1);
+			}
+			
+			return (double) getNativeLong(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			return (double) getNativeLong(columnIndex + 1);
+			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);
 
@@ -3674,20 +3704,52 @@
 
 		this.wasNullFlag = false;
 
-		// TODO: Truncation check
-		switch (this.fields[columnIndex].getMysqlType()) {
+		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), 
+						columnIndex + 1, Types.FLOAT);
+			}
+			
 			return (float) getNativeDouble(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_TINY:
-			return (float) getNativeByte(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (float) getNativeByte(columnIndex + 1);
+			}
+			
+			return (float) getNativeShort(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
-			return (float) getNativeShort(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (float) getNativeShort(columnIndex + 1);
+			}
+			
+			return (float) getNativeInt(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_INT24:
 		case MysqlDefs.FIELD_TYPE_LONG:
-			return (float) getNativeInt(columnIndex + 1);
+			if (!f.isUnsigned()) {
+				return (float) getNativeInt(columnIndex + 1);
+			}
+			
+			return (float) getNativeLong(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			return (float) getNativeLong(columnIndex + 1);
+			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];
 
@@ -3727,6 +3789,10 @@
 	 *                if a database access error occurs
 	 */
 	protected int getNativeInt(int columnIndex) throws SQLException {
+		return getNativeInt(columnIndex, false);
+	}
+	
+	protected int getNativeInt(int columnIndex, boolean overflowCheck) throws SQLException {
 		checkRowPos();
 		checkColumnBounds(columnIndex);
 
@@ -3745,7 +3811,7 @@
 		switch (f.getMysqlType()) {
 
 		case MysqlDefs.FIELD_TYPE_TINY:
-			byte tinyintVal = getNativeByte(columnIndex + 1);
+			byte tinyintVal = getNativeByte(columnIndex + 1, false);
 			
 			if (!f.isUnsigned() || tinyintVal >= 0) {
 				return tinyintVal;
@@ -3753,15 +3819,14 @@
 
 			return tinyintVal + 256;
 		case MysqlDefs.FIELD_TYPE_SHORT:
-			short asShort = getNativeShort(columnIndex + 1);
+		case MysqlDefs.FIELD_TYPE_YEAR:
+			short asShort = getNativeShort(columnIndex + 1, false);
 			
 			if (!f.isUnsigned() || asShort >= 0) {
 				return asShort;
 			}
 
 			return asShort + 65536;
-		case MysqlDefs.FIELD_TYPE_YEAR:
-			return getNativeShort(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_INT24:
 		case MysqlDefs.FIELD_TYPE_LONG:
 			byte[] bits = (byte[]) this.thisRow[columnIndex];
@@ -3769,11 +3834,24 @@
 			int valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
 					| ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
 
-			return valueAsInt;
+			if (!f.isUnsigned()) {	
+				return valueAsInt;
+			}
+			
+			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;
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			long valueAsLong = getNativeLong(columnIndex + 1);
+			valueAsLong = getNativeLong(columnIndex + 1, false, true);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsLong < Integer.MIN_VALUE
 						|| valueAsLong > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsLong),
@@ -3785,7 +3863,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Integer.MIN_VALUE
 						|| valueAsDouble > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3797,7 +3875,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			valueAsDouble = getNativeFloat(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Integer.MIN_VALUE
 						|| valueAsDouble > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3838,6 +3916,11 @@
 	 *                if a database access error occurs
 	 */
 	protected long getNativeLong(int columnIndex) throws SQLException {
+		return getNativeLong(columnIndex, false, true);
+	}
+	
+	protected long getNativeLong(int columnIndex, boolean overflowCheck, 
+			boolean expandUnsignedLong) throws SQLException {
 		checkRowPos();
 		checkColumnBounds(columnIndex);
 
@@ -3891,21 +3974,25 @@
 					| ((long) (bits[6] & 0xff) << 48)
 					| ((long) (bits[7] & 0xff) << 56);
 
-			//
-			// TODO: Actually do this check
-			//
-			// if (f.isUnsigned()) {
-			// if (this.connection.getJdbcCompliantTruncation()) {
-			// throwRangeException(String.valueOf(valueAsDouble), columnIndex +
-			// 1, Types.BIGINT);
-			// }
-			// }
+			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);
+			}
+			
+			return getLongFromString(asBigInt.toString(), columnIndex + 1);
 
-			return valueAsLong;
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Long.MIN_VALUE
 						|| valueAsDouble > Long.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3917,7 +4004,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			valueAsDouble = getNativeFloat(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Long.MIN_VALUE
 						|| valueAsDouble > Long.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3974,6 +4061,10 @@
 	 *                if a database access error occurs
 	 */
 	protected short getNativeShort(int columnIndex) throws SQLException {
+		return getNativeShort(columnIndex, true);
+	}
+	
+	protected short getNativeShort(int columnIndex, boolean overflowCheck) throws SQLException {
 		checkRowPos();
 		checkColumnBounds(columnIndex);
 
@@ -4001,15 +4092,17 @@
 			return (short)(tinyintVal + (short)256);
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
-			short asShort = getNativeShort(columnIndex + 1);
+			byte[] bits = (byte[]) this.thisRow[columnIndex];
 			
+			short asShort = (short) ((bits[0] & 0xff) | ((bits[1] & 0xff) << 8));
+
 			if (!f.isUnsigned()) {
 				return asShort;
 			}
 			
-			int valueAsInt = asShort + 65536;
+			int valueAsInt = asShort & 0xffff;
 			
-			if (this.connection.getJdbcCompliantTruncation() &&
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
 					valueAsInt > Short.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsInt),
 						columnIndex + 1, Types.SMALLINT);
@@ -4018,28 +4111,59 @@
 			return (short)valueAsInt;
 		case MysqlDefs.FIELD_TYPE_INT24:
 		case MysqlDefs.FIELD_TYPE_LONG:
-			byte[] bits = (byte[]) this.thisRow[columnIndex];
-
-			valueAsInt = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8)
-					| ((bits[2] & 0xff) << 16) | ((bits[3] & 0xff) << 24);
-
-			return (short)valueAsInt;
+			if (!f.isUnsigned()) {
+				valueAsInt = getNativeInt(columnIndex + 1, false);
+				
+				if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+						valueAsInt > Short.MAX_VALUE ||
+						valueAsInt < Short.MIN_VALUE) {
+					throwRangeException(String.valueOf(valueAsInt),
+							columnIndex + 1, Types.SMALLINT);
+				}
+				
+				return (short)valueAsInt;
+			}
+			
+			long valueAsLong = getNativeLong(columnIndex + 1, false, true);
+			
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+					valueAsLong > Short.MAX_VALUE) {
+				throwRangeException(String.valueOf(valueAsLong),
+						columnIndex + 1, Types.SMALLINT);
+			}
+			
+			return (short)valueAsLong;
+			
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
-			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);
+			valueAsLong = getNativeLong(columnIndex + 1, false, false);
+			
+			if (!f.isUnsigned()) {
+				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);
+			}
+			
+			return (short)getIntFromString(asBigInt.toString(), columnIndex + 1);
 
-			return (short) valueAsLong;
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsDouble < Short.MIN_VALUE
 						|| valueAsDouble > Short.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -4051,7 +4175,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			float valueAsFloat = getNativeFloat(columnIndex + 1);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
 				if (valueAsFloat < Short.MIN_VALUE
 						|| valueAsFloat > Short.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsFloat),

Thread
Connector/J commit: r4728 - branches/branch_5_0/connector-j/src/com/mysql/jdbcmmatthews21 Dec