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); }
