liyafan82 commented on a change in pull request #2282:
URL: https://github.com/apache/calcite/pull/2282#discussion_r532346934



##########
File path: core/src/main/java/org/apache/calcite/rex/RexSimplify.java
##########
@@ -329,6 +336,93 @@ private RexNode simplifyGenericNode(RexCall e) {
     return rexBuilder.makeCall(e.getType(), e.getOperator(), operands);
   }
 
+  /**
+   * Try to find a literal with the given value in the input list.
+   */
+  private int findLiteralIndex(List<RexNode> operands, long value) {
+    for (int i = 0; i < operands.size(); i++) {
+      if (operands.get(i).isA(SqlKind.LITERAL)) {
+        Comparable comparable = ((RexLiteral) operands.get(i)).getValue();
+        if (comparable instanceof BigDecimal && ((BigDecimal) 
comparable).longValue() == value) {
+          return i;
+        }
+      }
+    }
+    return -1;
+  }
+
+  private RexNode simplifyArithmetic(RexCall e) {
+    if (e.getType().getSqlTypeName().getFamily() != SqlTypeFamily.NUMERIC
+        || e.getOperands().stream()
+        .anyMatch(o -> e.getType().getSqlTypeName().getFamily() != 
SqlTypeFamily.NUMERIC)) {
+      // we only support simplifying numeric types
+      return simplifyGenericNode(e);
+    }
+
+    assert e.getOperands().size() == 2;
+
+    // if any operand is null, the result will be null
+    if (RexUtil.isNullLiteral(e.operands.get(0), true)
+        || RexUtil.isNullLiteral(e.operands.get(1), true)) {
+      return rexBuilder.makeNullLiteral(e.type);
+    }
+
+    switch (e.getKind()) {
+    case PLUS:
+      return simplifyPlus(e);
+    case MINUS:
+      return simplifyMinus(e);
+    case TIMES:
+      return simplifyMultiply(e);
+    case DIVIDE:
+      return simplifyDivide(e);
+    default:
+      throw new IllegalArgumentException("Unsupported arithmeitc operation " + 
e.getKind());
+    }
+  }
+
+  private RexNode simplifyPlus(RexCall e) {
+    int zeroIndex = findLiteralIndex(e.operands, 0L);
+    if (zeroIndex >= 0) {
+      // return the other operand
+      RexNode other = e.getOperands().get((zeroIndex + 1) % 2);
+      return other.getType().equals(e.getType())
+          ? other : rexBuilder.makeCast(e.getType(), other);
+    }
+    return simplifyGenericNode(e);
+  }
+
+  private RexNode simplifyMinus(RexCall e) {
+    int zeroIndex = findLiteralIndex(e.operands, 0L);
+    if (zeroIndex == 1) {
+      RexNode leftOperand = e.getOperands().get(0);
+      return leftOperand.getType().equals(e.getType())
+          ? leftOperand : rexBuilder.makeCast(e.getType(), leftOperand);

Review comment:
       Thanks for the suggestion. 
   There are some special cases for which this is not true. For example,
   ```
   NaN - NaN = NaN
   Inf - Inf = NaN
   ```




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

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


Reply via email to