From 0ba9826b43b6fd8c2aec9822e9919bf89986175e Mon Sep 17 00:00:00 2001 From: alexradzin Date: Thu, 28 Sep 2023 18:18:10 +0300 Subject: [PATCH] FIR-26736 improved support of infinity Also added conversion from int floating point types --- .../java/integration/tests/StatementTest.java | 15 ++++++++ .../jdbc/resultset/FieldTypeConverter.java | 4 +- .../java/com/firebolt/jdbc/type/BaseType.java | 15 ++++++-- .../jdbc/resultset/FireboltResultSetTest.java | 37 +++++++++++++++++++ .../responses/firebolt-response-with-infinity | 3 ++ 5 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/responses/firebolt-response-with-infinity diff --git a/src/integrationTest/java/integration/tests/StatementTest.java b/src/integrationTest/java/integration/tests/StatementTest.java index 19eb1f058..455633be9 100644 --- a/src/integrationTest/java/integration/tests/StatementTest.java +++ b/src/integrationTest/java/integration/tests/StatementTest.java @@ -190,4 +190,19 @@ void empty(String sql) throws SQLException { } } + @Test + void specialIntValue() throws SQLException { + try (Connection connection = createConnection()) { + try (Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery("SELECT 1/0"); + resultSet.next(); + assertThrows(IllegalArgumentException.class, () -> resultSet.getShort(1)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getInt(1)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getLong(1)); + assertEquals(Float.POSITIVE_INFINITY, resultSet.getFloat(1)); + assertEquals(Double.POSITIVE_INFINITY, resultSet.getDouble(1)); + } + } + } + } diff --git a/src/main/java/com/firebolt/jdbc/resultset/FieldTypeConverter.java b/src/main/java/com/firebolt/jdbc/resultset/FieldTypeConverter.java index 37e6088ed..9e3067426 100644 --- a/src/main/java/com/firebolt/jdbc/resultset/FieldTypeConverter.java +++ b/src/main/java/com/firebolt/jdbc/resultset/FieldTypeConverter.java @@ -40,7 +40,7 @@ public class FieldTypeConverter { return BaseType.LONG.transform(value, column); }); CLASS_TO_CONVERT_FUNCTION.put(Double.class, (value, columnType, column) -> { - verify(Double.class, columnType, BaseType.DOUBLE, BaseType.REAL); + verify(Double.class, columnType, BaseType.DOUBLE, BaseType.REAL, BaseType.INTEGER, BaseType.SHORT, BaseType.LONG, BaseType.BIGINT); return BaseType.DOUBLE.transform(value, column); }); CLASS_TO_CONVERT_FUNCTION.put(Boolean.class, (value, columnType, column) -> { @@ -56,7 +56,7 @@ public class FieldTypeConverter { return BaseType.BIGINT.transform(value, column); }); CLASS_TO_CONVERT_FUNCTION.put(Float.class, (value, columnType, column) -> { - verify(Float.class, columnType, BaseType.REAL); + verify(Float.class, columnType, BaseType.REAL, BaseType.INTEGER, BaseType.SHORT, BaseType.LONG, BaseType.BIGINT); return BaseType.REAL.transform(value, column); }); CLASS_TO_CONVERT_FUNCTION.put(BigDecimal.class, (value, columnType, column) -> { diff --git a/src/main/java/com/firebolt/jdbc/type/BaseType.java b/src/main/java/com/firebolt/jdbc/type/BaseType.java index e7109ad00..742c4c910 100644 --- a/src/main/java/com/firebolt/jdbc/type/BaseType.java +++ b/src/main/java/com/firebolt/jdbc/type/BaseType.java @@ -24,10 +24,10 @@ /** This class contains the java types the Firebolt datatypes are mapped to */ @CustomLog public enum BaseType { - LONG(Long.class, conversion -> Long.parseLong(conversion.getValue())), - INTEGER(Integer.class, conversion -> Integer.parseInt(conversion.getValue())), - SHORT(Short.class, conversion -> Short.parseShort(conversion.getValue())), - BIGINT(BigInteger.class, conversion -> new BigInteger(conversion.getValue())), + LONG(Long.class, conversion -> Long.parseLong(checkInfinity(conversion.getValue()))), + INTEGER(Integer.class, conversion -> Integer.parseInt(checkInfinity(conversion.getValue()))), + SHORT(Short.class, conversion -> Short.parseShort(checkInfinity(conversion.getValue()))), + BIGINT(BigInteger.class, conversion -> new BigInteger(checkInfinity(conversion.getValue()))), TEXT(String.class, conversion -> StringEscapeUtils.unescapeJava(conversion.getValue())), REAL(Float.class, conversion -> { if (isNan(conversion.getValue())) { @@ -101,6 +101,13 @@ private static boolean isNegativeInf(String value) { return StringUtils.equals(value, "-inf"); } + private static String checkInfinity(String s) { + if (isPositiveInf(s) || isNegativeInf(s)) { + throw new IllegalArgumentException("Integer does not support infinity"); + } + return s; + } + public static boolean isNull(String value) { return StringUtils.equalsIgnoreCase(value, NULL_VALUE); } diff --git a/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java b/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java index 63622e6ef..a3b949b85 100644 --- a/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java +++ b/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java @@ -888,7 +888,40 @@ void shouldConvertInt64s() throws SQLException { resultSet.next(); assertEquals(new BigInteger("18446744073709551615"), resultSet.getObject(1, BigInteger.class)); assertEquals(new BigInteger("-9223372036854775807"), resultSet.getObject(2, BigInteger.class)); + } + + @Test + void shouldThrowIntegerInfinity() throws SQLException { + inputStream = getInputStreamWithInfinity(); + resultSet = new FireboltResultSet(inputStream); + resultSet.next(); + assertThrows(IllegalArgumentException.class, () -> resultSet.getShort(1)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getInt(1)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getLong(1)); + + assertThrows(IllegalArgumentException.class, () -> resultSet.getShort(2)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getInt(2)); + assertThrows(IllegalArgumentException.class, () -> resultSet.getLong(2)); + + assertThrows(IllegalArgumentException.class, () -> resultSet.getObject(1, BigInteger.class)); + } + @Test + void shouldConvertFloatInfinity() throws SQLException { + inputStream = getInputStreamWithInfinity(); + resultSet = new FireboltResultSet(inputStream); + resultSet.next(); + + assertEquals(Float.POSITIVE_INFINITY, resultSet.getFloat(1)); + assertEquals(Float.NEGATIVE_INFINITY, resultSet.getFloat(2)); + + assertEquals(Float.POSITIVE_INFINITY, resultSet.getDouble(1)); + assertEquals(Float.NEGATIVE_INFINITY, resultSet.getDouble(2)); + + assertEquals(Double.POSITIVE_INFINITY, resultSet.getObject(1, Double.class)); + assertEquals(Double.NEGATIVE_INFINITY, resultSet.getObject(2, Double.class)); + assertEquals(Float.POSITIVE_INFINITY, resultSet.getObject(1, Float.class)); + assertEquals(Float.NEGATIVE_INFINITY, resultSet.getObject(2, Float.class)); } @Test @@ -934,6 +967,10 @@ private InputStream getInputStreamWithBigInt64() { return FireboltResultSetTest.class.getResourceAsStream("/responses/firebolt-response-with-bigint-64"); } + private InputStream getInputStreamWithInfinity() { + return FireboltResultSetTest.class.getResourceAsStream("/responses/firebolt-response-with-infinity"); + } + private InputStream getInputStreamWithNewTypes() { return FireboltResultSetTest.class.getResourceAsStream("/responses/firebolt-response-with-new-types"); } diff --git a/src/test/resources/responses/firebolt-response-with-infinity b/src/test/resources/responses/firebolt-response-with-infinity new file mode 100644 index 000000000..e8d82cc85 --- /dev/null +++ b/src/test/resources/responses/firebolt-response-with-infinity @@ -0,0 +1,3 @@ +pos neg +int64 int64 +inf -inf