Repository: drill Updated Branches: refs/heads/master 79a3c164c -> 7e6de2bbc
DRILL-4531: Add a Drill customized rule for pushing filter past aggregate Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/7e6de2bb Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/7e6de2bb Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/7e6de2bb Branch: refs/heads/master Commit: 7e6de2bbceffdb2566c57590da04113221f0a166 Parents: 79a3c16 Author: Jinfeng Ni <j...@apache.org> Authored: Tue Mar 22 17:57:02 2016 -0700 Committer: Jinfeng Ni <j...@apache.org> Committed: Thu Mar 24 15:22:12 2016 -0700 ---------------------------------------------------------------------- .../apache/drill/exec/planner/PlannerPhase.java | 3 +- .../DrillFilterAggregateTransposeRule.java | 48 ++++++++++++++++++++ .../exec/fn/impl/TestAggregateFunctions.java | 34 ++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/7e6de2bb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/PlannerPhase.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/PlannerPhase.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/PlannerPhase.java index 57f2984..2875bcf 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/PlannerPhase.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/PlannerPhase.java @@ -42,6 +42,7 @@ import org.apache.calcite.tools.RuleSet; import org.apache.calcite.tools.RuleSets; import org.apache.drill.exec.ops.OptimizerRulesContext; import org.apache.drill.exec.planner.logical.DrillAggregateRule; +import org.apache.drill.exec.planner.logical.DrillFilterAggregateTransposeRule; import org.apache.drill.exec.planner.logical.DrillFilterJoinRules; import org.apache.drill.exec.planner.logical.DrillFilterRule; import org.apache.drill.exec.planner.logical.DrillJoinRel; @@ -253,7 +254,7 @@ public enum PlannerPhase { DrillPushFilterPastProjectRule.INSTANCE, // Due to infinite loop in planning (DRILL-3257), temporarily disable this rule //FilterSetOpTransposeRule.INSTANCE, - FilterAggregateTransposeRule.INSTANCE, + DrillFilterAggregateTransposeRule.INSTANCE, FilterMergeRule.INSTANCE, AggregateRemoveRule.INSTANCE, http://git-wip-us.apache.org/repos/asf/drill/blob/7e6de2bb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterAggregateTransposeRule.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterAggregateTransposeRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterAggregateTransposeRule.java new file mode 100644 index 0000000..9d5e444 --- /dev/null +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterAggregateTransposeRule.java @@ -0,0 +1,48 @@ +/** + * 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; + +import org.apache.calcite.plan.Contexts; +import org.apache.calcite.plan.ConventionTraitDef; +import org.apache.calcite.plan.RelOptRuleCall; +import org.apache.calcite.rel.core.Aggregate; +import org.apache.calcite.rel.core.Filter; +import org.apache.calcite.rel.core.RelFactories; +import org.apache.calcite.rel.rules.FilterAggregateTransposeRule; +import org.apache.calcite.tools.RelBuilder; + +public class DrillFilterAggregateTransposeRule extends FilterAggregateTransposeRule{ + + // Since Calcite's default FilterAggregateTransposeRule would match Filter on top of Aggregate, it potentially will match Rels with mixed CONVENTION trait. + // Here override match method, such that the rule matchs with Rel in the same CONVENTION. + + public static final FilterAggregateTransposeRule INSTANCE = new DrillFilterAggregateTransposeRule(); + + private DrillFilterAggregateTransposeRule() { + super(Filter.class, RelBuilder.proto(Contexts.of(RelFactories.DEFAULT_FILTER_FACTORY)), Aggregate.class); + } + + @Override + public boolean matches(RelOptRuleCall call) { + final Filter filter = (Filter) call.rel(0); + final Aggregate aggregate = (Aggregate) call.rel(1); + return filter.getTraitSet().getTrait(ConventionTraitDef.INSTANCE) == aggregate.getTraitSet().getTrait(ConventionTraitDef.INSTANCE); + } + +} http://git-wip-us.apache.org/repos/asf/drill/blob/7e6de2bb/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunctions.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunctions.java index 4d44398..0e558a7 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunctions.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestAggregateFunctions.java @@ -491,4 +491,38 @@ public class TestAggregateFunctions extends BaseTestQuery { .build() .run(); } + + + @Test // DRILL-4531 + public void testPushFilterDown() throws Exception { + final String sql = + "SELECT cust.custAddress, \n" + + " lineitem.provider \n" + + "FROM ( \n" + + " SELECT cast(c_custkey AS bigint) AS custkey, \n" + + " c_address AS custAddress \n" + + " FROM cp.`tpch/customer.parquet` ) cust \n" + + "LEFT JOIN \n" + + " ( \n" + + " SELECT DISTINCT l_linenumber, \n" + + " CASE \n" + + " WHEN l_partkey IN (1, 2) THEN 'Store1'\n" + + " WHEN l_partkey IN (5, 6) THEN 'Store2'\n" + + " END AS provider \n" + + " FROM cp.`tpch/lineitem.parquet` \n" + + " WHERE ( l_orderkey >=20160101 AND l_partkey <=20160301) \n" + + " AND l_partkey IN (1,2, 5, 6) ) lineitem\n" + + "ON cust.custkey = lineitem.l_linenumber \n" + + "WHERE provider IS NOT NULL \n" + + "GROUP BY cust.custAddress, \n" + + " lineitem.provider \n" + + "ORDER BY cust.custAddress, \n" + + " lineitem.provider"; + + // Validate the plan + final String[] expectedPlan = {"(?s)(Join).*inner"}; // With filter pushdown, left join will be converted into inner join + final String[] excludedPatterns = {"(?s)(Join).*(left)"}; + PlanTestBase.testPlanMatchingPatterns(sql, expectedPlan, excludedPatterns); + } + }