You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/12/17 23:46:17 UTC

calcite git commit: Fix Strong functionality broken in [CALCITE-1526]

Repository: calcite
Updated Branches:
  refs/heads/master d6940a1a9 -> cd8060894


Fix Strong functionality broken in [CALCITE-1526]


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

Branch: refs/heads/master
Commit: cd806089478dae1276280c1bedf487c9719907fa
Parents: d6940a1
Author: Julian Hyde <jh...@apache.org>
Authored: Wed Dec 14 15:04:46 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 17 12:00:58 2016 -0800

----------------------------------------------------------------------
 .../org/apache/calcite/plan/RelOptUtil.java     |  4 ++--
 .../java/org/apache/calcite/plan/Strong.java    | 23 ++++++++++++++++++--
 .../org/apache/calcite/test/RexProgramTest.java | 11 ++++++++++
 3 files changed, 34 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/cd806089/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index bf24a41..f51c625 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -2234,11 +2234,11 @@ public abstract class RelOptUtil {
 
     for (RexNode filter : aboveFilters) {
       if (joinType.generatesNullsOnLeft()
-          && Strong.isNull(filter, leftBitmap)) {
+          && Strong.isNotTrue(filter, leftBitmap)) {
         joinType = joinType.cancelNullsOnLeft();
       }
       if (joinType.generatesNullsOnRight()
-          && Strong.isNull(filter, rightBitmap)) {
+          && Strong.isNotTrue(filter, rightBitmap)) {
         joinType = joinType.cancelNullsOnRight();
       }
       if (joinType == JoinRelType.INNER) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/cd806089/core/src/main/java/org/apache/calcite/plan/Strong.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/Strong.java b/core/src/main/java/org/apache/calcite/plan/Strong.java
index b18e11c..7fd6055 100644
--- a/core/src/main/java/org/apache/calcite/plan/Strong.java
+++ b/core/src/main/java/org/apache/calcite/plan/Strong.java
@@ -54,6 +54,10 @@ import java.util.Map;
 public class Strong {
   private static final Map<SqlKind, Policy> MAP = createPolicyMap();
 
+  public Strong() {
+    super();
+  }
+
   /** Returns a checker that consults a bit set to find out whether particular
    * inputs may be null. */
   public static Strong of(final ImmutableBitSet nullColumns) {
@@ -70,12 +74,29 @@ public class Strong {
     return of(nullColumns).isNull(node);
   }
 
+  /** Returns whether the analyzed expression will definitely not return true
+   * (equivalently, will definitely not return null or false) if
+   * all of a given set of input columns are null. */
+  public static boolean isNotTrue(RexNode node, ImmutableBitSet nullColumns) {
+    return of(nullColumns).isNotTrue(node);
+  }
+
   /** Returns how to deduce whether a particular kind of expression is null,
    * given whether its arguments are null. */
   public static Policy policy(SqlKind kind) {
     return Preconditions.checkNotNull(MAP.get(kind), kind);
   }
 
+  /** Returns whether an expression is definitely not true. */
+  public boolean isNotTrue(RexNode node) {
+    switch (node.getKind()) {
+    case IS_NOT_NULL:
+      return anyNull(((RexCall) node).getOperands());
+    default:
+      return isNull(node);
+    }
+  }
+
   /** Returns whether an expression is definitely null.
    *
    * <p>The answer is based on calls to {@link #isNull} for its constituent
@@ -85,8 +106,6 @@ public class Strong {
     switch (node.getKind()) {
     case LITERAL:
       return ((RexLiteral) node).getValue() == null;
-    case IS_TRUE:
-    case IS_NOT_NULL:
     case AND:
     case NOT:
     case EQUALS:

http://git-wip-us.apache.org/repos/asf/calcite/blob/cd806089/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 f72ab55..3ca7c44 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -536,6 +536,17 @@ public class RexProgramTest {
     // If i0 is null, "i0 or i1" is not necessarily null
     assertThat(Strong.isNull(or(i0, i1), c0), is(false));
     assertThat(Strong.isNull(or(i0, i1), c1), is(false));
+
+    // If i0 is null, then "i0 is not null" is false
+    RexNode i0NotNull = isNotNull(i0);
+    assertThat(Strong.isNull(i0NotNull, c0), is(false));
+    assertThat(Strong.isNotTrue(i0NotNull, c0), is(true));
+
+    // If i0 is null, then "not(i0 is not null)" is true.
+    // Join-strengthening relies on this.
+    RexNode notI0NotNull = not(isNotNull(i0));
+    assertThat(Strong.isNull(notI0NotNull, c0), is(false));
+    assertThat(Strong.isNotTrue(notI0NotNull, c0), is(false));
   }
 
   /** Unit test for {@link org.apache.calcite.rex.RexUtil#toCnf}. */