Search in sources :

Example 1 with HepRelVertex

use of org.apache.calcite.plan.hep.HepRelVertex in project hive by apache.

the class HiveSemiJoinRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    LOG.debug("Matched HiveSemiJoinRule");
    final Project project = call.rel(0);
    final Join join = call.rel(1);
    final RelNode left = call.rel(2);
    final Aggregate aggregate = call.rel(3);
    final RelOptCluster cluster = join.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(project.getProjects(), null);
    final ImmutableBitSet rightBits = ImmutableBitSet.range(left.getRowType().getFieldCount(), join.getRowType().getFieldCount());
    if (bits.intersects(rightBits)) {
        return;
    }
    final JoinInfo joinInfo = join.analyzeCondition();
    if (!joinInfo.rightSet().equals(ImmutableBitSet.range(aggregate.getGroupCount()))) {
        // By the way, neither a super-set nor a sub-set would work.
        return;
    }
    if (join.getJoinType() == JoinRelType.LEFT) {
        // since for LEFT join we are only interested in rows from LEFT we can get rid of right side
        call.transformTo(call.builder().push(left).project(project.getProjects(), project.getRowType().getFieldNames()).build());
        return;
    }
    if (join.getJoinType() != JoinRelType.INNER) {
        return;
    }
    if (!joinInfo.isEqui()) {
        return;
    }
    LOG.debug("All conditions matched for HiveSemiJoinRule. Going to apply transformation.");
    final List<Integer> newRightKeyBuilder = Lists.newArrayList();
    final List<Integer> aggregateKeys = aggregate.getGroupSet().asList();
    for (int key : joinInfo.rightKeys) {
        newRightKeyBuilder.add(aggregateKeys.get(key));
    }
    final ImmutableIntList newRightKeys = ImmutableIntList.copyOf(newRightKeyBuilder);
    final RelNode newRight = aggregate.getInput();
    final RexNode newCondition = RelOptUtil.createEquiJoinCondition(left, joinInfo.leftKeys, newRight, newRightKeys, rexBuilder);
    RelNode semi = null;
    // is not expected further down the pipeline. see jira for more details
    if (aggregate.getInput() instanceof HepRelVertex && ((HepRelVertex) aggregate.getInput()).getCurrentRel() instanceof Join) {
        Join rightJoin = (Join) (((HepRelVertex) aggregate.getInput()).getCurrentRel());
        List<RexNode> projects = new ArrayList<>();
        for (int i = 0; i < rightJoin.getRowType().getFieldCount(); i++) {
            projects.add(rexBuilder.makeInputRef(rightJoin, i));
        }
        RelNode topProject = call.builder().push(rightJoin).project(projects, rightJoin.getRowType().getFieldNames(), true).build();
        semi = call.builder().push(left).push(topProject).semiJoin(newCondition).build();
    } else {
        semi = call.builder().push(left).push(aggregate.getInput()).semiJoin(newCondition).build();
    }
    call.transformTo(call.builder().push(semi).project(project.getProjects(), project.getRowType().getFieldNames()).build());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) JoinInfo(org.apache.calcite.rel.core.JoinInfo) Project(org.apache.calcite.rel.core.Project) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) Aggregate(org.apache.calcite.rel.core.Aggregate) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with HepRelVertex

use of org.apache.calcite.plan.hep.HepRelVertex 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 = call.getMetadataQuery();
    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 3 with HepRelVertex

use of org.apache.calcite.plan.hep.HepRelVertex in project calcite by apache.

the class RelDecorrelator method stripHep.

private static RelNode stripHep(RelNode rel) {
    if (rel instanceof HepRelVertex) {
        HepRelVertex hepRelVertex = (HepRelVertex) rel;
        rel = hepRelVertex.getCurrentRel();
    }
    return rel;
}
Also used : HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex)

Example 4 with HepRelVertex

use of org.apache.calcite.plan.hep.HepRelVertex in project drill by apache.

the class DrillPushRowKeyJoinToScanRule method isRowKeyColumn.

/* Finds whether the given column reference is for the rowkey col(also known as primary-key col).
   * We need to recurse down the operators looking at their references down to the scan
   * to figure out whether the reference is a rowkey col. Projections can rearrange the
   * incoming columns. We also need to handle HepRelVertex/RelSubset while handling the rels.
   */
private static boolean isRowKeyColumn(int index, RelNode rel) {
    RelNode curRel = rel;
    int curIndex = index;
    while (curRel != null && !(curRel instanceof DrillScanRel)) {
        logger.debug("IsRowKeyColumn: Rel={}, RowTypePos={}, RowType={}", curRel.toString(), curIndex, curRel.getRowType().toString());
        if (curRel instanceof HepRelVertex) {
            curRel = ((HepRelVertex) curRel).getCurrentRel();
        } else if (curRel instanceof RelSubset) {
            if (((RelSubset) curRel).getBest() != null) {
                curRel = ((RelSubset) curRel).getBest();
            } else {
                curRel = ((RelSubset) curRel).getOriginal();
            }
        } else {
            RelNode child = null;
            // before recursing down that child rel.
            for (RelNode input : curRel.getInputs()) {
                if (input.getRowType().getFieldList().size() <= curIndex) {
                    curIndex -= input.getRowType().getFieldList().size();
                } else {
                    child = input;
                    break;
                }
            }
            curRel = child;
        }
        // Otherwise, the column index is the `RexInputRef` index.
        if (curRel != null && curRel instanceof DrillProjectRel) {
            List<RexNode> childExprs = curRel.getChildExps();
            if (childExprs != null && childExprs.size() > 0) {
                if (childExprs.get(curIndex) instanceof RexInputRef) {
                    curIndex = ((RexInputRef) childExprs.get(curIndex)).getIndex();
                } else {
                    // Currently do not support expressions on rowkey col. So if an expr is present,
                    // return false
                    logger.debug("IsRowKeyColumn: ABORT: Primary-key EXPR$={}", childExprs.get(curIndex).toString());
                    return false;
                }
            }
        }
    }
    logger.debug("IsRowKeyColumn:Primary-key Col={} ", curRel != null ? curRel.getRowType().getFieldNames().get(curIndex) : "??");
    // Get the primary-key col name from the scan and match with the column being referenced.
    if (curRel != null && curRel instanceof DrillScanRel) {
        if (((DrillScanRel) curRel).getGroupScan() instanceof DbGroupScan) {
            DbGroupScan dbGroupScan = (DbGroupScan) ((DrillScanRel) curRel).getGroupScan();
            String rowKeyName = dbGroupScan.getRowKeyName();
            DbGroupScan restrictedGroupScan = dbGroupScan.getRestrictedScan(((DrillScanRel) curRel).getColumns());
            // Also verify this scan supports restricted groupscans(random seeks)
            if (restrictedGroupScan != null && curRel.getRowType().getFieldNames().get(curIndex).equalsIgnoreCase(rowKeyName)) {
                logger.debug("IsRowKeyColumn: FOUND: Rel={}, RowTypePos={}, RowType={}", curRel.toString(), curIndex, curRel.getRowType().toString());
                return true;
            }
        }
    }
    logger.debug("IsRowKeyColumn: NOT FOUND");
    return false;
}
Also used : HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) RelNode(org.apache.calcite.rel.RelNode) DbGroupScan(org.apache.drill.exec.physical.base.DbGroupScan) RexInputRef(org.apache.calcite.rex.RexInputRef) RelSubset(org.apache.calcite.plan.volcano.RelSubset) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with HepRelVertex

use of org.apache.calcite.plan.hep.HepRelVertex in project flink by apache.

the class PythonCorrelateSplitRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    FlinkLogicalCorrelate correlate = call.rel(0);
    RelNode right = ((HepRelVertex) correlate.getRight()).getCurrentRel();
    FlinkLogicalTableFunctionScan tableFunctionScan;
    if (right instanceof FlinkLogicalTableFunctionScan) {
        tableFunctionScan = (FlinkLogicalTableFunctionScan) right;
    } else if (right instanceof FlinkLogicalCalc) {
        tableFunctionScan = StreamPhysicalCorrelateRule.getTableScan((FlinkLogicalCalc) right);
    } else {
        return false;
    }
    RexNode rexNode = tableFunctionScan.getCall();
    if (rexNode instanceof RexCall) {
        return PythonUtil.isPythonCall(rexNode, null) && PythonUtil.containsNonPythonCall(rexNode) || PythonUtil.isNonPythonCall(rexNode) && PythonUtil.containsPythonCall(rexNode, null) || (PythonUtil.isPythonCall(rexNode, null) && RexUtil.containsFieldAccess(rexNode));
    }
    return false;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) FlinkLogicalCorrelate(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCorrelate) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) RelNode(org.apache.calcite.rel.RelNode) FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) FlinkLogicalTableFunctionScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableFunctionScan) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

HepRelVertex (org.apache.calcite.plan.hep.HepRelVertex)16 RelNode (org.apache.calcite.rel.RelNode)8 RexNode (org.apache.calcite.rex.RexNode)7 Join (org.apache.calcite.rel.core.Join)4 RexBuilder (org.apache.calcite.rex.RexBuilder)4 ArrayList (java.util.ArrayList)3 JoinInfo (org.apache.calcite.rel.core.JoinInfo)3 Project (org.apache.calcite.rel.core.Project)3 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)3 RelOptCluster (org.apache.calcite.plan.RelOptCluster)2 RelSubset (org.apache.calcite.plan.volcano.RelSubset)2 Aggregate (org.apache.calcite.rel.core.Aggregate)2 Sort (org.apache.calcite.rel.core.Sort)2 TableScan (org.apache.calcite.rel.core.TableScan)2 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)2 HashMap (java.util.HashMap)1 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 Calc (org.apache.calcite.rel.core.Calc)1 Collect (org.apache.calcite.rel.core.Collect)1