Search in sources :

Example 1 with RelOptPredicateList

use of org.apache.calcite.plan.RelOptPredicateList in project hive by apache.

the class HiveRelMdPredicates method getPredicates.

/** Infers predicates for a {@link org.apache.calcite.rel.core.Join}. */
public RelOptPredicateList getPredicates(Join join, RelMetadataQuery mq) {
    RexBuilder rB = join.getCluster().getRexBuilder();
    RelNode left = join.getInput(0);
    RelNode right = join.getInput(1);
    final RelOptPredicateList leftInfo = mq.getPulledUpPredicates(left);
    final RelOptPredicateList rightInfo = mq.getPulledUpPredicates(right);
    JoinConditionBasedPredicateInference jI = new JoinConditionBasedPredicateInference(join, RexUtil.composeConjunction(rB, leftInfo.pulledUpPredicates, false), RexUtil.composeConjunction(rB, rightInfo.pulledUpPredicates, false));
    return jI.inferPredicates(false);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder)

Example 2 with RelOptPredicateList

use of org.apache.calcite.plan.RelOptPredicateList in project hive by apache.

the class HiveRelMdPredicates method getPredicates.

/**
   * Infers predicates for a Union.
   */
public RelOptPredicateList getPredicates(Union union, RelMetadataQuery mq) {
    RexBuilder rB = union.getCluster().getRexBuilder();
    Map<String, RexNode> finalPreds = new HashMap<>();
    List<RexNode> finalResidualPreds = new ArrayList<>();
    for (int i = 0; i < union.getInputs().size(); i++) {
        RelNode input = union.getInputs().get(i);
        RelOptPredicateList info = mq.getPulledUpPredicates(input);
        if (info.pulledUpPredicates.isEmpty()) {
            return RelOptPredicateList.EMPTY;
        }
        Map<String, RexNode> preds = new HashMap<>();
        List<RexNode> residualPreds = new ArrayList<>();
        for (RexNode pred : info.pulledUpPredicates) {
            final String predString = pred.toString();
            if (i == 0) {
                preds.put(predString, pred);
                continue;
            }
            if (finalPreds.containsKey(predString)) {
                preds.put(predString, pred);
            } else {
                residualPreds.add(pred);
            }
        }
        // Add new residual preds
        finalResidualPreds.add(RexUtil.composeConjunction(rB, residualPreds, false));
        // Add those that are not part of the final set to residual
        for (Entry<String, RexNode> e : finalPreds.entrySet()) {
            if (!preds.containsKey(e.getKey())) {
                // This node was in previous union inputs, but it is not in this one
                for (int j = 0; j < i; j++) {
                    finalResidualPreds.set(j, RexUtil.composeConjunction(rB, Lists.newArrayList(finalResidualPreds.get(j), e.getValue()), false));
                }
            }
        }
        // Final preds
        finalPreds = preds;
    }
    List<RexNode> preds = new ArrayList<>(finalPreds.values());
    RexNode disjPred = RexUtil.composeDisjunction(rB, finalResidualPreds, false);
    if (!disjPred.isAlwaysTrue()) {
        preds.add(disjPred);
    }
    return RelOptPredicateList.of(preds);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) HashMap(java.util.HashMap) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with RelOptPredicateList

use of org.apache.calcite.plan.RelOptPredicateList in project hive by apache.

the class HiveSortLimitPullUpConstantsRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final RelNode parent = call.rel(0);
    final Sort sort = call.rel(1);
    final int count = sort.getInput().getRowType().getFieldCount();
    if (count == 1) {
        // Project operator.
        return;
    }
    final RexBuilder rexBuilder = sort.getCluster().getRexBuilder();
    final RelMetadataQuery mq = RelMetadataQuery.instance();
    final RelOptPredicateList predicates = mq.getPulledUpPredicates(sort.getInput());
    if (predicates == null) {
        return;
    }
    Map<RexNode, RexNode> conditionsExtracted = HiveReduceExpressionsRule.predicateConstants(RexNode.class, rexBuilder, predicates);
    Map<RexNode, RexNode> constants = new HashMap<>();
    for (int i = 0; i < count; i++) {
        RexNode expr = rexBuilder.makeInputRef(sort.getInput(), i);
        if (conditionsExtracted.containsKey(expr)) {
            constants.put(expr, conditionsExtracted.get(expr));
        }
    }
    // None of the expressions are constant. Nothing to do.
    if (constants.isEmpty()) {
        return;
    }
    if (count == constants.size()) {
        // At least a single item in project is required.
        constants.remove(constants.keySet().iterator().next());
    }
    // Create expressions for Project operators before and after the Sort
    List<RelDataTypeField> fields = sort.getInput().getRowType().getFieldList();
    List<Pair<RexNode, String>> newChildExprs = new ArrayList<>();
    List<RexNode> topChildExprs = new ArrayList<>();
    List<String> topChildExprsFields = new ArrayList<>();
    for (int i = 0; i < count; i++) {
        RexNode expr = rexBuilder.makeInputRef(sort.getInput(), i);
        RelDataTypeField field = fields.get(i);
        if (constants.containsKey(expr)) {
            topChildExprs.add(constants.get(expr));
            topChildExprsFields.add(field.getName());
        } else {
            newChildExprs.add(Pair.<RexNode, String>of(expr, field.getName()));
            topChildExprs.add(expr);
            topChildExprsFields.add(field.getName());
        }
    }
    // Update field collations
    final Mappings.TargetMapping mapping = RelOptUtil.permutation(Pair.left(newChildExprs), sort.getInput().getRowType()).inverse();
    List<RelFieldCollation> fieldCollations = new ArrayList<>();
    for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
        final int target = mapping.getTargetOpt(fc.getFieldIndex());
        if (target < 0) {
            // It is a constant, we can ignore it
            continue;
        }
        fieldCollations.add(fc.copy(target));
    }
    // Update top Project positions
    topChildExprs = ImmutableList.copyOf(RexUtil.apply(mapping, topChildExprs));
    // Create new Project-Sort-Project sequence
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(sort.getInput());
    relBuilder.project(Pair.left(newChildExprs), Pair.right(newChildExprs));
    final ImmutableList<RexNode> sortFields = relBuilder.fields(RelCollations.of(fieldCollations));
    relBuilder.sortLimit(sort.offset == null ? -1 : RexLiteral.intValue(sort.offset), sort.fetch == null ? -1 : RexLiteral.intValue(sort.fetch), sortFields);
    // Create top Project fixing nullability of fields
    relBuilder.project(topChildExprs, topChildExprsFields);
    relBuilder.convert(sort.getRowType(), false);
    List<RelNode> inputs = new ArrayList<>();
    for (RelNode child : parent.getInputs()) {
        if (!((HepRelVertex) child).getCurrentRel().equals(sort)) {
            inputs.add(child);
        } else {
            inputs.add(relBuilder.build());
        }
    }
    call.transformTo(parent.copy(parent.getTraitSet(), inputs));
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) Sort(org.apache.calcite.rel.core.Sort) RexBuilder(org.apache.calcite.rex.RexBuilder) Pair(org.apache.calcite.util.Pair) RelBuilder(org.apache.calcite.tools.RelBuilder) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Mappings(org.apache.calcite.util.mapping.Mappings) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with RelOptPredicateList

use of org.apache.calcite.plan.RelOptPredicateList in project hive by apache.

the class HiveUnionPullUpConstantsRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final Union union = call.rel(0);
    final int count = union.getRowType().getFieldCount();
    if (count == 1) {
        // Project operator.
        return;
    }
    final RexBuilder rexBuilder = union.getCluster().getRexBuilder();
    final RelMetadataQuery mq = RelMetadataQuery.instance();
    final RelOptPredicateList predicates = mq.getPulledUpPredicates(union);
    if (predicates == null) {
        return;
    }
    Map<RexNode, RexNode> conditionsExtracted = HiveReduceExpressionsRule.predicateConstants(RexNode.class, rexBuilder, predicates);
    Map<RexNode, RexNode> constants = new HashMap<>();
    for (int i = 0; i < count; i++) {
        RexNode expr = rexBuilder.makeInputRef(union, i);
        if (conditionsExtracted.containsKey(expr)) {
            constants.put(expr, conditionsExtracted.get(expr));
        }
    }
    // None of the expressions are constant. Nothing to do.
    if (constants.isEmpty()) {
        return;
    }
    // Create expressions for Project operators before and after the Union
    List<RelDataTypeField> fields = union.getRowType().getFieldList();
    List<RexNode> topChildExprs = new ArrayList<>();
    List<String> topChildExprsFields = new ArrayList<>();
    List<RexNode> refs = new ArrayList<>();
    ImmutableBitSet.Builder refsIndexBuilder = ImmutableBitSet.builder();
    for (int i = 0; i < count; i++) {
        RexNode expr = rexBuilder.makeInputRef(union, i);
        RelDataTypeField field = fields.get(i);
        if (constants.containsKey(expr)) {
            topChildExprs.add(constants.get(expr));
            topChildExprsFields.add(field.getName());
        } else {
            topChildExprs.add(expr);
            topChildExprsFields.add(field.getName());
            refs.add(expr);
            refsIndexBuilder.set(i);
        }
    }
    ImmutableBitSet refsIndex = refsIndexBuilder.build();
    // Update top Project positions
    final Mappings.TargetMapping mapping = RelOptUtil.permutation(refs, union.getInput(0).getRowType()).inverse();
    topChildExprs = ImmutableList.copyOf(RexUtil.apply(mapping, topChildExprs));
    // Create new Project-Union-Project sequences
    final RelBuilder relBuilder = call.builder();
    for (int i = 0; i < union.getInputs().size(); i++) {
        RelNode input = union.getInput(i);
        List<Pair<RexNode, String>> newChildExprs = new ArrayList<>();
        for (int j = 0; j < refsIndex.cardinality(); j++) {
            int pos = refsIndex.nth(j);
            newChildExprs.add(Pair.<RexNode, String>of(rexBuilder.makeInputRef(input, pos), input.getRowType().getFieldList().get(pos).getName()));
        }
        if (newChildExprs.isEmpty()) {
            // At least a single item in project is required.
            newChildExprs.add(Pair.<RexNode, String>of(topChildExprs.get(0), topChildExprsFields.get(0)));
        }
        // Add the input with project on top
        relBuilder.push(input);
        relBuilder.project(Pair.left(newChildExprs), Pair.right(newChildExprs));
    }
    relBuilder.union(union.all, union.getInputs().size());
    // Create top Project fixing nullability of fields
    relBuilder.project(topChildExprs, topChildExprsFields);
    relBuilder.convert(union.getRowType(), false);
    call.transformTo(relBuilder.build());
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelBuilder(org.apache.calcite.tools.RelBuilder) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HiveUnion(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveUnion) Union(org.apache.calcite.rel.core.Union) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) Mappings(org.apache.calcite.util.mapping.Mappings) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 5 with RelOptPredicateList

use of org.apache.calcite.plan.RelOptPredicateList in project hive by apache.

the class HiveRelMdPredicates method getPredicates.

/**
   * Infers predicates for a project.
   *
   * <ol>
   * <li>create a mapping from input to projection. Map only positions that
   * directly reference an input column.
   * <li>Expressions that only contain above columns are retained in the
   * Project's pullExpressions list.
   * <li>For e.g. expression 'a + e = 9' below will not be pulled up because 'e'
   * is not in the projection list.
   *
   * <pre>
   * childPullUpExprs:      {a &gt; 7, b + c &lt; 10, a + e = 9}
   * projectionExprs:       {a, b, c, e / 2}
   * projectionPullupExprs: {a &gt; 7, b + c &lt; 10}
   * </pre>
   *
   * </ol>
   */
public RelOptPredicateList getPredicates(Project project, RelMetadataQuery mq) {
    RelNode child = project.getInput();
    final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
    RelOptPredicateList childInfo = mq.getPulledUpPredicates(child);
    List<RexNode> projectPullUpPredicates = new ArrayList<RexNode>();
    HashMultimap<Integer, Integer> inpIndxToOutIndxMap = HashMultimap.create();
    ImmutableBitSet.Builder columnsMappedBuilder = ImmutableBitSet.builder();
    Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, child.getRowType().getFieldCount(), project.getRowType().getFieldCount());
    for (Ord<RexNode> o : Ord.zip(project.getProjects())) {
        if (o.e instanceof RexInputRef) {
            int sIdx = ((RexInputRef) o.e).getIndex();
            m.set(sIdx, o.i);
            inpIndxToOutIndxMap.put(sIdx, o.i);
            columnsMappedBuilder.set(sIdx);
        }
    }
    // Go over childPullUpPredicates. If a predicate only contains columns in
    // 'columnsMapped' construct a new predicate based on mapping.
    final ImmutableBitSet columnsMapped = columnsMappedBuilder.build();
    for (RexNode r : childInfo.pulledUpPredicates) {
        ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
        if (columnsMapped.contains(rCols)) {
            r = r.accept(new RexPermuteInputsShuttle(m, child));
            projectPullUpPredicates.add(r);
        }
    }
    // Project can also generate constants. We need to include them.
    for (Ord<RexNode> expr : Ord.zip(project.getProjects())) {
        if (RexLiteral.isNullLiteral(expr.e)) {
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, rexBuilder.makeInputRef(project, expr.i)));
        } else if (expr.e instanceof RexLiteral) {
            final RexLiteral literal = (RexLiteral) expr.e;
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef(project, expr.i), literal));
        } else if (expr.e instanceof RexCall && HiveCalciteUtil.isDeterministicFuncOnLiterals(expr.e)) {
            //TODO: Move this to calcite
            projectPullUpPredicates.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef(project, expr.i), expr.e));
        }
    }
    return RelOptPredicateList.of(projectPullUpPredicates);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) Mapping(org.apache.calcite.util.mapping.Mapping) RexCall(org.apache.calcite.rex.RexCall) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RexPermuteInputsShuttle(org.apache.calcite.rex.RexPermuteInputsShuttle) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)7 RelNode (org.apache.calcite.rel.RelNode)7 RexBuilder (org.apache.calcite.rex.RexBuilder)6 RexNode (org.apache.calcite.rex.RexNode)6 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)3 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)3 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 RexPermuteInputsShuttle (org.apache.calcite.rex.RexPermuteInputsShuttle)2 RelBuilder (org.apache.calcite.tools.RelBuilder)2 Pair (org.apache.calcite.util.Pair)2 Mapping (org.apache.calcite.util.mapping.Mapping)2 Mappings (org.apache.calcite.util.mapping.Mappings)2 HepRelVertex (org.apache.calcite.plan.hep.HepRelVertex)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 Join (org.apache.calcite.rel.core.Join)1 Sort (org.apache.calcite.rel.core.Sort)1 Union (org.apache.calcite.rel.core.Union)1 RexCall (org.apache.calcite.rex.RexCall)1