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


##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -1524,6 +1524,139 @@ 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 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 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 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));

Review Comment:
   I agree with both of you, `Double` makes more sense than `Float`. I've 
changed it.



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