private boolean isAggWithConstantGbyKeys(final Aggregate aggregate, RelOptRuleCall call) { final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder(); final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(aggregate.getInput()); if (predicates == null) { return false; } final NavigableMap<Integer, RexNode> map = new TreeMap<>(); for (int key : aggregate.getGroupSet()) { final RexInputRef ref = rexBuilder.makeInputRef(aggregate.getInput(), key); if (predicates.constantMap.containsKey(ref)) { map.put(key, predicates.constantMap.get(ref)); } } // None of the group expressions are constant. Nothing to do. if (map.isEmpty()) { return false; } final int groupCount = aggregate.getGroupCount(); if (groupCount == map.size()) { return true; } return false; }
@Override public boolean matches(RelOptRuleCall call) { final HiveSortLimit sortLimit = call.rel(0); // If it is not created by HiveSortJoinReduceRule, we cannot remove it if (!sortLimit.isRuleCreated()) { return false; } // Finally, if we do not reduce the size input enough, we bail out int limit = RexLiteral.intValue(sortLimit.fetch); Double rowCount = call.getMetadataQuery().getRowCount(sortLimit.getInput()); if (rowCount != null && limit <= reductionProportion * rowCount && rowCount - limit >= reductionTuples) { return false; } return true; }
final RelMetadataQuery mq = call.getMetadataQuery(); if ((nonDistinctCount == 0) && (argListSets.size() == 1)) { for (Integer arg : argListSets.iterator().next()) {
final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(union); if (predicates == null) {
final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(sort.getInput()); if (predicates == null) {
@Override public void onMatch(RelOptRuleCall call) { final Filter filter = call.rel(0); final RexBuilder rexBuilder = filter.getCluster().getRexBuilder(); final RelMetadataQuery metadataProvider = call.getMetadataQuery(); // 1. Recompose filter possibly by pulling out common elements from DNF // expressions RexNode newFilterCondition = RexUtil.pullFactors(rexBuilder, filter.getCondition()); // 2. Reduce filter with stats information RexReplacer replacer = new RexReplacer(filter, rexBuilder, metadataProvider); newFilterCondition = replacer.apply(newFilterCondition); // 3. Transform if we have created a new filter operator if (!filter.getCondition().toString().equals(newFilterCondition.toString())) { Filter newFilter = filter.copy(filter.getTraitSet(), filter.getInput(), newFilterCondition); call.transformTo(newFilter); } }
origFields, input.getRowType().getFieldList(), adjustments)); if (setOp instanceof Union && setOp.all) { final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(input); if (predicates != null) {
for (RelNode input : union.getInputs()) { if (RexLiteral.intValue(sort.fetch) + offset < call.getMetadataQuery().getRowCount(input)) { finishPushSortPastUnion = false;
final RelMetadataQuery mq = call.getMetadataQuery(); if (!RelMdUtil.areColumnsDefinitelyUniqueWhenNullsFiltered(mq, left, correlatedInputRefJoinKeys)) { final RelMetadataQuery mq = call.getMetadataQuery(); if (!RelMdUtil.areColumnsDefinitelyUnique(mq, left, allCols)) {
RexNode newConditionExp; boolean reduced; final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(filter.getInput());
final RelMetadataQuery mq = call.getMetadataQuery(); if (!RelMdUtil.areColumnsDefinitelyUniqueWhenNullsFiltered(mq, right, rightJoinKeys)) {
final RelMetadataQuery mq = call.getMetadataQuery(); final ImmutableBitSet keyColumns = keyColumns(aggregateColumns, mq.getPulledUpPredicates(join).pulledUpPredicates);
join, leftInput == fkInput, call.getMetadataQuery());
Join join = call.rel(0); RelOptPredicateList preds = call.getMetadataQuery().getPulledUpPredicates(join);
final RelMetadataQuery mq = call.getMetadataQuery(); if (offset + RexLiteral.intValue(sortLimit.fetch) >= mq.getRowCount(reducedInput)) {
protected static boolean isSingleton(RelOptRuleCall call) { PlannerSettings settings = PrelUtil.getPlannerSettings(call.getPlanner()); if (settings.isSingleMode()) { return true; } RelNode child = call.rel(0).getInputs().get(0); // if small input, then singleton return call.getMetadataQuery().getRowCount(child) < settings.getSliceTarget(); }
@Override public boolean matches(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelNode input = call.rel(1); if (aggregate.getGroupCount() == 0 || aggregate.indicator || aggregate.getGroupType() != Aggregate.Group.SIMPLE) { return false; } for (AggregateCall aggCall : aggregate.getAggCallList()) { SqlKind aggCallKind = aggCall.getAggregation().getKind(); // TODO supports more AggregateCalls boolean isAllowAggCall = aggCallKind == SqlKind.SUM || aggCallKind == SqlKind.MIN || aggCallKind == SqlKind.MAX || aggCall.getAggregation() instanceof SqlAuxiliaryGroupAggFunction$; if (!isAllowAggCall || aggCall.filterArg >= 0 || aggCall.getArgList().size() != 1) { return false; } } final RelMetadataQuery mq = call.getMetadataQuery(); return SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet())); }
@Override public void onMatch(RelOptRuleCall call) { final Project project = call.rel(0); final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(project.getInput()); final List<RexNode> expList = Lists.newArrayList(project.getProjects()); if (reduceExpressions(project, expList, predicates, false, matchNullability)) { call.transformTo( call.builder() .push(project.getInput()) .project(expList, project.getRowType().getFieldNames()) .build()); // New plan is absolutely better than old plan. call.getPlanner().setImportance(project, 0.0); } } }
@Override public void onMatch(RelOptRuleCall call) { final Project project = call.rel(0); final RelMetadataQuery mq = call.getMetadataQuery(); final RelOptPredicateList predicates = mq.getPulledUpPredicates(project.getInput()); final List<RexNode> expList = Lists.newArrayList(project.getProjects()); if (reduceExpressions(project, expList, predicates, false, matchNullability)) { call.transformTo( call.builder() .push(project.getInput()) .project(expList, project.getRowType().getFieldNames()) .build()); // New plan is absolutely better than old plan. call.getPlanner().setImportance(project, 0.0); } } }
public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelNode input = call.rel(1); if (!aggregate.getAggCallList().isEmpty() || aggregate.indicator) { return; } final RelMetadataQuery mq = call.getMetadataQuery(); if (!SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet()))) { return; } // Distinct is "GROUP BY c1, c2" (where c1, c2 are a set of columns on // which the input is unique, i.e. contain a key) and has no aggregate // functions. It can be removed. final RelNode newInput = convert(input, aggregate.getTraitSet().simplify()); // If aggregate was projecting a subset of columns, add a project for the // same effect. final RelBuilder relBuilder = call.builder(); relBuilder.push(newInput); if (newInput.getRowType().getFieldCount() > aggregate.getRowType().getFieldCount()) { relBuilder.project(relBuilder.fields(aggregate.getGroupSet().asList())); } call.transformTo(relBuilder.build()); } }