tanclary commented on code in PR #3234:
URL: https://github.com/apache/calcite/pull/3234#discussion_r1282152026
##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -1592,6 +1592,87 @@ public static int multiply(int b0, int b1) {
throw notArithmetic("*", b0, b1);
}
+ /** 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 long and BigDecimal
values. */
+ public static @Nullable BigDecimal safeMultiply(long b0, BigDecimal b1) {
+ BigDecimal ans = BigDecimal.valueOf(b0).multiply(b1);
+ return safeDecimal(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 = b0.multiply(BigDecimal.valueOf(b1));
+ return safeDecimal(ans) ? ans : null;
+ }
+
+ /** SQL <code>SAFE_MULTIPLY</code> function applied to BigDecimal values. */
+ public static @Nullable BigDecimal safeMultiply(BigDecimal b0, BigDecimal
b1) {
+ BigDecimal ans = b0.multiply(b1);
+ return safeDecimal(ans) ? ans : null;
+ }
+
+ /** 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;
+ return safeDouble(ans) || !Double.isFinite(b0) ? ans : null;
+ }
+
+ /** 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;
+ return safeDouble(ans) || !Double.isFinite(b1) ? ans : null;
+ }
+
+ /** 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();
+ return safeDouble(ans) || !Double.isFinite(b0) ? ans : null;
+ }
+
+ /** 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;
+ return safeDouble(ans) || !Double.isFinite(b1) ? ans : null;
+ }
+
+ /** SQL <code>SAFE_MULTIPLY</code> function applied to double values. */
+ public static @Nullable Double safeMultiply(double b0, double b1) {
+ double ans = b0 * b1;
+ boolean isFinite = Double.isFinite(b0) && Double.isFinite(b1);
+ return safeDouble(ans) || !isFinite ? 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 scale
+ * is greater than 38. */
+ private static boolean safeDecimal(BigDecimal b) {
+ return b.scale() <= 38 && b.precision() <= 76;
+ }
+
+ /** Helper for the safe arithmetic functions to determine
Review Comment:
Done
##########
core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java:
##########
@@ -2369,6 +2372,30 @@ private static class LastDayImplementor extends
MethodNameImplementor {
}
}
+ /** Implementor for the {@code SAFE_MULTIPLY} function. */
+ private static class SafeArithmeticImplementor extends MethodNameImplementor
{
+ SafeArithmeticImplementor() {
+ super("safeMultiply", NullPolicy.STRICT, false);
+ }
+
+ @Override Expression implementSafe(final RexToLixTranslator translator,
+ final RexCall call, final List<Expression> argValueList) {
+ Expression arg0 = convertType(argValueList.get(0), call.operands.get(0));
+ Expression arg1 = convertType(argValueList.get(1), call.operands.get(1));
+ return Expressions.call(SqlFunctions.class, "safeMultiply", arg0, arg1);
+ }
+
+ // Because BigQuery treats all int types as aliases for BIGINT (Java's
LONG)
Review Comment:
Done
--
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]