diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java index d4157bf097201..63b27f3a8ac99 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java @@ -18,7 +18,6 @@ import java.math.BigDecimal; import java.math.BigInteger; -import java.math.RoundingMode; import org.apache.calcite.DataContext; import org.apache.calcite.avatica.util.ByteString; import org.apache.calcite.config.CalciteConnectionConfig; @@ -38,6 +37,9 @@ import org.apache.ignite.internal.processors.query.calcite.util.Commons; import org.checkerframework.checker.nullness.qual.Nullable; +import static org.apache.ignite.internal.processors.query.calcite.util.IgniteMath.NUMERIC_ROUNDING_MODE; +import static org.apache.ignite.internal.processors.query.calcite.util.IgniteMath.convertToBigDecimal; + /** * Ignite SQL functions. */ @@ -48,9 +50,6 @@ public class IgniteSqlFunctions { /** */ private static final int DFLT_NUM_PRECISION = IgniteTypeSystem.INSTANCE.getDefaultPrecision(SqlTypeName.DECIMAL); - /** */ - private static final RoundingMode NUMERIC_ROUNDING_MODE = RoundingMode.HALF_UP; - /** * Default constructor. */ @@ -145,24 +144,6 @@ public static BigDecimal toBigDecimal(Number val, int precision, int scale) { return dec.setScale(scale, NUMERIC_ROUNDING_MODE); } - /** */ - private static BigDecimal convertToBigDecimal(Number value) { - BigDecimal dec; - - if (value instanceof Float) - dec = BigDecimal.valueOf(value.floatValue()); - else if (value instanceof Double) - dec = BigDecimal.valueOf(value.doubleValue()); - else if (value instanceof BigDecimal) - dec = (BigDecimal)value; - else if (value instanceof BigInteger) - dec = new BigDecimal((BigInteger)value); - else - dec = new BigDecimal(value.longValue()); - - return dec; - } - /** Cast object depending on type to DECIMAL. */ public static BigDecimal toBigDecimal(Object o, int precision, int scale) { if (o == null) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java index f5350d1c18c15..020b747a45a5e 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java @@ -18,6 +18,8 @@ package org.apache.ignite.internal.processors.query.calcite.util; import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; import org.apache.calcite.sql.type.SqlTypeName; import static org.apache.calcite.sql.type.SqlTypeName.BIGINT; @@ -45,6 +47,33 @@ public class IgniteMath { /** */ private static final Float LOWER_LONG_FLOAT = (float)Long.MIN_VALUE; + /** */ + private static final double LONG_MAX_EXT = Long.MAX_VALUE + 1.d; + + /** */ + private static final double LONG_MIN_EXT = Long.MIN_VALUE - 1d; + + /** */ + private static final double INT_MAX_EXT = Integer.MAX_VALUE + 1.d; + + /** */ + private static final double INT_MIN_EXT = Integer.MIN_VALUE - 1d; + + /** */ + private static final double SHORT_MAX_EXT = Short.MAX_VALUE + 1.d; + + /** */ + private static final double SHORT_MIN_EXT = Short.MIN_VALUE - 1d; + + /** */ + private static final double BYTE_MAX_EXT = Byte.MAX_VALUE + 1.d; + + /** */ + private static final double BYTE_MIN_EXT = Byte.MIN_VALUE - 1d; + + /** */ + public static final RoundingMode NUMERIC_ROUNDING_MODE = RoundingMode.HALF_UP; + /** Returns the sum of its arguments, throwing an exception if the result overflows an {@code long}. */ public static long addExact(long x, long y) { long r = x + y; @@ -236,28 +265,10 @@ public static byte divideExact(byte x, byte y) { return (byte)(x / y); } - /** */ - private static void checkNumberLongBounds(SqlTypeName type, Number x) { - if (x instanceof BigDecimal) { - if ((((BigDecimal)x).compareTo(UPPER_LONG_BIG_DECIMAL) < 0 && ((BigDecimal)x).compareTo(LOWER_LONG_BIG_DECIMAL) > 0)) - return; - } - else if (x instanceof Double) { - if ((((Double)x).compareTo(UPPER_LONG_DOUBLE) <= 0 && ((Double)x).compareTo(LOWER_LONG_DOUBLE) >= 0)) - return; - } - else if (x instanceof Float) { - if ((((Float)x).compareTo(UPPER_LONG_FLOAT) <= 0 && ((Float)x).compareTo(LOWER_LONG_FLOAT) >= 0)) - return; - } - else - return; - - throw new ArithmeticException(type.getName() + " overflow"); - } - /** Cast value to {@code long}, throwing an exception if the result overflows an {@code long}. */ public static long convertToLongExact(Number x) { + x = round(x); + checkNumberLongBounds(BIGINT, x); return x.longValue(); @@ -265,8 +276,10 @@ public static long convertToLongExact(Number x) { /** Cast value to {@code long}, throwing an exception if the result overflows an {@code long}. */ public static long convertToLongExact(double x) { - if (x > Long.MAX_VALUE || x < Long.MIN_VALUE) - throw new ArithmeticException(BIGINT.getName() + " overflow"); + x = extendToRound(x); + + if (x <= LONG_MIN_EXT || x >= LONG_MAX_EXT) + throw new ArithmeticException(INTEGER.getName() + " overflow"); return (long)x; } @@ -283,7 +296,9 @@ public static int convertToIntExact(long x) { /** Cast value to {@code int}, throwing an exception if the result overflows an {@code int}. */ public static int convertToIntExact(double x) { - if (x > Integer.MAX_VALUE || x < Integer.MIN_VALUE) + x = extendToRound(x); + + if (x <= INT_MIN_EXT || x >= INT_MAX_EXT) throw new ArithmeticException(INTEGER.getName() + " overflow"); return (int)x; @@ -291,6 +306,8 @@ public static int convertToIntExact(double x) { /** Cast value to {@code int}, throwing an exception if the result overflows an {@code int}. */ public static int convertToIntExact(Number x) { + x = round(x); + checkNumberLongBounds(INTEGER, x); return convertToIntExact(x.longValue()); @@ -308,7 +325,9 @@ public static short convertToShortExact(long x) { /** Cast value to {@code short}, throwing an exception if the result overflows an {@code short}. */ public static short convertToShortExact(double x) { - if (x > Short.MAX_VALUE || x < Short.MIN_VALUE) + x = extendToRound(x); + + if (x <= SHORT_MIN_EXT || x >= SHORT_MAX_EXT) throw new ArithmeticException(SMALLINT.getName() + " overflow"); return (short)x; @@ -316,6 +335,8 @@ public static short convertToShortExact(double x) { /** Cast value to {@code short}, throwing an exception if the result overflows an {@code short}. */ public static short convertToShortExact(Number x) { + x = round(x); + checkNumberLongBounds(SMALLINT, x); return convertToShortExact(x.longValue()); @@ -333,7 +354,9 @@ public static byte convertToByteExact(long x) { /** Cast value to {@code byte}, throwing an exception if the result overflows an {@code byte}. */ public static byte convertToByteExact(double x) { - if (x > Byte.MAX_VALUE || x < Byte.MIN_VALUE) + x = extendToRound(x); + + if (x <= BYTE_MIN_EXT || x >= BYTE_MAX_EXT) throw new ArithmeticException(TINYINT.getName() + " overflow"); return (byte)x; @@ -341,8 +364,58 @@ public static byte convertToByteExact(double x) { /** Cast value to {@code byte}, throwing an exception if the result overflows an {@code byte}. */ public static byte convertToByteExact(Number x) { + x = round(x); + checkNumberLongBounds(TINYINT, x); return convertToByteExact(x.longValue()); } + + /** */ + public static BigDecimal convertToBigDecimal(Number val) { + BigDecimal dec; + + if (val instanceof Float) + dec = BigDecimal.valueOf(val.floatValue()); + else if (val instanceof Double) + dec = BigDecimal.valueOf(val.doubleValue()); + else if (val instanceof BigDecimal) + dec = (BigDecimal)val; + else if (val instanceof BigInteger) + dec = new BigDecimal((BigInteger)val); + else + dec = BigDecimal.valueOf(val.longValue()); + + return dec; + } + + /** */ + private static void checkNumberLongBounds(SqlTypeName type, Number x) { + if (x instanceof BigDecimal) { + if ((((BigDecimal)x).compareTo(UPPER_LONG_BIG_DECIMAL) < 0 && ((BigDecimal)x).compareTo(LOWER_LONG_BIG_DECIMAL) > 0)) + return; + } + else if (x instanceof Double) { + if ((((Double)x).compareTo(UPPER_LONG_DOUBLE) <= 0 && ((Double)x).compareTo(LOWER_LONG_DOUBLE) >= 0)) + return; + } + else if (x instanceof Float) { + if ((((Float)x).compareTo(UPPER_LONG_FLOAT) <= 0 && ((Float)x).compareTo(LOWER_LONG_FLOAT) >= 0)) + return; + } + else + return; + + throw new ArithmeticException(type.getName() + " overflow"); + } + + /** */ + private static double extendToRound(double x) { + return x < 0.0d ? x - 0.5d : x + 0.5d; + } + + /** */ + private static BigDecimal round(Number x) { + return convertToBigDecimal(x).setScale(0, NUMERIC_ROUNDING_MODE); + } } diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/DataTypesTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/DataTypesTest.java index a577fa9f96e6e..1c8e95e852d35 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/DataTypesTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/DataTypesTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.query.calcite.integration; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -43,6 +44,99 @@ * Test SQL data types. */ public class DataTypesTest extends AbstractBasicIntegrationTransactionalTest { + /** */ + @Test + public void testRoundingOfNumerics() { + doTestCoercionOfNumerics(numericsToRound(), false, false); + } + + /** */ + @Test + public void testRoundingOfNumericsPrecasted() { + doTestCoercionOfNumerics(numericsToRound(), false, true); + } + + /** */ + @Test + public void testRoundingOfDynamicNumerics() { + doTestCoercionOfNumerics(numericsToRound(), true, false); + } + + /** */ + @Test + public void testRoundingOfDynamicNumericsPrecasted() { + doTestCoercionOfNumerics(numericsToRound(), true, true); + } + + /** @return input type, input value, target type, expected result. */ + private static List> numericsToRound() { + List> lst = new ArrayList<>(50); + + Exception overflowErr = new ArithmeticException("overflow"); + + lst.add(F.asList("DECIMAL(5,4)", BigDecimal.valueOf(1.4999d), "DECIMAL(1)", new BigDecimal(1))); + lst.add(F.asList("DECIMAL(5,4)", BigDecimal.valueOf(-1.4999d), "DECIMAL(1)", new BigDecimal(-1))); + lst.add(F.asList("DECIMAL(2,1)", BigDecimal.valueOf(1.5d), "DECIMAL(1)", new BigDecimal(2))); + lst.add(F.asList("DECIMAL(2,1)", BigDecimal.valueOf(-1.5d), "DECIMAL(1)", new BigDecimal(-2))); + lst.add(F.asList("DECIMAL(5,4)", BigDecimal.valueOf(1.4999d), "DECIMAL(2,1)", BigDecimal.valueOf(1.5))); + lst.add(F.asList("DECIMAL(5,4)", BigDecimal.valueOf(-1.4999d), "DECIMAL(2,1)", BigDecimal.valueOf(-1.5))); + + lst.add(F.asList("DECIMAL", new BigDecimal("-9223372036854775808.4"), "BIGINT", -9223372036854775808L)); + lst.add(F.asList("DECIMAL", new BigDecimal("-9223372036854775808.5"), "BIGINT", overflowErr)); + lst.add(F.asList("DECIMAL", new BigDecimal("9223372036854775807.4"), "BIGINT", 9223372036854775807L)); + lst.add(F.asList("DECIMAL", new BigDecimal("9223372036854775807.5"), "BIGINT", overflowErr)); + + lst.add(F.asList("DOUBLE", -2147483648.4d, "INT", -2147483648)); + lst.add(F.asList("DOUBLE", -2147483648.5d, "INT", overflowErr)); + lst.add(F.asList("DOUBLE", 2147483647.4d, "INT", 2147483647)); + lst.add(F.asList("DOUBLE", 2147483647.5d, "INT", overflowErr)); + + for (String numTypeName : F.asList("DOUBLE", "FLOAT")) { + lst.add(F.asList(numTypeName, floatingVal(1.4999f, numTypeName), "DECIMAL(1)", new BigDecimal(1))); + lst.add(F.asList(numTypeName, floatingVal(-1.4999f, numTypeName), "DECIMAL(1)", new BigDecimal(-1))); + lst.add(F.asList(numTypeName, floatingVal(1.5f, numTypeName), "DECIMAL(1)", new BigDecimal(2))); + lst.add(F.asList(numTypeName, floatingVal(-1.5f, numTypeName), "DECIMAL(1)", new BigDecimal(-2))); + + lst.add(F.asList(numTypeName, floatingVal(1.4999f, numTypeName), "BIGINT", 1L)); + lst.add(F.asList(numTypeName, floatingVal(-1.4999f, numTypeName), "BIGINT", -1L)); + lst.add(F.asList(numTypeName, floatingVal(1.5f, numTypeName), "BIGINT", 2L)); + lst.add(F.asList(numTypeName, floatingVal(-1.5f, numTypeName), "BIGINT", -2L)); + + lst.add(F.asList(numTypeName, floatingVal(1.4999f, numTypeName), "INT", 1)); + lst.add(F.asList(numTypeName, floatingVal(-1.4999f, numTypeName), "INT", -1)); + lst.add(F.asList(numTypeName, floatingVal(1.5f, numTypeName), "INT", 2)); + lst.add(F.asList(numTypeName, floatingVal(-1.5f, numTypeName), "INT", -2)); + + lst.add(F.asList(numTypeName, floatingVal(1.4999f, numTypeName), "SMALLINT", (short)1)); + lst.add(F.asList(numTypeName, floatingVal(-1.4999f, numTypeName), "SMALLINT", (short)-1)); + lst.add(F.asList(numTypeName, floatingVal(1.5f, numTypeName), "SMALLINT", (short)2)); + lst.add(F.asList(numTypeName, floatingVal(-1.5f, numTypeName), "SMALLINT", (short)-2)); + lst.add(F.asList(numTypeName, floatingVal(32767.4f, numTypeName), "SMALLINT", (short)32767)); + lst.add(F.asList(numTypeName, floatingVal(32767.5f, numTypeName), "SMALLINT", overflowErr)); + lst.add(F.asList(numTypeName, floatingVal(-32768.4f, numTypeName), "SMALLINT", (short)-32768)); + lst.add(F.asList(numTypeName, floatingVal(-32768.5f, numTypeName), "SMALLINT", overflowErr)); + + lst.add(F.asList(numTypeName, floatingVal(1.4999f, numTypeName), "TINYINT", (byte)1)); + lst.add(F.asList(numTypeName, floatingVal(-1.4999f, numTypeName), "TINYINT", (byte)-1)); + lst.add(F.asList(numTypeName, floatingVal(1.5f, numTypeName), "TINYINT", (byte)2)); + lst.add(F.asList(numTypeName, floatingVal(-1.5f, numTypeName), "TINYINT", (byte)-2)); + lst.add(F.asList(numTypeName, floatingVal(127.4f, numTypeName), "TINYINT", (byte)127)); + lst.add(F.asList(numTypeName, floatingVal(127.5f, numTypeName), "TINYINT", overflowErr)); + lst.add(F.asList(numTypeName, floatingVal(-128.4f, numTypeName), "TINYINT", (byte)-128)); + lst.add(F.asList(numTypeName, floatingVal(-128.5f, numTypeName), "TINYINT", overflowErr)); + } + + return lst; + } + + /** */ + private static Number floatingVal(float v, String typeName) { + if ("DOUBLE".equalsIgnoreCase(typeName)) + return (double)v; + + return v; + } + /** Tests Other type. */ @Test public void testOtherType() { @@ -619,38 +713,32 @@ private static List> varcharsToCoerce() { /** */ @Test public void testCoercionOfNumericLiterals() { - assumeNoTransactions(); - - doTestCoercionOfNumerics(false, false); + doTestCoercionOfNumerics(numericsToCast(), false, false); } /** */ @Test public void testCoercionOfNumericLiteralsPrecasted() { - assumeNoTransactions(); - - doTestCoercionOfNumerics(false, true); + doTestCoercionOfNumerics(numericsToCast(), false, true); } /** */ @Test public void testCoercionOfNumericDynamicParameters() { - assumeNoTransactions(); - - doTestCoercionOfNumerics(true, false); + doTestCoercionOfNumerics(numericsToCast(), true, false); } /** */ @Test public void testCoercionOfNumericDynamicParametersPrecasted() { - assumeNoTransactions(); - - doTestCoercionOfNumerics(true, true); + doTestCoercionOfNumerics(numericsToCast(), true, true); } /** */ - private void doTestCoercionOfNumerics(boolean dynamic, boolean precasted) { - for (List params : numericsToCast()) { + private void doTestCoercionOfNumerics(List> testSuite, boolean dynamic, boolean precasted) { + assumeNoTransactions(); + + for (List params : testSuite) { assert params.size() == 4 : "Wrong params lenght: " + params.size(); String inputType = params.get(0).toString(); @@ -686,7 +774,7 @@ private void doTestCoercionOfNumerics(boolean dynamic, boolean precasted) { /** */ private static String asLiteral(Object val, String type) { - return type.equalsIgnoreCase("VARCHAR") ? String.format("'%s'", val) : String.valueOf(val); + return "VARCHAR".equalsIgnoreCase(type) ? String.format("'%s'", val) : String.valueOf(val); } /** @return input type, input value, target type, expected result. */ @@ -863,80 +951,119 @@ public void testCastDecimalOverflows() { // BIGINT assertQuery("SELECT CAST(9223372036854775807.1 AS BIGINT)").returns(9223372036854775807L).check(); - assertQuery("SELECT CAST(9223372036854775807.9 AS BIGINT)").returns(9223372036854775807L).check(); - assertQuery("SELECT CAST(9223372036854775808.9 - 1 AS BIGINT)").returns(9223372036854775807L).check(); + assertQuery("SELECT CAST(9223372036854775807.4 AS BIGINT)").returns(9223372036854775807L).check(); + assertQuery("SELECT CAST(9223372036854775806.9 AS BIGINT)").returns(9223372036854775807L).check(); + assertThrows("SELECT CAST(9223372036854775807.5 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); + assertThrows("SELECT CAST(9223372036854775807.9 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); + assertQuery("SELECT CAST(9223372036854775807.9 - 1 AS BIGINT)").returns(9223372036854775807L).check(); assertThrows("SELECT CAST(9223372036854775808 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST(9223372036854775808.1 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST(-9223372036854775809 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST(-9223372036854775809.1 AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertQuery("SELECT CAST(-9223372036854775808.1 AS BIGINT)").returns(-9223372036854775808L).check(); - assertQuery("SELECT CAST(-9223372036854775808.9 AS BIGINT)").returns(-9223372036854775808L).check(); - assertQuery("SELECT CAST(-9223372036854775809.9 + 1 AS BIGINT)").returns(-9223372036854775808L).check(); + assertQuery("SELECT CAST(-9223372036854775807.9 AS BIGINT)").returns(-9223372036854775808L).check(); + assertQuery("SELECT CAST(-9223372036854775808.4 AS BIGINT)").returns(-9223372036854775808L).check(); + assertQuery("SELECT CAST(-9223372036854775808.9 + 1 AS BIGINT)").returns(-9223372036854775808L).check(); assertQuery("SELECT CAST('9223372036854775807.1' AS BIGINT)").returns(9223372036854775807L).check(); - assertQuery("SELECT CAST('9223372036854775807.9' AS BIGINT)").returns(9223372036854775807L).check(); + assertQuery("SELECT CAST('9223372036854775807.4' AS BIGINT)").returns(9223372036854775807L).check(); + assertThrows("SELECT CAST('9223372036854775807.5' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); + assertThrows("SELECT CAST('9223372036854775807.9' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST('9223372036854775808' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST('9223372036854775808.1' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST('-9223372036854775809' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertThrows("SELECT CAST('-9223372036854775809.1' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); assertQuery("SELECT CAST('-9223372036854775808.1' AS BIGINT)").returns(-9223372036854775808L).check(); - assertQuery("SELECT CAST('-9223372036854775808.9' AS BIGINT)").returns(-9223372036854775808L).check(); + assertThrows("SELECT CAST('-9223372036854775808.9' AS BIGINT)", IgniteSQLException.class, "BIGINT overflow"); // INTEGER - assertQuery("SELECT CAST(2147483647.1 AS INTEGER)").returns(2147483647).check(); - assertQuery("SELECT CAST(2147483647.9 AS INTEGER)").returns(2147483647).check(); - assertQuery("SELECT CAST(2147483648.9 - 1 AS INTEGER)").returns(2147483647).check(); + assertQuery("SELECT CAST(2147483647.4 AS INTEGER)").returns(2147483647).check(); + assertThrows("SELECT CAST(2147483647.5 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST(2147483647.9 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST(2147483648.5 - 1 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST(2147483648.9 - 1 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertQuery("SELECT CAST(2147483648.4 - 1 AS INTEGER)").returns(2147483647).check(); + assertQuery("SELECT CAST(2147483647.9 - 1 AS INTEGER)").returns(2147483647).check(); assertThrows("SELECT CAST(2147483648 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST(2147483648.1 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST(-2147483649 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST(-2147483649.1 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertQuery("SELECT CAST(-2147483648.1 AS INTEGER)").returns(-2147483648).check(); - assertQuery("SELECT CAST(-2147483648.9 AS INTEGER)").returns(-2147483648).check(); + assertQuery("SELECT CAST(-2147483648.4 AS INTEGER)").returns(-2147483648).check(); + assertThrows("SELECT CAST(-2147483648.5 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST(-2147483648.9 AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertQuery("SELECT CAST('2147483647.1' AS INTEGER)").returns(2147483647).check(); - assertQuery("SELECT CAST('2147483647.9' AS INTEGER)").returns(2147483647).check(); + assertQuery("SELECT CAST('2147483647.4' AS INTEGER)").returns(2147483647).check(); + assertThrows("SELECT CAST('2147483647.5' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST('2147483647.9' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST('2147483648' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST('2147483648.1' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST('2147483648.4' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST('2147483648.5' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertThrows("SELECT CAST('-2147483649' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); - assertThrows("SELECT CAST('-2147483649.1' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST('-2147483649.4' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); assertQuery("SELECT CAST('-2147483648.1' AS INTEGER)").returns(-2147483648).check(); - assertQuery("SELECT CAST('-2147483648.9' AS INTEGER)").returns(-2147483648).check(); + assertQuery("SELECT CAST('-2147483648.4' AS INTEGER)").returns(-2147483648).check(); + assertThrows("SELECT CAST('-2147483648.5' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); + assertThrows("SELECT CAST('-2147483648.9' AS INTEGER)", IgniteSQLException.class, "INTEGER overflow"); // SMALLINT assertQuery("SELECT CAST(32767.1 AS SMALLINT)").returns((short)32767).check(); - assertQuery("SELECT CAST(32767.9 AS SMALLINT)").returns((short)32767).check(); - assertQuery("SELECT CAST(32768.9 - 1 AS SMALLINT)").returns((short)32767).check(); + assertQuery("SELECT CAST(32767.4 AS SMALLINT)").returns((short)32767).check(); + assertThrows("SELECT CAST(32767.5 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); + assertThrows("SELECT CAST(32767.9 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); + assertQuery("SELECT CAST(32767.9 - 1 AS SMALLINT)").returns((short)32767).check(); + assertQuery("SELECT CAST(32768.4 - 1 AS SMALLINT)").returns((short)32767).check(); + assertThrows("SELECT CAST(32768.5 - 1 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); + assertThrows("SELECT CAST(32768.9 - 1 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST(32768 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST(32768.1 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST(-32769 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST(-32769.1 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertQuery("SELECT CAST(-32768.1 AS SMALLINT)").returns((short)-32768).check(); - assertQuery("SELECT CAST(-32768.9 AS SMALLINT)").returns((short)-32768).check(); + assertQuery("SELECT CAST(-32768.4 AS SMALLINT)").returns((short)-32768).check(); + assertThrows("SELECT CAST(-32768.5 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); + assertThrows("SELECT CAST(-32768.9 AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertQuery("SELECT CAST('32767.1' AS SMALLINT)").returns((short)32767).check(); - assertQuery("SELECT CAST('32767.9' AS SMALLINT)").returns((short)32767).check(); + assertQuery("SELECT CAST('32767.4' AS SMALLINT)").returns((short)32767).check(); + assertThrows("SELECT CAST('32767.9' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST('32768' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST('32768.1' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST('-32769' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertThrows("SELECT CAST('-32769.1' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); assertQuery("SELECT CAST('-32768.1' AS SMALLINT)").returns((short)-32768).check(); - assertQuery("SELECT CAST('-32768.9' AS SMALLINT)").returns((short)-32768).check(); + assertQuery("SELECT CAST('-32768.4' AS SMALLINT)").returns((short)-32768).check(); + assertThrows("SELECT CAST('-32768.5' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); + assertThrows("SELECT CAST('-32768.9' AS SMALLINT)", IgniteSQLException.class, "SMALLINT overflow"); // TINYINT assertQuery("SELECT CAST(127.1 AS TINYINT)").returns((byte)127).check(); - assertQuery("SELECT CAST(127.9 AS TINYINT)").returns((byte)127).check(); - assertQuery("SELECT CAST(128.9 - 1 AS TINYINT)").returns((byte)127).check(); + assertQuery("SELECT CAST(127.4 AS TINYINT)").returns((byte)127).check(); + assertThrows("SELECT CAST(127.5 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertThrows("SELECT CAST(127.9 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertQuery("SELECT CAST(127.9 - 1 AS TINYINT)").returns((byte)127).check(); + assertQuery("SELECT CAST(128.4 - 1 AS TINYINT)").returns((byte)127).check(); + assertThrows("SELECT CAST(128.9 - 1 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertThrows("SELECT CAST(128.5 - 1 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST(128 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST(128.1 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST(-129 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST(-129.1 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertQuery("SELECT CAST(-128.1 AS TINYINT)").returns((byte)-128).check(); - assertQuery("SELECT CAST(-128.9 AS TINYINT)").returns((byte)-128).check(); + assertQuery("SELECT CAST(-128.4 AS TINYINT)").returns((byte)-128).check(); + assertThrows("SELECT CAST(-128.5 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertThrows("SELECT CAST(-128.9 AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertQuery("SELECT CAST('127.1' AS TINYINT)").returns((byte)127).check(); - assertQuery("SELECT CAST('127.9' AS TINYINT)").returns((byte)127).check(); + assertQuery("SELECT CAST('127.4' AS TINYINT)").returns((byte)127).check(); + assertThrows("SELECT CAST('127.5' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertThrows("SELECT CAST('127.9' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST('128' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST('128.1' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST('-129' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertThrows("SELECT CAST('-129.1' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); assertQuery("SELECT CAST('-128.1' AS TINYINT)").returns((byte)-128).check(); - assertQuery("SELECT CAST('-128.9' AS TINYINT)").returns((byte)-128).check(); + assertQuery("SELECT CAST('-128.4' AS TINYINT)").returns((byte)-128).check(); + assertThrows("SELECT CAST('-128.5' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); + assertThrows("SELECT CAST('-128.9' AS TINYINT)", IgniteSQLException.class, "TINYINT overflow"); } /** */ diff --git a/modules/calcite/src/test/sql/function/numeric/test_floor_ceil.test b/modules/calcite/src/test/sql/function/numeric/test_round_ceil.test similarity index 96% rename from modules/calcite/src/test/sql/function/numeric/test_floor_ceil.test rename to modules/calcite/src/test/sql/function/numeric/test_round_ceil.test index fc0c0107a6f33..2d009414bc4c2 100644 --- a/modules/calcite/src/test/sql/function/numeric/test_floor_ceil.test +++ b/modules/calcite/src/test/sql/function/numeric/test_round_ceil.test @@ -11,41 +11,41 @@ INSERT INTO numbers VALUES (NULL),(-42.8),(-42.2),(0), (42.2), (42.8) query I SELECT cast(CEIL(n::tinyint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(CEIL(n::smallint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(CEIL(n::integer) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(CEIL(n::bigint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I @@ -81,41 +81,41 @@ NULL query I SELECT cast(FLOOR(n::tinyint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(FLOOR(n::smallint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(FLOOR(n::integer) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I SELECT cast(FLOOR(n::bigint) as bigint) FROM numbers ORDER BY n NULLS LAST ---- --42 +-43 -42 0 42 -42 +43 NULL query I diff --git a/modules/calcite/src/test/sql/function/numeric/test_trigo.test b/modules/calcite/src/test/sql/function/numeric/test_trigo.test index 628b30214a799..68836b276a2fd 100644 --- a/modules/calcite/src/test/sql/function/numeric/test_trigo.test +++ b/modules/calcite/src/test/sql/function/numeric/test_trigo.test @@ -11,121 +11,121 @@ INSERT INTO numbers VALUES (-42),(-1),(0), (1), (42), (NULL) query I SELECT cast(SIN(n::tinyint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(SIN(n::smallint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(SIN(n::integer)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(SIN(n::bigint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(SIN(n::float)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(SIN(n::double)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -916 +917 -841 0 841 --916 +-917 NULL query I SELECT cast(COS(n::tinyint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I SELECT cast(COS(n::smallint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I SELECT cast(COS(n::integer)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I SELECT cast(COS(n::bigint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I SELECT cast(COS(n::float)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I SELECT cast(COS(n::double)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --399 +-400 540 1000 540 --399 +-400 NULL query I @@ -191,145 +191,145 @@ NULL query I SELECT cast(ATAN(n::tinyint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ATAN(n::smallint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ATAN(n::integer)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ATAN(n::bigint)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ATAN(n::float)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ATAN(n::double)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- --1546 +-1547 -785 0 785 -1546 +1547 NULL query I SELECT cast(ASIN(n::tinyint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ASIN(n::smallint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ASIN(n::integer)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ASIN(n::bigint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ASIN(n::float)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ASIN(n::double)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- --1570 +-1571 0 -1570 +1571 query I SELECT cast(ACOS(n::tinyint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 query I SELECT cast(ACOS(n::smallint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 query I SELECT cast(ACOS(n::integer)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 query I SELECT cast(ACOS(n::bigint)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 query I SELECT cast(ACOS(n::float)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 query I SELECT cast(ACOS(n::double)*1000 as bigint) FROM numbers WHERE n between -1 and 1 ORDER BY n ---- -3141 -1570 +3142 +1571 0 statement error @@ -387,9 +387,9 @@ query I SELECT cast(ATAN2(n::tinyint, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL @@ -397,9 +397,9 @@ query I SELECT cast(ATAN2(n::smallint, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL @@ -407,9 +407,9 @@ query I SELECT cast(ATAN2(n::integer, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL @@ -417,9 +417,9 @@ query I SELECT cast(ATAN2(n::bigint, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL @@ -427,9 +427,9 @@ query I SELECT cast(ATAN2(n::float, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL @@ -437,9 +437,9 @@ query I SELECT cast(ATAN2(n::double, 42)*1000 as bigint) FROM numbers ORDER BY n NULLS LAST ---- -785 --23 +-24 0 -23 +24 785 NULL