You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by vl...@apache.org on 2018/08/28 09:33:55 UTC

calcite git commit: [CALCITE-2327] Avoid simplification of x AND NOT(x) to false for nullable x

Repository: calcite
Updated Branches:
  refs/heads/master af3e35d64 -> 141781bf4


[CALCITE-2327] Avoid simplification of x AND NOT(x) to false for nullable x

x AND NOT(x) ==> FALSE AND x IS NULL

closes #707


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

Branch: refs/heads/master
Commit: 141781bf4d591d973812c73ea9f03d715b5406cb
Parents: af3e35d
Author: Vladimir Sitnikov <si...@gmail.com>
Authored: Tue Aug 28 10:36:40 2018 +0300
Committer: Vladimir Sitnikov <si...@gmail.com>
Committed: Tue Aug 28 11:42:40 2018 +0300

----------------------------------------------------------------------
 .../org/apache/calcite/rex/RexSimplify.java     | 22 +++++++++++++++++++-
 .../org/apache/calcite/test/RexProgramTest.java |  4 +---
 2 files changed, 22 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/141781bf/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 7aaf141..1274391 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -718,11 +718,31 @@ public class RexSimplify {
     // Example #1. x AND y AND z AND NOT (x AND y)  - not satisfiable
     // Example #2. x AND y AND NOT (x AND y)        - not satisfiable
     // Example #3. x AND y AND NOT (x AND y AND z)  - may be satisfiable
+    RexNode bestNotDisjunction = null;
     for (RexNode notDisjunction : notTerms) {
       final List<RexNode> terms2 = RelOptUtil.conjunctions(notDisjunction);
-      if (terms.containsAll(terms2)) {
+      if (!terms.containsAll(terms2)) {
+        // may be satisfiable ==> check other terms
+        continue;
+      }
+      if (!notDisjunction.getType().isNullable()) {
+        // x is NOT nullable, then x AND NOT(x) ==> FALSE
         return rexBuilder.makeLiteral(false);
       }
+      // x AND NOT(x) is UNKNOWN for NULL input
+      // So we search for the shortest notDisjunction then convert
+      // original expression to NULL and x IS NULL
+      if (bestNotDisjunction == null
+          || bestNotDisjunction.toString().length() > notDisjunction.toString().length()) {
+        bestNotDisjunction = notDisjunction;
+      }
+    }
+    if (bestNotDisjunction != null) {
+      // NULL AND (x IS NULL)
+      return rexBuilder.makeCall(SqlStdOperatorTable.AND,
+          rexBuilder.makeNullLiteral(bestNotDisjunction.getType()),
+          simplifyIs(
+              (RexCall) rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, bestNotDisjunction)));
     }
     // Add the NOT disjunctions back in.
     for (RexNode notDisjunction : notTerms) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/141781bf/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 9a8c27d..990afb6 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -56,7 +56,6 @@ import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Multimap;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.math.BigDecimal;
@@ -1543,7 +1542,6 @@ public class RexProgramTest extends RexProgramBuilderBase {
         "false");
   }
 
-  @Ignore
   @Test public void testSimplifyAnd3() {
     final RelDataType boolType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
     final RelDataType rowType = typeFactory.builder()
@@ -1557,7 +1555,7 @@ public class RexProgramTest extends RexProgramBuilderBase {
     checkSimplify2(
         and(aRef,
             not(aRef)),
-        "a is null and null",
+        "AND(null, IS NULL(?0.a))",
         "false");
   }