diff -Nur --exclude='*.txt' --exclude=CVS --exclude='*.class' postgres-v5/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java postgres-clean2/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java --- postgres-v5/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2006-11-26 13:37:51.000000000 +0200 +++ postgres-clean2/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2006-11-27 00:46:02.000000000 +0200 @@ -2267,7 +2267,15 @@ if (oid == Oid.FLOAT4) { return ByteConverter.float4(this_row[col], 0); } - return (float) readDoubleValue(this_row[col], oid, "float"); + double d = readDoubleValue(this_row[col], oid, "float"); + float f = (float) d; + if ((double) f != d) { + if (!Double.isNaN(d)) { + throw new PSQLException(GT.tr("Bad value for type {0} : {1}", new Object[]{"float", Double.toString(d)}), + PSQLState.NUMERIC_VALUE_OUT_OF_RANGE); + } + } + return f; } return toFloat( getFixedString(columnIndex) ); @@ -3016,7 +3024,13 @@ case Oid.INT4: return ByteConverter.int4(bytes, 0); case Oid.INT8: - return ByteConverter.int8(bytes, 0); + long l = ByteConverter.int8(bytes, 0); + double d = (double) l; + if (l != (long) d) { + throw new PSQLException(GT.tr("Bad value for type {0} : {1}", new Object[]{targetType, Long.valueOf(l)}), + PSQLState.NUMERIC_VALUE_OUT_OF_RANGE); + } + return d; case Oid.FLOAT4: return ByteConverter.float4(bytes, 0); case Oid.FLOAT8: @@ -3072,7 +3086,7 @@ PSQLState.DATA_TYPE_MISMATCH); } if (val < minVal || val > maxVal) { - throw new PSQLException(GT.tr("Bad value for type {0} : {1}", new Object[]{targetType, val}), + throw new PSQLException(GT.tr("Bad value for type {0} : {1}", new Object[]{targetType, Long.valueOf(val)}), PSQLState.NUMERIC_VALUE_OUT_OF_RANGE); } return val; diff -Nur --exclude='*.txt' --exclude=CVS --exclude='*.class' postgres-v5/org/postgresql/test/jdbc2/TestNumericOverflows.java postgres-clean2/org/postgresql/test/jdbc2/TestNumericOverflows.java --- postgres-v5/org/postgresql/test/jdbc2/TestNumericOverflows.java 1970-01-01 02:00:00.000000000 +0200 +++ postgres-clean2/org/postgresql/test/jdbc2/TestNumericOverflows.java 2006-11-27 00:54:02.000000000 +0200 @@ -0,0 +1,433 @@ +/*------------------------------------------------------------------------- +* +* Copyright (c) 2004-2005, PostgreSQL Global Development Group +* +* IDENTIFICATION +* $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/GetXXXTest.java,v 1.5 2005/01/11 08:25:48 jurka Exp $ +* +*------------------------------------------------------------------------- +*/ +package org.postgresql.test.jdbc2; + +import java.math.BigDecimal; +import java.sql.*; +import java.util.*; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.postgresql.test.TestUtil; + +public class TestNumericOverflows extends TestCase +{ + Connection con = null; + + private PreparedStatement pstmt; + + private int round; + + private boolean mustFail; + + private static String[][] OKVALUES = { + // values that fit into int2 + { + String.valueOf(0), + String.valueOf(Short.MAX_VALUE), + String.valueOf(Short.MIN_VALUE), + }, + // values that fit into int4 + all of int2 + { + String.valueOf(Short.MAX_VALUE), + String.valueOf(Short.MIN_VALUE), + String.valueOf(Integer.MAX_VALUE), + String.valueOf(Integer.MIN_VALUE), + }, + // values that fit into int8 + all of int4 and int2 + { + String.valueOf(Integer.MAX_VALUE), + String.valueOf(Integer.MIN_VALUE), + String.valueOf(Long.MAX_VALUE), + String.valueOf(Long.MIN_VALUE), + }, + // value that fit into float4 + all of int2 + { + String.valueOf(1 << 24), + String.valueOf(-(1 << 24)), + String.valueOf(Float.NaN), + String.valueOf(Float.NEGATIVE_INFINITY), + String.valueOf(Float.POSITIVE_INFINITY), + "3.4028234E38", // correct: 3.4028235E+38 + "-3.4028234E38", + "1.2E-38", // correct: 1.4E-45 + "-1.2E-38", +// BUG or not? backend seems to only accept normalised values +// see: http://en.wikipedia.org/wiki/IEEE_754#Single-precision_32_bit pt 7-9 +// String.valueOf(Float.MAX_VALUE), +// String.valueOf(-Float.MAX_VALUE), +// String.valueOf(Float.MIN_VALUE), +// String.valueOf(-Float.MIN_VALUE), + }, + // value that fit into float8 + all of int4 and int2 + { + String.valueOf(1L << 53), + String.valueOf(-(1L << 53)), + String.valueOf(Double.NaN), + String.valueOf(Double.NEGATIVE_INFINITY), + String.valueOf(Double.POSITIVE_INFINITY), + String.valueOf(Double.MAX_VALUE), + String.valueOf(-Double.MAX_VALUE), + "4.9e-308", + "-4.9e-308", +// String.valueOf(Double.MIN_VALUE), +// String.valueOf(-Double.MIN_VALUE), + }, + }; + + private static String[][] FAILVALUES = { + // values that just barely wont fit into int2 + { + String.valueOf(Short.MAX_VALUE + 1), + String.valueOf(Short.MIN_VALUE - 1), + }, + // values that just barely wont fit into int4 + { + String.valueOf(Integer.MAX_VALUE + 1L), + String.valueOf(Integer.MIN_VALUE - 1L), + }, + // values that just barely wont fit into int8 + { + "9223372036854775809", + "-9223372036854775810", + }, + // integer value that just barely wont fit into float4 + { + String.valueOf((1 << 24) + 1), + String.valueOf(-(1 << 24) - 1), + }, + // value that just barely wont fit into float4 + { + String.valueOf(3.4028236e+38), + String.valueOf(-3.4028236e+38), + String.valueOf(3.4028235e+39), + String.valueOf(-3.4028235e+39), + String.valueOf(0.9e-45f), + String.valueOf(1.4e-46), + }, + // integer value that just barely wont fit into float8 + { + String.valueOf((1L << 53) + 1L), + String.valueOf(-(1L << 53) - 1L), + }, + // value that just barely wont fit into float8 + { + "1.8976931348623157e+308", + "-1.8976931348623157e+308", + "1.7976931348623157e+309", + "-1.7976931348623157e+309", + "0.9e-324", + "-4.9e-324", + "0.9e-325", + "-4.9e-325", + }, + }; + + public TestNumericOverflows(String name ) + { + super(name); + } + protected void setUp() throws Exception + { + Properties p = new Properties(); + p.setProperty("prepareThreshold", "1"); + p.setProperty("binaryEncoding", "true"); + con = TestUtil.openDB(p); + mustFail = false; + } + + protected void tearDown() throws Exception + { + if (pstmt != null) { + pstmt.close(); + } + TestUtil.dropTable( con, "test_overflow" ); + con.close(); + } + + public void testShort() throws SQLException + { + String[] types = new String[]{"int2", "int4", "int8", "float4", "float8"}; + for (int i=0; i