You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by xi...@apache.org on 2022/02/15 01:43:17 UTC

[calcite] branch master updated: [CALCITE-4988] ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL) When A is deterministic

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

xiong 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 4a6e222  [CALCITE-4988] ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL) When A is deterministic
4a6e222 is described below

commit 4a6e2228c2e2ccf46acb31a0342a1b7d4563e2f6
Author: NobiGo <no...@gmail.com>
AuthorDate: Fri Jan 21 19:05:22 2022 +0800

    [CALCITE-4988] ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL) When A is deterministic
---
 .../java/org/apache/calcite/rex/RexSimplify.java   |  4 +-
 .../org/apache/calcite/rex/RexProgramTest.java     | 76 ++++++++++++++++++++++
 2 files changed, 78 insertions(+), 2 deletions(-)

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 96338ab..7c0aa6b 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -865,7 +865,7 @@ public class RexSimplify {
   }
 
   private @Nullable RexNode simplifyIsPredicate(SqlKind kind, RexNode a) {
-    if (!RexUtil.isReferenceOrAccess(a, true)) {
+    if (!(RexUtil.isReferenceOrAccess(a, true) || RexUtil.isDeterministic(a))) {
       return null;
     }
 
@@ -2664,7 +2664,7 @@ public class RexSimplify {
       case IS_NULL:
       case IS_NOT_NULL:
         RexNode pA = ((RexCall) e).getOperands().get(0);
-        if (!RexUtil.isReferenceOrAccess(pA, true)) {
+        if (!(RexUtil.isReferenceOrAccess(pA, true) || RexUtil.isDeterministic(pA))) {
           return null;
         }
         return new IsPredicate(pA, e.getKind());
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
index 9edb64a..691c954 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
@@ -2157,6 +2157,82 @@ class RexProgramTest extends RexProgramTestBase {
     checkSimplify(isNotNull(cast(i2, intType)), "true");
   }
 
+  /**
+   * Unit test for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-4988">[CALCITE-4988]
+   * ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL)
+   * When A is deterministic</a>. */
+  @Test void testSimplifyIsNotNullWithDeterministic() {
+    // "(A IS NOT NULL OR B) AND A IS NOT NULL" when A is deterministic
+    // ==>
+    // "A IS NOT NULL"
+    SqlOperator dc = getDeterministicOperator();
+    checkSimplify2(
+        and(or(isNotNull(rexBuilder.makeCall(dc)), gt(vInt(2), literal(2))),
+            isNotNull(rexBuilder.makeCall(dc))),
+        "AND(OR(IS NOT NULL(DC()), >(?0.int2, 2)), IS NOT NULL(DC()))",
+        "IS NOT NULL(DC())");
+  }
+
+  @Test void testSimplifyIsNotNullWithDeterministic2() {
+    // "(A IS NOT NULL AND B) OR A IS NULL" when A is deterministic
+    // ==>
+    // "A IS NULL OR B"
+    SqlOperator dc = getDeterministicOperator();
+    checkSimplify(
+            or(and(isNotNull(rexBuilder.makeCall(dc)), gt(vInt(2), literal(2))),
+                    isNull(rexBuilder.makeCall(dc))),
+            "OR(IS NULL(DC()), >(?0.int2, 2))");
+  }
+
+  @Test void testSimplifyIsNotNullWithNoDeterministic() {
+    // "(A IS NOT NULL OR B) AND A IS NOT NULL" when A is not deterministic
+    // ==>
+    // "(A IS NOT NULL OR B) AND A IS NOT NULL"
+    SqlOperator ndc = getNoDeterministicOperator();
+    checkSimplifyUnchanged(
+        and(or(isNotNull(rexBuilder.makeCall(ndc)), gt(vInt(2), literal(2))),
+            isNotNull(rexBuilder.makeCall(ndc))));
+  }
+
+  @Test void testSimplifyIsNotNullWithNoDeterministic2() {
+    // "(A IS NOT NULL AND B) OR A IS NOT NULL" when A is not deterministic
+    // ==>
+    // "(A IS NOT NULL AND B) OR A IS NOT NULL"
+    SqlOperator ndc = getNoDeterministicOperator();
+    checkSimplifyUnchanged(
+            and(or(isNotNull(rexBuilder.makeCall(ndc)), gt(vInt(2), literal(2))),
+                    isNotNull(rexBuilder.makeCall(ndc))));
+  }
+
+  private SqlOperator getDeterministicOperator() {
+    return new SqlSpecialOperator(
+            "DC",
+            SqlKind.OTHER_FUNCTION,
+            0,
+            false,
+            ReturnTypes.BOOLEAN_FORCE_NULLABLE,
+            null, null) {
+      @Override public boolean isDeterministic() {
+        return true;
+      }
+    };
+  }
+
+  private SqlOperator getNoDeterministicOperator() {
+    return new SqlSpecialOperator(
+            "NDC",
+            SqlKind.OTHER_FUNCTION,
+            0,
+            false,
+            ReturnTypes.BOOLEAN_FORCE_NULLABLE,
+            null, null) {
+      @Override public boolean isDeterministic() {
+        return false;
+      }
+    };
+  }
+
   /** Unit test for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-2929">[CALCITE-2929]
    * Simplification of IS NULL checks are incorrectly assuming that CAST-s are possible</a>. */