DRILL-6054: don't try to split the filter when it is not AND

This closes #1078


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

Branch: refs/heads/master
Commit: ef0fafea214e866556fa39c902685d48a56001e1
Parents: dcaac1b
Author: chunhui-shi <[email protected]>
Authored: Fri Dec 22 15:42:27 2017 -0800
Committer: Parth Chandra <[email protected]>
Committed: Thu Jan 11 17:22:58 2018 -0800

----------------------------------------------------------------------
 .../partition/FindPartitionConditions.java      | 21 ++++--
 .../exec/planner/logical/FilterSplitTest.java   | 69 +++++++++++++++++++-
 2 files changed, 82 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/ef0fafea/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/FindPartitionConditions.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/FindPartitionConditions.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/FindPartitionConditions.java
index da90065..87732c3 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/FindPartitionConditions.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/FindPartitionConditions.java
@@ -195,8 +195,16 @@ public class FindPartitionConditions extends 
RexVisitorImpl<Void> {
          * For all other operators we clear the children if one of the
          * children is a no push.
          */
-        assert currentOp.getOp().getKind() == SqlKind.AND;
-        newFilter = currentOp.getChildren().get(0);
+        if (currentOp.getOp().getKind() == SqlKind.AND) {
+          newFilter = currentOp.getChildren().get(0);
+          for (OpState opState : opStack) {
+            if (opState.getOp().getKind() == SqlKind.NOT) {
+              //AND under NOT should not get pushed
+              newFilter = null;
+            }
+          }
+
+        }
       } else {
         newFilter = builder.makeCall(currentOp.getOp(), 
currentOp.getChildren());
       }
@@ -228,13 +236,16 @@ public class FindPartitionConditions extends 
RexVisitorImpl<Void> {
     return false;
   }
 
+  protected boolean inputRefToPush(RexInputRef inputRef) {
+    return dirs.get(inputRef.getIndex());
+  }
+
   public Void visitInputRef(RexInputRef inputRef) {
-    if(dirs.get(inputRef.getIndex())){
+    if (inputRefToPush(inputRef)) {
       pushStatusStack.add(PushDirFilter.PUSH);
       addResult(inputRef);
       referencedDirs.set(inputRef.getIndex());
-
-    }else{
+    } else {
       pushStatusStack.add(PushDirFilter.NO_PUSH);
     }
     return null;

http://git-wip-us.apache.org/repos/asf/drill/blob/ef0fafea/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/FilterSplitTest.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/FilterSplitTest.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/FilterSplitTest.java
index 5ca071e..f95f2e7 100644
--- 
a/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/FilterSplitTest.java
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/FilterSplitTest.java
@@ -24,7 +24,6 @@ import java.util.BitSet;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
 
-import org.apache.drill.categories.PlannerTest;
 import org.apache.drill.exec.planner.logical.partition.FindPartitionConditions;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexBuilder;
@@ -32,9 +31,7 @@ import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.junit.Test;
-import org.junit.experimental.categories.Category;
 
-@Category(PlannerTest.class)
 public class FilterSplitTest {
   static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(FilterSplitTest.class);
 
@@ -91,6 +88,68 @@ public class FilterSplitTest {
   }
 
   @Test
+  public void AndOrMix() {
+    // b = 3 OR dir0 = 1 and a = 2
+    RexNode n = or(
+        eq(c(2), lit(3)),
+        and(
+            eq(c(0), lit(1)),
+            eq(c(1), lit(2))
+        )
+    );
+
+    BitSet bs = new BitSet();
+    bs.set(0);
+    FindPartitionConditions c = new FindPartitionConditions(bs, builder);
+    c.analyze(n);
+
+    RexNode partNode = c.getFinalCondition();
+    assertEquals("OR(=($2, 3), AND(=($0, 1), =($1, 2)))", n.toString());
+    assertEquals(null, partNode);
+  }
+
+
+  @Test
+  public void NotOnAnd() {
+    // not (dir0 = 1 AND b = 2)
+    RexNode n = not(
+        and (
+            eq(c(0), lit(1)),
+            eq(c(1), lit(2))
+        )
+    );
+
+    BitSet bs = new BitSet();
+    bs.set(0);
+    FindPartitionConditions c = new FindPartitionConditions(bs, builder);
+    c.analyze(n);
+
+    RexNode partNode = c.getFinalCondition();
+    assertEquals("NOT(AND(=($0, 1), =($1, 2)))", n.toString());
+    assertEquals(null, partNode);
+  }
+
+  @Test
+  public void AndNot() {
+    // (not dir0 = 1) AND b = 2)
+    RexNode n = and(
+        not(
+            eq(c(0), lit(1))
+        ),
+        eq(c(1), lit(2))
+    );
+
+    BitSet bs = new BitSet();
+    bs.set(0);
+    FindPartitionConditions c = new FindPartitionConditions(bs, builder);
+    c.analyze(n);
+
+    RexNode partNode = c.getFinalCondition();
+    assertEquals("AND(NOT(=($0, 1)), =($1, 2))", n.toString());
+    assertEquals("NOT(=($0, 1))", partNode.toString());
+  }
+
+  @Test
   public void badOr() {
     // (dir0 = 1 and dir1 = 2) OR (a < 5)
     RexNode n = or(
@@ -146,6 +205,10 @@ public class FilterSplitTest {
     return builder.makeCall(SqlStdOperatorTable.OR, nodes);
   }
 
+  private RexNode not(RexNode...nodes){
+    return builder.makeCall(SqlStdOperatorTable.NOT, nodes);
+  }
+
   private RexNode lt(RexNode left, RexNode right){
     return builder.makeCall(SqlStdOperatorTable.LESS_THAN, left, right);
   }

Reply via email to