Vladsz83 commented on code in PR #11635: URL: https://github.com/apache/ignite/pull/11635#discussion_r1829815537
########## modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java: ########## @@ -333,16 +325,142 @@ 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) + if (x < (Double)BYTE_BOUNDS[2] || x > (Double)BYTE_BOUNDS[3]) throw new ArithmeticException(TINYINT.getName() + " overflow"); - return (byte)x; + return (byte)round(x); } /** Cast value to {@code byte}, throwing an exception if the result overflows an {@code byte}. */ public static byte convertToByteExact(Number x) { - checkNumberLongBounds(TINYINT, x); + BigDecimal rounded = checkByteBounds(x); + + if (rounded != null) + return rounded.byteValue(); + + return convertToBigDecimal(x).setScale(0, NUMERIC_ROUNDING_MODE).byteValue(); + } + + /** */ + 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; + } + + /** */ + @Nullable private static BigDecimal checkLongBounds(Number x) { + if (x instanceof BigDecimal) { + BigDecimal rounded = ((BigDecimal)x).setScale(0, NUMERIC_ROUNDING_MODE); + + if (rounded.compareTo((BigDecimal)LONG_BOUNDS[4]) >= 0 && rounded.compareTo((BigDecimal)LONG_BOUNDS[5]) <= 0) + return rounded; + } + else if (x instanceof Double) { + if (((Double)x).compareTo((Double)LONG_BOUNDS[2]) < 0 && ((Double)x).compareTo((Double)LONG_BOUNDS[3]) > 0) + return null; + } + else if (x instanceof Float) { + if (((Float)x).compareTo((Float)LONG_BOUNDS[0]) < 0 && ((Float)x).compareTo((Float)LONG_BOUNDS[1]) > 0) + return null; + } + else + return null; + + throw new ArithmeticException(BIGINT.getName() + " overflow"); + } - return convertToByteExact(x.longValue()); + /** */ + @Nullable private static BigDecimal checkIntegerBounds(Number x) { + if (x instanceof BigDecimal) { + BigDecimal rounded = ((BigDecimal)x).setScale(0, NUMERIC_ROUNDING_MODE); + + if (rounded.compareTo((BigDecimal)INT_BOUNDS[4]) >= 0 && rounded.compareTo((BigDecimal)INT_BOUNDS[5]) <= 0) + return rounded; + } + else if (x instanceof Double) { + if (((Double)x).compareTo((Double)INT_BOUNDS[2]) < 0 && ((Double)x).compareTo((Double)INT_BOUNDS[3]) > 0) + return null; + } + else if (x instanceof Float) { + if (((Float)x).compareTo((Float)INT_BOUNDS[0]) < 0 && ((Float)x).compareTo((Float)INT_BOUNDS[1]) > 0) + return null; + } + else { + long longVal = x.longValue(); + + if (longVal >= Integer.MIN_VALUE && longVal <= Integer.MAX_VALUE) + return null; + } + + throw new ArithmeticException(INTEGER.getName() + " overflow"); + } + + /** */ + @Nullable private static BigDecimal checkShortBounds(Number x) { + if (x instanceof BigDecimal) { + BigDecimal rounded = ((BigDecimal)x).setScale(0, NUMERIC_ROUNDING_MODE); + + if (rounded.compareTo((BigDecimal)SHORT_BOUNDS[4]) >= 0 && rounded.compareTo((BigDecimal)SHORT_BOUNDS[5]) <= 0) + return rounded; + } + else if (x instanceof Double) { + if (((Double)x).compareTo((Double)SHORT_BOUNDS[2]) < 0 && ((Double)x).compareTo((Double)SHORT_BOUNDS[3]) > 0) + return null; + } + else if (x instanceof Float) { + if (((Float)x).compareTo((Float)SHORT_BOUNDS[0]) < 0 && ((Float)x).compareTo((Float)SHORT_BOUNDS[1]) > 0) + return null; + } + else { + long longVal = x.longValue(); + + if (longVal >= Short.MIN_VALUE && longVal <= Short.MAX_VALUE) + return null; + } + + throw new ArithmeticException(SMALLINT.getName() + " overflow"); + } + + /** */ + @Nullable private static BigDecimal checkByteBounds(Number x) { + if (x instanceof BigDecimal) { + BigDecimal rounded = ((BigDecimal)x).setScale(0, NUMERIC_ROUNDING_MODE); + + if (rounded.compareTo((BigDecimal)BYTE_BOUNDS[4]) >= 0 && rounded.compareTo((BigDecimal)BYTE_BOUNDS[5]) <= 0) + return rounded; + } + else if (x instanceof Double) { + if (((Double)x).compareTo((Double)BYTE_BOUNDS[2]) < 0 && ((Double)x).compareTo((Double)BYTE_BOUNDS[3]) > 0) + return null; + } + else if (x instanceof Float) { + if (((Float)x).compareTo((Float)BYTE_BOUNDS[0]) < 0 && ((Float)x).compareTo((Float)BYTE_BOUNDS[1]) > 0) + return null; + } + else { + long longVal = x.longValue(); + + if (longVal >= Byte.MIN_VALUE && longVal <= Byte.MAX_VALUE) + return null; + } + + throw new ArithmeticException(TINYINT.getName() + " overflow"); + } + + /** */ + private static double round(double x) { Review Comment: Renamed -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org