diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveFilterMergeRule.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveFilterMergeRule.java new file mode 100644 index 0000000..b173d42 --- /dev/null +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveFilterMergeRule.java @@ -0,0 +1,80 @@ +/** + * 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.hadoop.hive.ql.optimizer.calcite.rules; + +import org.apache.calcite.plan.RelOptRuleCall; +import org.apache.calcite.rel.core.Filter; +import org.apache.calcite.rel.rules.FilterMergeRule; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexNode; +import org.apache.calcite.rex.RexProgram; +import org.apache.calcite.rex.RexProgramBuilder; +import org.apache.calcite.rex.RexUtil; +import org.apache.calcite.tools.RelBuilder; +import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter; + +public class HiveFilterMergeRule extends FilterMergeRule { + public static final HiveFilterMergeRule INSTANCE = new HiveFilterMergeRule(); + + public HiveFilterMergeRule() { + super(HiveFilter.DEFAULT_FILTER_FACTORY); + } + + public void onMatch(RelOptRuleCall call) { + final Filter topFilter = call.rel(0); + final Filter bottomFilter = call.rel(1); + + // use RexPrograms to merge the two FilterRels into a single program + // so we can convert the two LogicalFilter conditions to directly + // reference the bottom LogicalFilter's child + RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder(); + RexProgram bottomProgram = createProgram(bottomFilter); + RexProgram topProgram = createProgram(topFilter); + + RexProgram mergedProgram = + RexProgramBuilder.mergePrograms( + topProgram, + bottomProgram, + rexBuilder); + + RexNode newCondition = RexUtil.simplify(rexBuilder, + mergedProgram.expandLocalRef(mergedProgram.getCondition())); + + final RelBuilder relBuilder = call.builder(); + relBuilder.push(bottomFilter.getInput()) + .filter(newCondition); + + call.transformTo(relBuilder.build()); + } + + /** + * Creates a RexProgram corresponding to a LogicalFilter + * + * @param filterRel the LogicalFilter + * @return created RexProgram + */ + private RexProgram createProgram(Filter filterRel) { + RexProgramBuilder programBuilder = + new RexProgramBuilder( + filterRel.getRowType(), + filterRel.getCluster().getRexBuilder()); + programBuilder.addIdentity(); + programBuilder.addCondition(filterRel.getCondition()); + return programBuilder.getProgram(); + } +} diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java index 2a415d5..e0d395f 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -32,10 +33,8 @@ import org.apache.calcite.rel.core.RelFactories.FilterFactory; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexBuilder; -import org.apache.calcite.rex.RexCall; import org.apache.calcite.rex.RexNode; import org.apache.calcite.rex.RexUtil; -import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.type.SqlTypeName; import org.apache.hadoop.hive.ql.exec.FunctionRegistry; @@ -46,11 +45,16 @@ import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter; import org.apache.hadoop.hive.ql.optimizer.calcite.translator.SqlFunctionConverter; import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; public final class HiveJoinAddNotNullRule extends RelOptRule { + private static final Logger LOG = LoggerFactory.getLogger(HiveJoinAddNotNullRule.class); + private static final String NOT_NULL_FUNC_NAME = "isnotnull"; /** The singleton. */ @@ -74,10 +78,29 @@ public HiveJoinAddNotNullRule(FilterFactory filterFactory) { //~ Methods ---------------------------------------------------------------- @Override + public boolean matches(RelOptRuleCall call) { + final Join join = call.rel(0); + + HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); + + // If this operator has been visited already by the rule, + // we do not need to apply the optimization + if (registry != null && registry.isVisited(this, join)) { + return false; + } + + return true; + } + + @Override public void onMatch(RelOptRuleCall call) { final Join join = call.rel(0); - RelNode leftInput = call.rel(1); - RelNode rightInput = call.rel(2); + + // Register that we have visited this operator in this rule + HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); + if (registry != null) { + registry.registerVisited(this, join); + } if (join.getJoinType() != JoinRelType.INNER) { return; @@ -107,54 +130,49 @@ public void onMatch(RelOptRuleCall call) { final RelOptCluster cluster = join.getCluster(); final RexBuilder rexBuilder = join.getCluster().getRexBuilder(); - final Map newLeftConditions = getNotNullConditions(cluster, - rexBuilder, leftInput, joinLeftKeyPositions); - final Map newRightConditions = getNotNullConditions(cluster, - rexBuilder, rightInput, joinRightKeyPositions); + final List newLeftConditions = getNotNullConditions(cluster, + rexBuilder, join.getLeft(), joinLeftKeyPositions); + final List newRightConditions = getNotNullConditions(cluster, + rexBuilder, join.getRight(), joinRightKeyPositions); // Nothing will be added to the expression - if (newLeftConditions == null && newRightConditions == null) { + if (newLeftConditions.isEmpty() && newRightConditions.isEmpty()) { return; } - if (newLeftConditions != null) { - if (leftInput instanceof HiveFilter) { - leftInput = leftInput.getInput(0); - } - leftInput = createHiveFilterConjunctiveCondition(filterFactory, rexBuilder, - leftInput, newLeftConditions.values()); + RelNode newLeftInput; + if (!newLeftConditions.isEmpty()) { + newLeftInput = createHiveFilterConjunctiveCondition(filterFactory, rexBuilder, + join.getLeft(), newLeftConditions); + } else { + newLeftInput = join.getLeft(); } - if (newRightConditions != null) { - if (rightInput instanceof HiveFilter) { - rightInput = rightInput.getInput(0); - } - rightInput = createHiveFilterConjunctiveCondition(filterFactory, rexBuilder, - rightInput, newRightConditions.values()); + RelNode newRightInput; + if (!newRightConditions.isEmpty()) { + newRightInput = createHiveFilterConjunctiveCondition(filterFactory, rexBuilder, + join.getRight(), newRightConditions); + } else { + newRightInput = join.getRight(); } Join newJoin = join.copy(join.getTraitSet(), join.getCondition(), - leftInput, rightInput, join.getJoinType(), join.isSemiJoinDone()); + newLeftInput, newRightInput, join.getJoinType(), join.isSemiJoinDone()); - call.getPlanner().onCopy(join, newJoin); + // We register the new join so we do not fire the rule on it again + if (registry != null) { + registry.registerVisited(this, newJoin); + } call.transformTo(newJoin); } - private static Map getNotNullConditions(RelOptCluster cluster, + private static List getNotNullConditions(RelOptCluster cluster, RexBuilder rexBuilder, RelNode input, Set inputKeyPositions) { - boolean added = false; - final RelDataType returnType = cluster.getTypeFactory(). createSqlType(SqlTypeName.BOOLEAN); - final Map newConditions; - if (input instanceof HiveFilter) { - newConditions = splitCondition(((HiveFilter) input).getCondition()); - } - else { - newConditions = new HashMap(); - } + final Map newConditions = new HashMap(); for (int pos : inputKeyPositions) { try { RelDataType keyType = input.getRowType().getFieldList().get(pos).getType(); @@ -166,33 +184,12 @@ public void onMatch(RelOptRuleCall call) { FunctionRegistry.getFunctionInfo(NOT_NULL_FUNC_NAME).getGenericUDF(), ImmutableList.of(keyType), returnType); RexNode cond = rexBuilder.makeCall(funcCall, rexBuilder.makeInputRef(input, pos)); - String digest = cond.toString(); - if (!newConditions.containsKey(digest)) { - newConditions.put(digest,cond); - added = true; - } + newConditions.put(cond.toString(),cond); } catch (SemanticException e) { throw new AssertionError(e.getMessage()); } } - // Nothing will be added to the expression - if (!added) { - return null; - } - return newConditions; - } - - private static Map splitCondition(RexNode condition) { - Map newConditions = new HashMap(); - if (condition.getKind() == SqlKind.AND) { - for (RexNode node : ((RexCall) condition).getOperands()) { - newConditions.put(node.toString(), node); - } - } - else { - newConditions.put(condition.toString(), condition); - } - return newConditions; + return HiveCalciteUtil.getPredsNotPushedAlready(input, Lists.newArrayList(newConditions.values())); } private static RelNode createHiveFilterConjunctiveCondition(FilterFactory filterFactory, diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinPushTransitivePredicatesRule.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinPushTransitivePredicatesRule.java index 703c8c6..395da0e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinPushTransitivePredicatesRule.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinPushTransitivePredicatesRule.java @@ -23,6 +23,7 @@ import org.apache.calcite.plan.RelOptPredicateList; import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; +import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Join; import org.apache.calcite.rel.core.RelFactories; @@ -40,8 +41,11 @@ import org.apache.hadoop.hive.ql.optimizer.calcite.HiveCalciteUtil; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotNull; import org.apache.hive.common.util.AnnotationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; /** * Planner rule that infers predicates from on a @@ -55,6 +59,9 @@ * and applies them appropriately. */ public class HiveJoinPushTransitivePredicatesRule extends RelOptRule { + + private static final Logger LOG = LoggerFactory.getLogger(HiveJoinPushTransitivePredicatesRule.class); + private final RelFactories.FilterFactory filterFactory; /** The singleton. */ @@ -69,6 +76,20 @@ public HiveJoinPushTransitivePredicatesRule(Class clazz, this.filterFactory = filterFactory; } + @Override + public boolean matches(RelOptRuleCall call) { + final Join join = call.rel(0); + + // If this operator has been visited already by the rule, + // we do not need to apply the optimization + HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); + if (registry != null && registry.isVisited(this, join)) { + return false; + } + + return true; + } + @Override public void onMatch(RelOptRuleCall call) { Join join = call.rel(0); diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePreFilteringRule.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePreFilteringRule.java index 79a627c..800185f 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePreFilteringRule.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePreFilteringRule.java @@ -37,10 +37,10 @@ import org.apache.calcite.rex.RexNode; import org.apache.calcite.rex.RexUtil; import org.apache.calcite.sql.SqlKind; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.hadoop.hive.ql.optimizer.calcite.HiveCalciteUtil; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.LinkedHashMultimap; @@ -79,11 +79,10 @@ public boolean matches(RelOptRuleCall call) { return false; } - HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); - // If this operator has been visited already by the rule, // we do not need to apply the optimization - if (registry != null && registry.getVisited(this).contains(filter)) { + HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); + if (registry != null && registry.isVisited(this, filter)) { return false; } diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRulesRegistry.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRulesRegistry.java index 18a065e..d5e53ad 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRulesRegistry.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRulesRegistry.java @@ -17,28 +17,58 @@ */ package org.apache.hadoop.hive.ql.optimizer.calcite.rules; +import java.util.Map; import java.util.Set; import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rex.RexNode; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; public class HiveRulesRegistry { - private SetMultimap registry; + private SetMultimap registryVisited; + private Map>> registryVisitedPredicate; public HiveRulesRegistry() { - this.registry = HashMultimap.create(); + this.registryVisited = HashMultimap.create(); + this.registryVisitedPredicate = Maps.newHashMap(); } public void registerVisited(RelOptRule rule, RelNode operator) { - this.registry.put(rule, operator); + this.registryVisited.put(rule, operator); } - public Set getVisited(RelOptRule rule) { - return this.registry.get(rule); + public boolean isVisited(RelOptRule rule, RelNode operator) { + return this.registryVisited.get(rule).contains(operator); + } + + public void registerVisitedPredicate(RelOptRule rule, RelNode operator, int pos, RexNode predicate) { + if (!this.registryVisitedPredicate.containsKey(rule)) { + this.registryVisitedPredicate.put(rule, ArrayListMultimap.>create()); + } + if (!this.registryVisitedPredicate.get(rule).containsKey(operator)) { + for (int i = 0; i < operator.getInputs().size(); i++) { + this.registryVisitedPredicate.get(rule).get(operator).add(Sets.newHashSet()); + } + } + this.registryVisitedPredicate.get(rule).get(operator).get(pos).add(predicate.toString()); + } + + public boolean isVisitedPredicate(RelOptRule rule, RelNode operator, int pos, RexNode predicate) { + if (!this.registryVisitedPredicate.containsKey(rule)) { + return false; + } + if (!this.registryVisitedPredicate.get(rule).containsKey(operator)) { + return false; + } + return this.registryVisitedPredicate.get(rule).get(operator).get(pos).contains(predicate.toString()); } } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index a0d14dc..8538785 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -63,7 +63,6 @@ import org.apache.calcite.rel.metadata.CachingRelMetadataProvider; import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider; import org.apache.calcite.rel.metadata.RelMetadataProvider; -import org.apache.calcite.rel.rules.FilterMergeRule; import org.apache.calcite.rel.rules.JoinToMultiJoinRule; import org.apache.calcite.rel.rules.LoptOptimizeJoinRule; import org.apache.calcite.rel.rules.ProjectMergeRule; @@ -138,6 +137,7 @@ import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveExpandDistinctAggregatesRule; import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterAggregateTransposeRule; import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterJoinRule; +import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterMergeRule; import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterProjectTSTransposeRule; import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterProjectTransposeRule; import org.apache.hadoop.hive.ql.optimizer.calcite.rules.HiveFilterSetOpTransposeRule; @@ -1032,29 +1032,25 @@ private RelNode applyPreJoinOrderingTransforms(RelNode basePlan, RelMetadataProv basePlan = hepPlan(basePlan, false, mdProvider, HepMatchOrder.ARBITRARY, HivePreFilteringRule.INSTANCE); - // 3. PPD for old Join Syntax + // 3. PPD for old Join Syntax, transitive inference, constant prop, + // predicate push down, add not null filters // NOTE: PPD needs to run before adding not null filters in order to // support old style join syntax (so that on-clauses will get filled up). // TODO: Add in ReduceExpressionrules (Constant folding) to below once // HIVE-11927 is fixed. - basePlan = hepPlan(basePlan, true, mdProvider, new HiveFilterProjectTransposeRule( - Filter.class, HiveFilter.DEFAULT_FILTER_FACTORY, HiveProject.class, - HiveProject.DEFAULT_PROJECT_FACTORY), new HiveFilterSetOpTransposeRule( - HiveFilter.DEFAULT_FILTER_FACTORY), HiveFilterJoinRule.JOIN, - HiveFilterJoinRule.FILTER_ON_JOIN, new HiveFilterAggregateTransposeRule(Filter.class, - HiveFilter.DEFAULT_FILTER_FACTORY, Aggregate.class), new FilterMergeRule( - HiveFilter.DEFAULT_FILTER_FACTORY)); - - // TODO: Transitive inference, constant prop & Predicate push down has to - // do multiple passes till no more inference is left - // Currently doing so would result in a spin. Just checking for if inferred - // pred is present below may not be sufficient as inferred & pushed pred - // could have been mutated by constant folding/prop - // 4. Transitive inference for join on clauses - basePlan = hepPlan(basePlan, true, mdProvider, new HiveJoinPushTransitivePredicatesRule( - Join.class, HiveFilter.DEFAULT_FILTER_FACTORY)); - - // 5. Push down limit through outer join + basePlan = hepPlan(basePlan, true, mdProvider, HepMatchOrder.TOP_DOWN, + new HiveFilterProjectTransposeRule(Filter.class, HiveFilter.DEFAULT_FILTER_FACTORY, + HiveProject.class, HiveProject.DEFAULT_PROJECT_FACTORY), + new HiveFilterSetOpTransposeRule(HiveFilter.DEFAULT_FILTER_FACTORY), + HiveFilterJoinRule.JOIN, + HiveFilterJoinRule.FILTER_ON_JOIN, + new HiveFilterAggregateTransposeRule(Filter.class, HiveFilter.DEFAULT_FILTER_FACTORY, + Aggregate.class), + HiveFilterMergeRule.INSTANCE, + new HiveJoinPushTransitivePredicatesRule(Join.class, HiveFilter.DEFAULT_FILTER_FACTORY), + new HiveJoinAddNotNullRule(HiveFilter.DEFAULT_FILTER_FACTORY)); + + // 4. Push down limit through outer join // NOTE: We run this after PPD to support old style join syntax. // Ex: select * from R1 left outer join R2 where ((R1.x=R2.x) and R1.y<10) or // ((R1.x=R2.x) and R1.z=10)) and rand(1) < 0.1 order by R1.x limit 10 @@ -1072,28 +1068,14 @@ private RelNode applyPreJoinOrderingTransforms(RelNode basePlan, RelMetadataProv HiveProjectSortTransposeRule.INSTANCE); } - // 6. Add not null filters - basePlan = hepPlan(basePlan, true, mdProvider, HiveJoinAddNotNullRule.INSTANCE); - - // 7. Rerun Constant propagation and PPD now that we have added Not NULL filters & did transitive inference - // TODO: Add in ReduceExpressionrules (Constant folding) to below once - // HIVE-11927 is fixed. - basePlan = hepPlan(basePlan, true, mdProvider, new HiveFilterProjectTransposeRule( - Filter.class, HiveFilter.DEFAULT_FILTER_FACTORY, HiveProject.class, - HiveProject.DEFAULT_PROJECT_FACTORY), new HiveFilterSetOpTransposeRule( - HiveFilter.DEFAULT_FILTER_FACTORY), HiveFilterJoinRule.JOIN, - HiveFilterJoinRule.FILTER_ON_JOIN, new HiveFilterAggregateTransposeRule(Filter.class, - HiveFilter.DEFAULT_FILTER_FACTORY, Aggregate.class), new FilterMergeRule( - HiveFilter.DEFAULT_FILTER_FACTORY)); - - // 8. Push Down Semi Joins + // 5. Push Down Semi Joins basePlan = hepPlan(basePlan, true, mdProvider, SemiJoinJoinTransposeRule.INSTANCE, SemiJoinFilterTransposeRule.INSTANCE, SemiJoinProjectTransposeRule.INSTANCE); - // 9. Apply Partition Pruning + // 6. Apply Partition Pruning basePlan = hepPlan(basePlan, false, mdProvider, new HivePartitionPruneRule(conf)); - // 10. Projection Pruning (this introduces select above TS & hence needs to be run last due to PP) + // 7. Projection Pruning (this introduces select above TS & hence needs to be run last due to PP) HiveRelFieldTrimmer fieldTrimmer = new HiveRelFieldTrimmer(null, cluster, HiveProject.DEFAULT_PROJECT_FACTORY, HiveFilter.DEFAULT_FILTER_FACTORY, HiveJoin.HIVE_JOIN_FACTORY, @@ -1101,12 +1083,11 @@ private RelNode applyPreJoinOrderingTransforms(RelNode basePlan, RelMetadataProv HiveAggregate.HIVE_AGGR_REL_FACTORY, HiveUnion.UNION_REL_FACTORY); basePlan = fieldTrimmer.trim(basePlan); - - // 11. Merge Project-Project if possible + // 8. Merge Project-Project if possible basePlan = hepPlan(basePlan, false, mdProvider, new ProjectMergeRule(true, HiveProject.DEFAULT_PROJECT_FACTORY)); - // 12. Rerun PPD through Project as column pruning would have introduced + // 9. Rerun PPD through Project as column pruning would have introduced // DT above scans; By pushing filter just above TS, Hive can push it into // storage (incase there are filters on non partition cols). This only // matches FIL-PROJ-TS diff --git ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/TestCBORuleFiredOnlyOnce.java ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/TestCBORuleFiredOnlyOnce.java index f1d8d1d..609581b 100644 --- ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/TestCBORuleFiredOnlyOnce.java +++ ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/TestCBORuleFiredOnlyOnce.java @@ -115,7 +115,7 @@ public boolean matches(RelOptRuleCall call) { // If this operator has been visited already by the rule, // we do not need to apply the optimization - if (registry != null && registry.getVisited(this).contains(node)) { + if (registry != null && registry.isVisited(this, node)) { return false; }