AMashenkov commented on code in PR #2396:
URL: https://github.com/apache/ignite-3/pull/2396#discussion_r1288215887


##########
modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/exp/IgniteSqlFunctions.java:
##########
@@ -213,40 +192,90 @@ public static BigDecimal toBigDecimal(Object o, int 
precision, int scale) {
         }
 
         return o instanceof Number ? toBigDecimal((Number) o, precision, scale)
-               : toBigDecimal(o.toString(), precision, scale);
+                : toBigDecimal(o.toString(), precision, scale);
     }
 
     /**
-     * Converts the given {@code BigDecimal} to a decimal with the given 
{@code precision} and {@code scale}
+     * Converts the given {@code Number} to a decimal with the given {@code 
precision} and {@code scale}
      * according to SQL spec for CAST specification: General Rules, 8.
      */
-    public static BigDecimal convertDecimal(BigDecimal value, int precision, 
int scale) {
+    public static BigDecimal toBigDecimal(Number value, int precision, int 
scale) {
         assert precision > 0 : "Invalid precision: " + precision;
 
+        if (value == null) {
+            return null;
+        }
+
         int defaultPrecision = 
IgniteTypeSystem.INSTANCE.getDefaultPrecision(SqlTypeName.DECIMAL);
+
         if (precision == defaultPrecision) {
+            BigDecimal dec = convertToBigDecimal(value);
             // This branch covers at least one known case: access to dynamic 
parameter from context.
             // In this scenario precision = DefaultTypePrecision, because 
types for dynamic params
             // are created by toSql(createType(param.class)).
-            return value;
+            return dec;
         }
 
-        boolean nonZero = !value.unscaledValue().equals(BigInteger.ZERO);
+        BigDecimal dec = processFractionData(value, precision, scale);
 
-        if (nonZero) {
-            if (scale > precision) {
-                throw new SqlException(RUNTIME_ERR, 
NUMERIC_FIELD_OVERFLOW_ERROR);
-            } else {
-                int currentSignificantDigits = value.precision() - 
value.scale();
-                int expectedSignificantDigits = precision - scale;
+        if (dec != null) {
+            return dec;
+        } else {
+            dec = convertToBigDecimal(value);
+        }
 
-                if (currentSignificantDigits > expectedSignificantDigits) {
-                    throw new SqlException(RUNTIME_ERR, 
NUMERIC_FIELD_OVERFLOW_ERROR);
-                }
+        if (scale > precision) {
+            throw new SqlException(RUNTIME_ERR, NUMERIC_FIELD_OVERFLOW_ERROR);
+        } else {
+            int currentSignificantDigits = dec.precision() - dec.scale();
+            int expectedSignificantDigits = precision - scale;
+
+            if (currentSignificantDigits > expectedSignificantDigits) {
+                throw new SqlException(RUNTIME_ERR, 
NUMERIC_FIELD_OVERFLOW_ERROR);
             }
         }
 
-        return value.setScale(scale, RoundingMode.HALF_UP);
+        return dec.setScale(scale, roundingMode);
+    }
+
+    private static @Nullable BigDecimal processFractionData(Number value, int 
precision, int scale) {
+        if (value.longValue() != 0) {
+            return null;
+        }

Review Comment:
   Let's move this check to outside of this method.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to