You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by gi...@apache.org on 2017/10/12 03:59:23 UTC

calcite git commit: [CALCITE-2007] Fix RexSimplify behavior when literals come first.

Repository: calcite
Updated Branches:
  refs/heads/master 453e928b6 -> 06c18ca74


[CALCITE-2007] Fix RexSimplify behavior when literals come first.

It would incorrectly simplify "1 < x AND x < 3" to "x < 3".


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/06c18ca7
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/06c18ca7
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/06c18ca7

Branch: refs/heads/master
Commit: 06c18ca74df2d4bf20a5dccef11d424ab28c97d7
Parents: 453e928
Author: Gian Merlino <gi...@gmail.com>
Authored: Wed Oct 11 16:55:01 2017 -0700
Committer: Gian Merlino <gi...@gmail.com>
Committed: Wed Oct 11 20:53:42 2017 -0700

----------------------------------------------------------------------
 .../org/apache/calcite/rex/RexSimplify.java     | 50 ++++++++++++++++----
 .../org/apache/calcite/test/RexProgramTest.java | 24 ++++++++++
 2 files changed, 64 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/06c18ca7/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
index f826c77..464d28f 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -1125,12 +1125,9 @@ public class RexSimplify {
       if (removeUpperBound) {
         ImmutableList.Builder<RexNode> newBounds = ImmutableList.builder();
         for (RexNode e : p.right) {
-          switch (e.getKind()) {
-          case LESS_THAN:
-          case LESS_THAN_OR_EQUAL:
+          if (isUpperBound(e)) {
             Collections.replaceAll(terms, e, rexBuilder.makeLiteral(true));
-            break;
-          default:
+          } else {
             newBounds.add(e);
           }
         }
@@ -1140,12 +1137,9 @@ public class RexSimplify {
       } else if (removeLowerBound) {
         ImmutableList.Builder<RexNode> newBounds = ImmutableList.builder();
         for (RexNode e : p.right) {
-          switch (e.getKind()) {
-          case GREATER_THAN:
-          case GREATER_THAN_OR_EQUAL:
+          if (isLowerBound(e)) {
             Collections.replaceAll(terms, e, rexBuilder.makeLiteral(true));
-            break;
-          default:
+          } else {
             newBounds.add(e);
           }
         }
@@ -1218,6 +1212,42 @@ public class RexSimplify {
       return null;
     }
   }
+
+  private static boolean isUpperBound(final RexNode e) {
+    final List<RexNode> operands;
+    switch (e.getKind()) {
+    case LESS_THAN:
+    case LESS_THAN_OR_EQUAL:
+      operands = ((RexCall) e).getOperands();
+      return RexUtil.isReferenceOrAccess(operands.get(0), true)
+          && operands.get(1).isA(SqlKind.LITERAL);
+    case GREATER_THAN:
+    case GREATER_THAN_OR_EQUAL:
+      operands = ((RexCall) e).getOperands();
+      return RexUtil.isReferenceOrAccess(operands.get(1), true)
+          && operands.get(0).isA(SqlKind.LITERAL);
+    default:
+      return false;
+    }
+  }
+
+  private static boolean isLowerBound(final RexNode e) {
+    final List<RexNode> operands;
+    switch (e.getKind()) {
+    case LESS_THAN:
+    case LESS_THAN_OR_EQUAL:
+      operands = ((RexCall) e).getOperands();
+      return RexUtil.isReferenceOrAccess(operands.get(1), true)
+          && operands.get(0).isA(SqlKind.LITERAL);
+    case GREATER_THAN:
+    case GREATER_THAN_OR_EQUAL:
+      operands = ((RexCall) e).getOperands();
+      return RexUtil.isReferenceOrAccess(operands.get(0), true)
+          && operands.get(1).isA(SqlKind.LITERAL);
+    default:
+      return false;
+    }
+  }
 }
 
 // End RexSimplify.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/06c18ca7/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
index d42cfbb..6cc4e44 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -1329,6 +1329,30 @@ public class RexProgramTest {
     // condition with null value for range
     checkSimplifyFilter(and(gt(aRef, unknownLiteral), ge(bRef, literal1)), "false");
 
+    // condition "1 < a && 5 < x" yields "5 < x"
+    checkSimplifyFilter(
+        and(lt(literal1, aRef), lt(literal5, aRef)),
+        RelOptPredicateList.EMPTY,
+        "<(5, ?0.a)");
+
+    // condition "1 < a && a < 5" is unchanged
+    checkSimplifyFilter(
+        and(lt(literal1, aRef), lt(aRef, literal5)),
+        RelOptPredicateList.EMPTY,
+        "AND(<(1, ?0.a), <(?0.a, 5))");
+
+    // condition "1 > a && 5 > x" yields "1 > a"
+    checkSimplifyFilter(
+        and(gt(literal1, aRef), gt(literal5, aRef)),
+        RelOptPredicateList.EMPTY,
+        ">(1, ?0.a)");
+
+    // condition "1 > a && a > 5" yields false
+    checkSimplifyFilter(
+        and(gt(literal1, aRef), gt(aRef, literal5)),
+        RelOptPredicateList.EMPTY,
+        "false");
+
     // range with no predicates;
     // condition "a > 1 && a < 10 && a < 5" yields "a < 1 && a < 5"
     checkSimplifyFilter(