This is an automated email from the ASF dual-hosted git repository.

jcamacho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new ee1a9d2  [CALCITE-3914] Improve SubstitutionVisitor to consider 
RexCall of type PLUS and TIMES for canonicalization (Vineet Garg)
ee1a9d2 is described below

commit ee1a9d2cacb67da4c5d7e8f0441c94a40dc69d66
Author: Vineet Garg <[email protected]>
AuthorDate: Fri Apr 10 15:07:18 2020 -0700

    [CALCITE-3914] Improve SubstitutionVisitor to consider RexCall of type PLUS 
and TIMES for canonicalization (Vineet Garg)
    
    Close apache/calcite#1909
---
 .../apache/calcite/plan/SubstitutionVisitor.java   | 23 ++++++++-
 .../apache/calcite/test/MaterializationTest.java   | 59 ++++++++++++++++++++++
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java 
b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
index 26a43fe..1c01ab5 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -345,13 +345,32 @@ public class SubstitutionVisitor {
     case LESS_THAN_OR_EQUAL:
     case GREATER_THAN_OR_EQUAL: {
       RexCall call = (RexCall) condition;
-      final RexNode left = call.getOperands().get(0);
-      final RexNode right = call.getOperands().get(1);
+      RexNode left = canonizeNode(rexBuilder, call.getOperands().get(0));
+      RexNode right = canonizeNode(rexBuilder, call.getOperands().get(1));
+      call = (RexCall) rexBuilder.makeCall(call.getOperator(), left, right);
+
       if (left.toString().compareTo(right.toString()) <= 0) {
         return call;
       }
       return RexUtil.invert(rexBuilder, call);
     }
+    case PLUS:
+    case TIMES: {
+      RexCall call = (RexCall) condition;
+      RexNode left = canonizeNode(rexBuilder, call.getOperands().get(0));
+      RexNode right = canonizeNode(rexBuilder, call.getOperands().get(1));
+
+      if (left.toString().compareTo(right.toString()) <= 0) {
+        return rexBuilder.makeCall(call.getOperator(), left, right);
+      }
+
+      RexNode newCall = rexBuilder.makeCall(call.getOperator(), right, left);
+      // new call should not be used if its inferred type is not same as old
+      if (!newCall.getType().equals(call.getType())) {
+        return call;
+      }
+      return newCall;
+    }
     default:
       return condition;
     }
diff --git 
a/core/src/test/java/org/apache/calcite/test/MaterializationTest.java 
b/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
index 8b33221..3caa53f 100644
--- a/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
+++ b/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
@@ -1297,6 +1297,35 @@ class MaterializationTest {
     final RexNode z_eq_3 =
         rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, z, i3); // $2 = 3
 
+    final RexNode x_plus_y_gt =  // x + y > 2
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.GREATER_THAN,
+            rexBuilder.makeCall(SqlStdOperatorTable.PLUS, x, y),
+            i2);
+    final RexNode y_plus_x_gt =  // y + x > 2
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.GREATER_THAN,
+            rexBuilder.makeCall(SqlStdOperatorTable.PLUS, y, x),
+            i2);
+
+    final RexNode x_times_y_gt = // x*y > 2
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.GREATER_THAN,
+            rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, x, y),
+            i2);
+
+    final RexNode y_times_x_gt = // 2 < y*x
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.LESS_THAN,
+            i2,
+            rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, y, x));
+
+    final RexNode x_plus_x_gt =  // x + x > 2
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.GREATER_THAN,
+            rexBuilder.makeCall(SqlStdOperatorTable.PLUS, x, y),
+            i2);
+
     RexNode newFilter;
 
     // Example 1.
@@ -1416,6 +1445,36 @@ class MaterializationTest {
         x_eq_1,
         x_eq_2);
     assertNull(newFilter);
+
+    // Example 8.
+    //   condition: x + y > 2
+    //   target:    y + x > 2
+    // yields
+    //   residue:  true
+    newFilter = SubstitutionVisitor.splitFilter(simplify,
+        x_plus_y_gt,
+        y_plus_x_gt);
+    assertThat(newFilter.isAlwaysTrue(), equalTo(true));
+
+    // Example 9.
+    //   condition: x + x > 2
+    //   target:    x + x > 2
+    // yields
+    //   residue:  true
+    newFilter = SubstitutionVisitor.splitFilter(simplify,
+        x_plus_x_gt,
+        x_plus_x_gt);
+    assertThat(newFilter.isAlwaysTrue(), equalTo(true));
+
+    // Example 10.
+    //   condition: x * y > 2
+    //   target:    2 < y * x
+    // yields
+    //   residue:  true
+    newFilter = SubstitutionVisitor.splitFilter(simplify,
+        x_times_y_gt,
+        y_times_x_gt);
+    assertThat(newFilter.isAlwaysTrue(), equalTo(true));
   }
 
   /** Tests a complicated star-join query on a complicated materialized

Reply via email to