Repository: calcite
Updated Branches:
  refs/heads/master d12549530 -> 86993bded


Following [CALCITE-2469] simplify "f(x, y) IS NULL" to "x IS NULL OR y IS NULL" 
if "f" is strong

Previously we did not use OR, which was wrong.


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

Branch: refs/heads/master
Commit: 86993bdedea758916deefcabbfd38eaa1c14eca7
Parents: d125495
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Aug 31 11:33:07 2018 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Sep 3 19:22:17 2018 -0700

----------------------------------------------------------------------
 .../java/org/apache/calcite/rex/RexSimplify.java    | 12 +++++-------
 .../org/apache/calcite/test/RexProgramTest.java     | 16 ++++++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/86993bde/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 f69ca9a..892b7ab 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -501,8 +501,8 @@ public class RexSimplify {
     case NOT_NULL:
       return rexBuilder.makeLiteral(true);
     case ANY:
-      // "f" is a strong operator, so "f(operand) IS NOT NULL" simplifies to
-      // "operand IS NOT NULL"
+      // "f" is a strong operator, so "f(operand0, operand1) IS NOT NULL"
+      // simplifies to "operand0 IS NOT NULL AND operand1 IS NOT NULL"
       final List<RexNode> operands = new ArrayList<>();
       for (RexNode operand : ((RexCall) a).getOperands()) {
         final RexNode simplified = simplifyIsNotNull(operand);
@@ -538,21 +538,19 @@ public class RexSimplify {
     case NOT_NULL:
       return rexBuilder.makeLiteral(false);
     case ANY:
-      // "f" is a strong operator, so "f(operand) IS NULL" simplifies to
-      // "operand IS NULL"
+      // "f" is a strong operator, so "f(operand0, operand1) IS NULL" 
simplifies
+      // to "operand0 IS NULL OR operand1 IS NULL"
       final List<RexNode> operands = new ArrayList<>();
       for (RexNode operand : ((RexCall) a).getOperands()) {
         final RexNode simplified = simplifyIsNull(operand);
         if (simplified == null) {
           operands.add(
               rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, operand));
-        } else if (simplified.isAlwaysFalse()) {
-          return rexBuilder.makeLiteral(false);
         } else {
           operands.add(simplified);
         }
       }
-      return RexUtil.composeConjunction(rexBuilder, operands, false);
+      return RexUtil.composeDisjunction(rexBuilder, operands, false);
     case AS_IS:
     default:
       return null;

http://git-wip-us.apache.org/repos/asf/calcite/blob/86993bde/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 92ad323..aa6c808 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -1199,6 +1199,22 @@ public class RexProgramTest extends 
RexProgramBuilderBase {
     // "(not x) is not null" to "x is not null"
     checkSimplify(isNotNull(not(vBool())), "IS NOT NULL(?0.bool0)");
     checkSimplify(isNotNull(not(vBoolNotNull())), "true");
+
+    // "(x + y) is null" simplifies to "x is null or y is null"
+    checkSimplify(isNull(plus(vInt(0), vInt(1))),
+        "OR(IS NULL(?0.int0), IS NULL(?0.int1))");
+    checkSimplify(isNull(plus(vInt(0), vIntNotNull(1))), "IS NULL(?0.int0)");
+    checkSimplify(isNull(plus(vIntNotNull(0), vIntNotNull(1))), "false");
+    checkSimplify(isNull(plus(vIntNotNull(0), vInt(1))), "IS NULL(?0.int1)");
+
+    // "(x + y) is not null" simplifies to "x is not null and y is not null"
+    checkSimplify(isNotNull(plus(vInt(0), vInt(1))),
+        "AND(IS NOT NULL(?0.int0), IS NOT NULL(?0.int1))");
+    checkSimplify(isNotNull(plus(vInt(0), vIntNotNull(1))),
+        "IS NOT NULL(?0.int0)");
+    checkSimplify(isNotNull(plus(vIntNotNull(0), vIntNotNull(1))), "true");
+    checkSimplify(isNotNull(plus(vIntNotNull(0), vInt(1))),
+        "IS NOT NULL(?0.int1)");
   }
 
   @Test public void testSimplifyFilter() {

Reply via email to