Repository: drill Updated Branches: refs/heads/master a915085e8 -> c1998605d
DRILL-3410: Recombine binary operators after finding prune condition This is to expression reordering and short-circuit evaluation Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/c1998605 Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/c1998605 Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/c1998605 Branch: refs/heads/master Commit: c1998605dc2acdc5fa55792a279a473ff890a010 Parents: a915085 Author: Steven Phillips <[email protected]> Authored: Sun Jun 28 11:05:32 2015 -0700 Committer: Steven Phillips <[email protected]> Committed: Mon Jun 29 01:22:41 2015 -0700 ---------------------------------------------------------------------- .../logical/partition/PruneScanRule.java | 7 ++ .../RewriteCombineBinaryOperators.java | 110 +++++++++++++++++++ 2 files changed, 117 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/c1998605/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/PruneScanRule.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/PruneScanRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/PruneScanRule.java index 869348a..5b5e4bc 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/PruneScanRule.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/PruneScanRule.java @@ -371,6 +371,7 @@ public abstract class PruneScanRule extends RelOptRule { return; } + // set up the partitions final GroupScan groupScan = scanRel.getGroupScan(); final FormatSelection origSelection = (FormatSelection)scanRel.getDrillTable().getSelection(); @@ -440,11 +441,17 @@ public abstract class PruneScanRule extends RelOptRule { logger.debug("Pruned {} => {}", files, newFiles); + List<RexNode> conjuncts = RelOptUtil.conjunctions(condition); List<RexNode> pruneConjuncts = RelOptUtil.conjunctions(pruneCondition); conjuncts.removeAll(pruneConjuncts); RexNode newCondition = RexUtil.composeConjunction(filterRel.getCluster().getRexBuilder(), conjuncts, false); + RewriteCombineBinaryOperators reverseVisitor = new RewriteCombineBinaryOperators(true, filterRel.getCluster().getRexBuilder()); + + condition = condition.accept(reverseVisitor); + pruneCondition = pruneCondition.accept(reverseVisitor); + final FileSelection newFileSelection = new FileSelection(newFiles, selectionRoot, true); final FileGroupScan newScan = ((FileGroupScan)scanRel.getGroupScan()).clone(newFileSelection); final DrillScanRel newScanRel = http://git-wip-us.apache.org/repos/asf/drill/blob/c1998605/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/RewriteCombineBinaryOperators.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/RewriteCombineBinaryOperators.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/RewriteCombineBinaryOperators.java new file mode 100644 index 0000000..247ad8f --- /dev/null +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/partition/RewriteCombineBinaryOperators.java @@ -0,0 +1,110 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.drill.exec.planner.logical.partition; + +import com.google.common.collect.Lists; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexCall; +import org.apache.calcite.rex.RexCorrelVariable; +import org.apache.calcite.rex.RexDynamicParam; +import org.apache.calcite.rex.RexFieldAccess; +import org.apache.calcite.rex.RexInputRef; +import org.apache.calcite.rex.RexLiteral; +import org.apache.calcite.rex.RexNode; +import org.apache.calcite.rex.RexOver; +import org.apache.calcite.rex.RexRangeRef; +import org.apache.calcite.rex.RexUtil; +import org.apache.calcite.rex.RexVisitorImpl; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlOperator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Rewrites an expression tree, replacing chained OR and AND operators with a single N-ary operator + * + * e.g. + * + * OR(A, OR(B, C)) ---> OR(A, B, C) + */ + public class RewriteCombineBinaryOperators extends RexVisitorImpl<RexNode> { + + RexBuilder builder; + public RewriteCombineBinaryOperators(boolean deep, RexBuilder builder) { + super(deep); + this.builder = builder; + } + + @Override + public RexNode visitInputRef(RexInputRef inputRef) { + return inputRef; + } + + @Override + public RexNode visitLiteral(RexLiteral literal) { + return literal; + } + + @Override + public RexNode visitOver(RexOver over) { + return over; + } + + @Override + public RexNode visitCorrelVariable(RexCorrelVariable correlVariable) { + return correlVariable; + } + + @Override + public RexNode visitCall(RexCall call) { + SqlOperator op = call.getOperator(); + SqlKind kind = op.getKind(); + if (kind == SqlKind.AND) { + List<RexNode> conjuncts = Lists.newArrayList(); + for (RexNode child : call.getOperands()) { + conjuncts.addAll(RelOptUtil.conjunctions(child.accept(this))); + } + return RexUtil.composeConjunction(builder, conjuncts, true); + } + if (kind == SqlKind.OR) { + List<RexNode> disjuncts = Lists.newArrayList(); + for (RexNode child : call.getOperands()) { + disjuncts.addAll(RelOptUtil.disjunctions(child.accept(this))); + } + return RexUtil.composeDisjunction(builder, disjuncts, true); + } + return call; + } + + @Override + public RexNode visitDynamicParam(RexDynamicParam dynamicParam) { + return dynamicParam; + } + + @Override + public RexNode visitRangeRef(RexRangeRef rangeRef) { + return rangeRef; + } + + @Override + public RexNode visitFieldAccess(RexFieldAccess fieldAccess) { + return fieldAccess; + } +}
