List:Commits« Previous MessageNext Message »
From:mmatthews Date:June 16 2006 9:50pm
Subject:Connector/J commit: r5403 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_3_1/connector-j/src/testsuite/regress...
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_3_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
   branches/branch_5_0/connector-j/CHANGES
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java
   branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
   branches/branch_5_1/connector-j/CHANGES
   branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java
   branches/branch_5_1/connector-j/src/testsuite/BaseTestCase.java
   branches/branch_5_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
Log:
- Fixed BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
	  returns incorrect values when using server-side prepared statements.
	  

Modified: branches/branch_3_1/connector-j/CHANGES
===================================================================
--- branches/branch_3_1/connector-j/CHANGES	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_3_1/connector-j/CHANGES	2006-06-16 21:50:01 UTC (rev 5403)
@@ -17,6 +17,9 @@
 	- Fixed BUG#16791 - NullPointerException in MysqlDataSourceFactory
 	  due to Reference containing RefAddrs with null content.
 	  
+	- Fixed BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	  returns incorrect values when using server-side prepared statements.
+	  
 05-26-06 - Version 3.1.13
 
     - Fixed BUG#15464 - INOUT parameter does not store IN value.

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-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_3_1/connector-j/src/com/mysql/jdbc/ResultSet.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -3527,7 +3527,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];
 
@@ -3542,15 +3544,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);
 		case MysqlDefs.FIELD_TYPE_BIT:
@@ -3599,24 +3623,63 @@
 
 		this.wasNullFlag = false;
 
-		// TODO: Truncation check
-		switch (this.fields[columnIndex].getMysqlType()) {
+		Field f = this.fields[columnIndex];
+		
+		switch (f.getMysqlType()) {
 		case MysqlDefs.FIELD_TYPE_BIT:
 			long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1);
 
 			return valueAsLong;
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
+			
+			// Only foolproof way to check for overflow
+			// Not efficient, but if you don't want to be inefficient, use the
+			// correct binding for the type!
+			
+			Double valueAsDouble = new Double(getNativeDouble(columnIndex + 1));
+			
+			float valueAsFloat = valueAsDouble.floatValue();
+			
+			if (this.connection.getJdbcCompliantTruncationForReads() && 
+					valueAsFloat == Float.NEGATIVE_INFINITY ||
+					valueAsFloat == Float.POSITIVE_INFINITY) {
+				throwRangeException(valueAsDouble.toString(), 
+						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);
+			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];
 
@@ -3643,7 +3706,7 @@
 			return getFloatFromString(stringVal, columnIndex + 1);
 		}
 	}
-
+	
 	/**
 	 * JDBC 2.0 Get a REF(<structured-type>) column.
 	 * 
@@ -7899,11 +7962,11 @@
 			
 			return (short)valueAsLong;
 		case MysqlDefs.FIELD_TYPE_TINY:
-			byte tinyintVal = getNativeByte(columnIndex + 1);
+			byte tinyintVal = getNativeByte(columnIndex + 1, false);
 			
-			if (!f.isUnsigned()) {
-				return tinyintVal;
-			}
+			if (!f.isUnsigned() || tinyintVal >= 0) {
+                 	return tinyintVal;
+			 }
 	
 			return (short)(tinyintVal + (short)256);
 		case MysqlDefs.FIELD_TYPE_SHORT:

Modified: branches/branch_3_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
===================================================================
--- branches/branch_3_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_3_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -2483,6 +2483,47 @@
 		}
 	}
 	
+	/** 
+	 * Tests fix for BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	 * returns incorrect values when using server-side prepared statements.
+	 * 
+	 * @throws Exception if the test fails.
+	 */
+	public void testBug20306() throws Exception {
+		createTable("testBug20306", "(field1 TINYINT UNSIGNED, field2 TINYINT UNSIGNED)");
+		this.stmt.executeUpdate("INSERT INTO testBug20306 VALUES (2, 133)");
+		try {
+			this.pstmt = this.conn.prepareStatement("SELECT field1, field2 FROM testBug20306");
+			this.rs = this.pstmt.executeQuery();
+			this.rs.next();
+			checkBug20306();
+			
+			this.rs = this.stmt.executeQuery("SELECT field1, field2 FROM testBug20306");
+			this.rs.next();
+			checkBug20306();
+			
+		} finally {
+			closeMemberJDBCResources();
+		}
+	}
+
+	private void checkBug20306() throws Exception {
+		assertEquals(2, this.rs.getByte(1));
+		assertEquals(2, this.rs.getInt(1));
+		assertEquals(2, this.rs.getShort(1));
+		assertEquals(2, this.rs.getLong(1));
+		assertEquals(2.0, this.rs.getFloat(1), 0);
+		assertEquals(2.0, this.rs.getDouble(1), 0);
+		assertEquals(2, this.rs.getBigDecimal(1).intValue());
+		
+		assertEquals(133, this.rs.getInt(2));
+		assertEquals(133, this.rs.getShort(2));
+		assertEquals(133, this.rs.getLong(2));
+		assertEquals(133.0, this.rs.getFloat(2), 0);
+		assertEquals(133.0, this.rs.getDouble(2), 0);
+		assertEquals(133, this.rs.getBigDecimal(2).intValue());
+	}
+	
 	/**
 	 * Tests fix for BUG#20479 - Updatable result set throws ClassCastException
 	 * when there is row data and moveToInsertRow() is called.

Modified: branches/branch_5_0/connector-j/CHANGES
===================================================================
--- branches/branch_5_0/connector-j/CHANGES	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_0/connector-j/CHANGES	2006-06-16 21:50:01 UTC (rev 5403)
@@ -160,6 +160,9 @@
 	- Fixed BUG#16791 - NullPointerException in MysqlDataSourceFactory
 	  due to Reference containing RefAddrs with null content.
 	  
+	- Fixed BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	  returns incorrect values when using server-side prepared statements.
+	  	  
 05-26-06 - Version 3.1.13
 
     - Fixed BUG#15464 - INOUT parameter does not store IN value.

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-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -1567,7 +1567,7 @@
 			if (decimalIndex != -1) {
 				double valueAsDouble = Double.parseDouble(stringVal);
 
-				if (this.connection.getJdbcCompliantTruncation()) {
+				if (this.connection.getJdbcCompliantTruncationForReads()) {
 					if (valueAsDouble < Byte.MIN_VALUE
 							|| valueAsDouble > Byte.MAX_VALUE) {
 						throwRangeException(stringVal, columnIndex,
@@ -1580,7 +1580,7 @@
 
 			long valueAsLong = Long.parseLong(stringVal);
 
-			if (this.connection.getJdbcCompliantTruncation()) {
+			if (this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsLong < Byte.MIN_VALUE
 						|| valueAsLong > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsLong),
@@ -2294,13 +2294,17 @@
 
 				float f = Float.parseFloat(val);
 
-				if (this.connection.getJdbcCompliantTruncation()) {
+				if (this.connection.getJdbcCompliantTruncationForReads()) {
 					if (f == Float.MIN_VALUE || f == Float.MAX_VALUE) {
-						double valAsDouble = Double.parseDouble(val);
 
-						if (valAsDouble < Float.MIN_VALUE
-								|| valAsDouble > Float.MAX_VALUE) {
-							throwRangeException(String.valueOf(valAsDouble),
+						Double valueAsDouble = new Double(val);
+						
+						float valueAsFloat = valueAsDouble.floatValue();
+						
+						if (this.connection.getJdbcCompliantTruncationForReads() && 
+								valueAsFloat == Float.NEGATIVE_INFINITY ||
+								valueAsFloat == Float.POSITIVE_INFINITY) {
+							throwRangeException(valueAsDouble.toString(), 
 									columnIndex, Types.FLOAT);
 						}
 					}
@@ -2312,17 +2316,20 @@
 			return 0; // for NULL
 		} catch (NumberFormatException nfe) {
 			try {
-				double valAsDouble = Double.parseDouble(val);
+				Double valueAsDouble = new Double(val);
+				float valueAsFloat = valueAsDouble.floatValue();
+				
+				if (this.connection.getJdbcCompliantTruncationForReads()) {
 
-				if (this.connection.getJdbcCompliantTruncation()) {
-					if (Math.abs(valAsDouble - Float.MIN_VALUE) > 1  
-							|| Math.abs(valAsDouble - Float.MAX_VALUE) > 1) {
-						throwRangeException(String.valueOf(valAsDouble),
+					if (this.connection.getJdbcCompliantTruncationForReads() && 
+							valueAsFloat == Float.NEGATIVE_INFINITY ||
+							valueAsFloat == Float.POSITIVE_INFINITY) {
+						throwRangeException(valueAsDouble.toString(), 
 								columnIndex, Types.FLOAT);
 					}
 				}
 
-				return (float) valAsDouble;
+				return valueAsFloat;
 			} catch (NumberFormatException newNfe) {
 				; // ignore, it's not a number
 			}
@@ -2516,7 +2523,7 @@
 					
 					int valueAsInt = Integer.parseInt(val);
 
-					if (this.connection.getJdbcCompliantTruncation()) {
+					if (this.connection.getJdbcCompliantTruncationForReads()) {
 						if (valueAsInt == Integer.MIN_VALUE
 								|| valueAsInt == Integer.MAX_VALUE) {
 							long valueAsLong = Long.parseLong(val);
@@ -2537,7 +2544,7 @@
 
 				double valueAsDouble = Double.parseDouble(val);
 
-				if (this.connection.getJdbcCompliantTruncation()) {
+				if (this.connection.getJdbcCompliantTruncationForReads()) {
 					if (valueAsDouble < Integer.MIN_VALUE
 							|| valueAsDouble > Integer.MAX_VALUE) {
 						throwRangeException(String.valueOf(valueAsDouble),
@@ -2553,7 +2560,7 @@
 			try {
 				double valueAsDouble = Double.parseDouble(val);
 
-				if (this.connection.getJdbcCompliantTruncation()) {
+				if (this.connection.getJdbcCompliantTruncationForReads()) {
 					if (valueAsDouble < Integer.MIN_VALUE
 							|| valueAsDouble > Integer.MAX_VALUE) {
 						throwRangeException(String.valueOf(valueAsDouble),
@@ -3095,7 +3102,7 @@
 			short valueAsShort = (valueAsByte >= 0) ? 
 					valueAsByte : (short)(valueAsByte + (short)256);
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsShort > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsShort),
 							columnIndex + 1, Types.TINYINT);
@@ -3108,7 +3115,7 @@
 		case MysqlDefs.FIELD_TYPE_YEAR:
 			valueAsShort = getNativeShort(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsShort < Byte.MIN_VALUE
 						|| valueAsShort > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsShort),
@@ -3121,7 +3128,7 @@
 		case MysqlDefs.FIELD_TYPE_LONG:
 			int valueAsInt = getNativeInt(columnIndex + 1, false);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsInt < Byte.MIN_VALUE || valueAsInt > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsInt),
 							columnIndex + 1, Types.TINYINT);
@@ -3133,7 +3140,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			float valueAsFloat = getNativeFloat(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsFloat < Byte.MIN_VALUE
 						|| valueAsFloat > Byte.MAX_VALUE) {
 
@@ -3147,7 +3154,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Byte.MIN_VALUE
 						|| valueAsDouble > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3160,7 +3167,7 @@
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
 			valueAsLong = getNativeLong(columnIndex + 1, false, true);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsLong < Byte.MIN_VALUE
 						|| valueAsLong > Byte.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsLong),
@@ -3791,15 +3798,22 @@
 
 			return valueAsLong;
 		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), 
+			// Only foolproof way to check for overflow
+			// Not efficient, but if you don't want to be inefficient, use the
+			// correct binding for the type!
+			
+			Double valueAsDouble = new Double(getNativeDouble(columnIndex + 1));
+			
+			float valueAsFloat = valueAsDouble.floatValue();
+			
+			if (this.connection.getJdbcCompliantTruncationForReads() && 
+					valueAsFloat == Float.NEGATIVE_INFINITY ||
+					valueAsFloat == Float.POSITIVE_INFINITY) {
+				throwRangeException(valueAsDouble.toString(), 
 						columnIndex + 1, Types.FLOAT);
 			}
-			
+
 			return (float) getNativeDouble(columnIndex + 1);
 		case MysqlDefs.FIELD_TYPE_TINY:
 			if (!f.isUnsigned()) {
@@ -3934,7 +3948,7 @@
 			valueAsLong = (valueAsInt >= 0) ? 
 					valueAsInt : valueAsInt + 4294967296L; 
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
 					valueAsLong > Integer.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsLong),
 						columnIndex + 1, Types.INTEGER);
@@ -3944,7 +3958,7 @@
 		case MysqlDefs.FIELD_TYPE_LONGLONG:
 			valueAsLong = getNativeLong(columnIndex + 1, false, true);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsLong < Integer.MIN_VALUE
 						|| valueAsLong > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsLong),
@@ -3956,7 +3970,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Integer.MIN_VALUE
 						|| valueAsDouble > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -3968,7 +3982,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			valueAsDouble = getNativeFloat(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Integer.MIN_VALUE
 						|| valueAsDouble > Integer.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -4075,7 +4089,7 @@
 			
 			BigInteger asBigInt = convertLongToUlong(valueAsLong);
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation() && 
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() && 
 					((asBigInt.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0 ) ||
 					 (asBigInt.compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0))) {
 				throwRangeException(asBigInt.toString(),
@@ -4087,7 +4101,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Long.MIN_VALUE
 						|| valueAsDouble > Long.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -4099,7 +4113,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			valueAsDouble = getNativeFloat(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Long.MIN_VALUE
 						|| valueAsDouble > Long.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -4178,12 +4192,12 @@
 		switch (f.getMysqlType()) {
 
 		case MysqlDefs.FIELD_TYPE_TINY:
-			byte tinyintVal = getNativeByte(columnIndex + 1);
+			byte tinyintVal = getNativeByte(columnIndex + 1, false);
 			
-			if (!f.isUnsigned()) {
-				return tinyintVal;
+			if (!f.isUnsigned() || tinyintVal >= 0) {
+             	return tinyintVal;
 			}
-
+			
 			return (short)(tinyintVal + (short)256);
 		case MysqlDefs.FIELD_TYPE_SHORT:
 		case MysqlDefs.FIELD_TYPE_YEAR:
@@ -4197,7 +4211,7 @@
 			
 			int valueAsInt = asShort & 0xffff;
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
 					valueAsInt > Short.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsInt),
 						columnIndex + 1, Types.SMALLINT);
@@ -4209,7 +4223,7 @@
 			if (!f.isUnsigned()) {
 				valueAsInt = getNativeInt(columnIndex + 1, false);
 				
-				if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+				if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
 						valueAsInt > Short.MAX_VALUE ||
 						valueAsInt < Short.MIN_VALUE) {
 					throwRangeException(String.valueOf(valueAsInt),
@@ -4221,7 +4235,7 @@
 			
 			long valueAsLong = getNativeLong(columnIndex + 1, false, true);
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation() &&
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() &&
 					valueAsLong > Short.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsLong),
 						columnIndex + 1, Types.SMALLINT);
@@ -4233,7 +4247,7 @@
 			valueAsLong = getNativeLong(columnIndex + 1, false, false);
 			
 			if (!f.isUnsigned()) {
-				if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+				if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 					if (valueAsLong < Short.MIN_VALUE
 							|| valueAsLong > Short.MAX_VALUE) {
 						throwRangeException(String.valueOf(valueAsLong),
@@ -4246,7 +4260,7 @@
 			
 			BigInteger asBigInt = convertLongToUlong(valueAsLong);
 			
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation() && 
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads() && 
 					((asBigInt.compareTo(new BigInteger(String.valueOf(Short.MAX_VALUE))) > 0 ) ||
 					 (asBigInt.compareTo(new BigInteger(String.valueOf(Short.MIN_VALUE))) < 0))) {
 				throwRangeException(asBigInt.toString(),
@@ -4258,7 +4272,7 @@
 		case MysqlDefs.FIELD_TYPE_DOUBLE:
 			double valueAsDouble = getNativeDouble(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsDouble < Short.MIN_VALUE
 						|| valueAsDouble > Short.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsDouble),
@@ -4270,7 +4284,7 @@
 		case MysqlDefs.FIELD_TYPE_FLOAT:
 			float valueAsFloat = getNativeFloat(columnIndex + 1);
 
-			if (overflowCheck && this.connection.getJdbcCompliantTruncation()) {
+			if (overflowCheck && this.connection.getJdbcCompliantTruncationForReads()) {
 				if (valueAsFloat < Short.MIN_VALUE
 						|| valueAsFloat > Short.MAX_VALUE) {
 					throwRangeException(String.valueOf(valueAsFloat),
@@ -6686,7 +6700,7 @@
 
 		double valueAsDouble = Double.parseDouble(val);
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (valueAsDouble < Integer.MIN_VALUE
 					|| valueAsDouble > Integer.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsDouble), columnIndex,
@@ -6722,7 +6736,7 @@
 			intValue = Integer.parseInt(valueAsString);
 		}
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (intValue == Integer.MIN_VALUE || intValue == Integer.MAX_VALUE) {
 				long valueAsLong = Long
 						.parseLong(valueAsString == null ? new String(
@@ -6748,7 +6762,7 @@
 
 		double valueAsDouble = Double.parseDouble(val);
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (valueAsDouble < Long.MIN_VALUE
 					|| valueAsDouble > Long.MAX_VALUE) {
 				throwRangeException(val, columnIndex, Types.BIGINT);
@@ -6784,7 +6798,7 @@
 			longValue = Long.parseLong(valueAsString);
 		}
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (longValue == Integer.MIN_VALUE
 					|| longValue == Integer.MAX_VALUE) {
 				double valueAsDouble = Double
@@ -6811,7 +6825,7 @@
 
 		double valueAsDouble = Double.parseDouble(val);
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (valueAsDouble < Short.MIN_VALUE
 					|| valueAsDouble > Short.MAX_VALUE) {
 				throwRangeException(String.valueOf(valueAsDouble), columnIndex,
@@ -6848,7 +6862,7 @@
 			shortValue = Short.parseShort(valueAsString);
 		}
 
-		if (this.connection.getJdbcCompliantTruncation()) {
+		if (this.connection.getJdbcCompliantTruncationForReads()) {
 			if (shortValue == Short.MIN_VALUE || shortValue == Short.MAX_VALUE) {
 				long valueAsLong = Long
 						.parseLong(valueAsString == null ? new String(

Modified: branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
===================================================================
--- branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -3374,4 +3374,45 @@
 			}		
 		}
 	}
+
+	/** 
+	 * Tests fix for BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	 * returns incorrect values when using server-side prepared statements.
+	 * 
+	 * @throws Exception if the test fails.
+	 */
+	public void testBug20306() throws Exception {
+		createTable("testBug20306", "(field1 TINYINT UNSIGNED, field2 TINYINT UNSIGNED)");
+		this.stmt.executeUpdate("INSERT INTO testBug20306 VALUES (2, 133)");
+		try {
+			this.pstmt = this.conn.prepareStatement("SELECT field1, field2 FROM testBug20306");
+			this.rs = this.pstmt.executeQuery();
+			this.rs.next();
+			checkBug20306();
+			
+			this.rs = this.stmt.executeQuery("SELECT field1, field2 FROM testBug20306");
+			this.rs.next();
+			checkBug20306();
+			
+		} finally {
+			closeMemberJDBCResources();
+		}
+	}
+
+	private void checkBug20306() throws Exception {
+		assertEquals(2, this.rs.getByte(1));
+		assertEquals(2, this.rs.getInt(1));
+		assertEquals(2, this.rs.getShort(1));
+		assertEquals(2, this.rs.getLong(1));
+		assertEquals(2.0, this.rs.getFloat(1), 0);
+		assertEquals(2.0, this.rs.getDouble(1), 0);
+		assertEquals(2, this.rs.getBigDecimal(1).intValue());
+
+		assertEquals(133, this.rs.getInt(2));
+		assertEquals(133, this.rs.getShort(2));
+		assertEquals(133, this.rs.getLong(2));
+		assertEquals(133.0, this.rs.getFloat(2), 0);
+		assertEquals(133.0, this.rs.getDouble(2), 0);
+		assertEquals(133, this.rs.getBigDecimal(2).intValue());
+	}
 }

Modified: branches/branch_5_1/connector-j/CHANGES
===================================================================
--- branches/branch_5_1/connector-j/CHANGES	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_1/connector-j/CHANGES	2006-06-16 21:50:01 UTC (rev 5403)
@@ -134,6 +134,9 @@
 	- Fixed BUG#16791 - NullPointerException in MysqlDataSourceFactory
 	  due to Reference containing RefAddrs with null content.
 	  
+	- Fixed BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	  returns incorrect values when using server-side prepared statements.
+	  
 05-26-06 - Version 3.1.13
 
     - Fixed BUG#15464 - INOUT parameter does not store IN value.

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-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSet.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -4187,10 +4187,10 @@
 		switch (f.getMysqlType()) {
 
 		case MysqlDefs.FIELD_TYPE_TINY:
-			byte tinyintVal = getNativeByte(columnIndex + 1);
+			byte tinyintVal = getNativeByte(columnIndex + 1, false);
 
-			if (!f.isUnsigned()) {
-				return tinyintVal;
+			if (!f.isUnsigned() || tinyintVal >= 0) {
+             	return tinyintVal;
 			}
 
 			return (short) (tinyintVal + (short) 256);

Modified: branches/branch_5_1/connector-j/src/testsuite/BaseTestCase.java
===================================================================
--- branches/branch_5_1/connector-j/src/testsuite/BaseTestCase.java	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_1/connector-j/src/testsuite/BaseTestCase.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -516,4 +516,28 @@
 			return false;
 		}	
 	}
+
+	protected void closeMemberJDBCResources() {
+		if (this.rs != null) {
+			ResultSet toClose = this.rs;
+			this.rs = null;
+			
+			try {
+				toClose.close();
+			} catch (SQLException sqlEx) {
+				// ignore
+			}
+		}
+		
+		if (this.pstmt != null) {
+			PreparedStatement toClose = this.pstmt;
+			this.pstmt = null;
+			
+			try {
+				toClose.close();
+			} catch (SQLException sqlEx) {
+				// ignore
+			}
+		}
+	}
 }

Modified: branches/branch_5_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java
===================================================================
--- branches/branch_5_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 20:58:36 UTC (rev 5402)
+++ branches/branch_5_1/connector-j/src/testsuite/regression/ResultSetRegressionTest.java	2006-06-16 21:50:01 UTC (rev 5403)
@@ -3072,5 +3072,45 @@
 			}		
 		}
 	}
+	
+	/** 
+	 * Tests fix for BUG#20306 - ResultSet.getShort() for UNSIGNED TINYINT
+	 * returns incorrect values when using server-side prepared statements.
+	 * 
+	 * @throws Exception if the test fails.
+	 */
+	public void testBug20306() throws Exception {
+		createTable("testBug20306", "(field1 TINYINT UNSIGNED, field2 TINYINT UNSIGNED)");
+		this.stmt.executeUpdate("INSERT INTO testBug20306 VALUES (2, 133)");
+		try {
+			this.pstmt = this.conn.prepareStatement("SELECT field1, field2 FROM testBug20306");
+			this.rs = this.pstmt.executeQuery();
+			this.rs.next();
+			checkBug20306();
+			
+			this.rs = this.stmt.executeQuery("SELECT field1, field2 FROM testBug20306");
+			this.rs.next();
+			checkBug20306();
+			
+		} finally {
+			closeMemberJDBCResources();
+		}
+	}
 
+	private void checkBug20306() throws Exception {
+		assertEquals(2, this.rs.getByte(1));
+		assertEquals(2, this.rs.getInt(1));
+		assertEquals(2, this.rs.getShort(1));
+		assertEquals(2, this.rs.getLong(1));
+		assertEquals(2.0, this.rs.getFloat(1), 0);
+		assertEquals(2.0, this.rs.getDouble(1), 0);
+		assertEquals(2, this.rs.getBigDecimal(1).intValue());
+		
+		assertEquals(133, this.rs.getInt(2));
+		assertEquals(133, this.rs.getShort(2));
+		assertEquals(133, this.rs.getLong(2));
+		assertEquals(133.0, this.rs.getFloat(2), 0);
+		assertEquals(133.0, this.rs.getDouble(2), 0);
+		assertEquals(133, this.rs.getBigDecimal(2).intValue());
+	}
 }

Thread
Connector/J commit: r5403 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_3_1/connector-j/src/testsuite/regress...mmatthews16 Jun