alex-plekhanov commented on code in PR #11635:
URL: https://github.com/apache/ignite/pull/11635#discussion_r1829790918


##########
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:
   Method doesn't round value. It's adds or substracts 0.5 to the value 
(prepare to round). round method should return value without floating point. 



##########
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:
   Method doesn't round value. It adds or substracts 0.5 to the value (prepare 
to round). round method should return value without floating point. 



-- 
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

Reply via email to