tanclary commented on code in PR #3234:
URL: https://github.com/apache/calcite/pull/3234#discussion_r1254727378


##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -1524,136 +1524,89 @@ public static int multiply(int b0, int b1) {
     throw notArithmetic("*", b0, b1);
   }
 
-  /** Helper method for safe arithmetic functions that checks if overflow has 
occurred. */
-  private static boolean isOverflow(BigDecimal ans, BigDecimal min, BigDecimal 
max) {
-    return ans.compareTo(min) > 0 || ans.compareTo(max) < 0;
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to integer values. */
-  public static @Nullable Integer safeMultiply(int b0, int b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow = isOverflow(ans, BigDecimal.valueOf(Integer.MAX_VALUE), 
BigDecimal.valueOf(Integer.MIN_VALUE));
-    return overflow ? null : ans.intValue();
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to integer and double 
values. */
-  public static @Nullable Double safeMultiply(int b0, double b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Double.MAX_VALUE), 
BigDecimal.valueOf(-Double.MAX_VALUE));
-    return overflow ? null : ans.doubleValue();
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to integer and 
BigDecimal values. */
-  public static @Nullable BigDecimal safeMultiply(int b0, BigDecimal b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), b1);
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to integer and long 
values. */
-  public static @Nullable Long safeMultiply(int b0, long b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Long.MAX_VALUE), 
BigDecimal.valueOf(Long.MIN_VALUE));
-    return overflow ? null : ans.longValue();
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to double and integer 
values. */
-  public static @Nullable Double safeMultiply(double b0, int b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Double.MAX_VALUE), 
BigDecimal.valueOf(-Double.MAX_VALUE));
-    return overflow ? null : ans.doubleValue();
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to double values. */
-  public static @Nullable Double safeMultiply(double b0, double b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Double.MAX_VALUE), 
BigDecimal.valueOf(-Double.MAX_VALUE));
-    return overflow ? null : ans.doubleValue();
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to double and BigDecimal 
values. */
-  public static @Nullable BigDecimal safeMultiply(double b0, BigDecimal b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), b1);
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
-  }
-
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to double and long 
values. */
-  public static @Nullable Long safeMultiply(double b0, long b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Long.MAX_VALUE), 
BigDecimal.valueOf(Long.MIN_VALUE));
-    return overflow ? null : ans.longValue();
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to long values. */
+  public static @Nullable Long safeMultiply(long b0, long b1) {
+    try {
+      return Math.multiplyExact(b0, b1);
+    } catch (ArithmeticException e) {
+      return null;
+    }
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal and 
integer values. */
-  public static @Nullable BigDecimal safeMultiply(BigDecimal b0, int b1) {
-    BigDecimal ans = multiply(b0, BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to long and BigDecimal 
values. */
+  public static @Nullable BigDecimal safeMultiply(long b0, BigDecimal b1) {
+    BigDecimal ans = BigDecimal.valueOf(b0).multiply(b1);
+    return decimalOverflow(ans) ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal and double 
values. */
-  public static @Nullable BigDecimal safeMultiply(BigDecimal b0, double b1) {
-    BigDecimal ans = multiply(b0, BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal and long 
values. */
+  public static @Nullable BigDecimal safeMultiply(BigDecimal b0, long b1) {
+    BigDecimal ans = b0.multiply(BigDecimal.valueOf(b1));
+    return decimalOverflow(ans) ? ans : null;
   }
 
   /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal values. */
   public static @Nullable BigDecimal safeMultiply(BigDecimal b0, BigDecimal 
b1) {
-    BigDecimal ans = multiply(b0, b1);
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
+    BigDecimal ans = b0.multiply(b1);
+    return decimalOverflow(ans) ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal and long 
values. */
-  public static @Nullable BigDecimal safeMultiply(BigDecimal b0, long b1) {
-    BigDecimal ans = multiply(b0, BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to double and long 
values. */
+  public static @Nullable Double safeMultiply(double b0, long b1) {
+    double ans = b0 * b1;
+    boolean isInfinite = Double.isInfinite(b0);
+    return doubleOverflow(ans) || isInfinite ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to long and integer 
values. */
-  public static @Nullable Long safeMultiply(long b0, int b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Long.MAX_VALUE), 
BigDecimal.valueOf(Long.MIN_VALUE));
-    return overflow ? null : ans.longValue();
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to long and double 
values. */
+  public static @Nullable Double safeMultiply(long b0, double b1) {
+    double ans = b0 * b1;
+    boolean isInfinite = Double.isInfinite(b1);
+    return doubleOverflow(ans) || isInfinite ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to long and double 
values. */
-  public static @Nullable Long safeMultiply(long b0, double b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Long.MAX_VALUE), 
BigDecimal.valueOf(Long.MIN_VALUE));
-    return overflow ? null : ans.longValue();
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to double and BigDecimal 
values. */
+  public static @Nullable Double safeMultiply(double b0, BigDecimal b1) {
+    double ans = b0 * b1.doubleValue();
+    boolean isInfinite = Double.isInfinite(b0);
+    return doubleOverflow(ans) || isInfinite ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to long values. */
-  public static @Nullable Long safeMultiply(long b0, long b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), BigDecimal.valueOf(b1));
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Long.MAX_VALUE), 
BigDecimal.valueOf(Long.MIN_VALUE));
-    return overflow ? null : ans.longValue();
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal and double 
values. */
+  public static @Nullable Double safeMultiply(BigDecimal b0, double b1) {
+    double ans = b0.doubleValue() * b1;
+    boolean isInfinite = Double.isInfinite(b1);
+    return doubleOverflow(ans) || isInfinite ? ans : null;
   }
 
-  /** SQL <code>SAFE_MULTIPLY</code> function applied to long and BigDecimal 
values. */
-  public static @Nullable BigDecimal safeMultiply(long b0, BigDecimal b1) {
-    BigDecimal ans = multiply(BigDecimal.valueOf(b0), b1);
-    boolean overflow =
-        isOverflow(ans, BigDecimal.valueOf(Float.MAX_VALUE), 
BigDecimal.valueOf(-Float.MAX_VALUE));
-    return overflow ? null : ans;
+  /** SQL <code>SAFE_MULTIPLY</code> function applied to double values. */
+  public static @Nullable Double safeMultiply(double b0, double b1) {
+    double ans = b0 * b1;
+    boolean isInfinite = Double.isInfinite(b0) || Double.isInfinite(b1);
+    return doubleOverflow(ans) || isInfinite ? ans : null;
+  }
+
+  /** Helper for the safe arithmetic functions to determine
+   * overflow for a BigDecimal value. According to BigQuery, BigDecimal
+   * overflow occurs if the precision is greater than 76 or the precision
+   * is greater than 38. */

Review Comment:
   Oops, good catch. Fixed now.



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