Search in sources :

Example 21 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project flink by apache.

the class FlinkRelDecorrelator method decorrelateRel.

/**
	 * Rewrite LogicalProject.
	 *
	 * @param rel the project rel to rewrite
	 */
public Frame decorrelateRel(LogicalProject rel) {
    //
    // Rewrite logic:
    //
    // 1. Pass along any correlated variables coming from the input.
    //
    final RelNode oldInput = rel.getInput();
    Frame frame = getInvoke(oldInput, rel);
    if (frame == null) {
        // If input has not been rewritten, do not rewrite this rel.
        return null;
    }
    final List<RexNode> oldProjects = rel.getProjects();
    final List<RelDataTypeField> relOutput = rel.getRowType().getFieldList();
    // LogicalProject projects the original expressions,
    // plus any correlated variables the input wants to pass along.
    final List<Pair<RexNode, String>> projects = Lists.newArrayList();
    // and produce the correlated variables in the new output.
    if (cm.mapRefRelToCorVar.containsKey(rel)) {
        decorrelateInputWithValueGenerator(rel);
        // The old input should be mapped to the LogicalJoin created by
        // rewriteInputWithValueGenerator().
        frame = map.get(oldInput);
    }
    // LogicalProject projects the original expressions
    final Map<Integer, Integer> mapOldToNewOutputPos = Maps.newHashMap();
    int newPos;
    for (newPos = 0; newPos < oldProjects.size(); newPos++) {
        projects.add(newPos, Pair.of(decorrelateExpr(oldProjects.get(newPos)), relOutput.get(newPos).getName()));
        mapOldToNewOutputPos.put(newPos, newPos);
    }
    // Project any correlated variables the input wants to pass along.
    final SortedMap<Correlation, Integer> mapCorVarToOutputPos = new TreeMap<>();
    for (Map.Entry<Correlation, Integer> entry : frame.corVarOutputPos.entrySet()) {
        projects.add(RexInputRef.of2(entry.getValue(), frame.r.getRowType().getFieldList()));
        mapCorVarToOutputPos.put(entry.getKey(), newPos);
        newPos++;
    }
    RelNode newProject = RelOptUtil.createProject(frame.r, projects, false);
    return register(rel, newProject, mapOldToNewOutputPos, mapCorVarToOutputPos);
}
Also used : TreeMap(java.util.TreeMap) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) NavigableMap(java.util.NavigableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 22 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project flink by apache.

the class FlinkRelDecorrelator method decorrelateRel.

/**
	 * Rewrite Correlator into a left outer join.
	 *
	 * @param rel Correlator
	 */
public Frame decorrelateRel(LogicalCorrelate rel) {
    //
    // Rewrite logic:
    //
    // The original left input will be joined with the new right input that
    // has generated correlated variables propagated up. For any generated
    // cor vars that are not used in the join key, pass them along to be
    // joined later with the CorrelatorRels that produce them.
    //
    // the right input to Correlator should produce correlated variables
    final RelNode oldLeft = rel.getInput(0);
    final RelNode oldRight = rel.getInput(1);
    final Frame leftFrame = getInvoke(oldLeft, rel);
    final Frame rightFrame = getInvoke(oldRight, rel);
    if (leftFrame == null || rightFrame == null) {
        // If any input has not been rewritten, do not rewrite this rel.
        return null;
    }
    if (rightFrame.corVarOutputPos.isEmpty()) {
        return null;
    }
    assert rel.getRequiredColumns().cardinality() <= rightFrame.corVarOutputPos.keySet().size();
    // Change correlator rel into a join.
    // Join all the correlated variables produced by this correlator rel
    // with the values generated and propagated from the right input
    final SortedMap<Correlation, Integer> corVarOutputPos = new TreeMap<>(rightFrame.corVarOutputPos);
    final List<RexNode> conditions = new ArrayList<>();
    final List<RelDataTypeField> newLeftOutput = leftFrame.r.getRowType().getFieldList();
    int newLeftFieldCount = newLeftOutput.size();
    final List<RelDataTypeField> newRightOutput = rightFrame.r.getRowType().getFieldList();
    for (Map.Entry<Correlation, Integer> rightOutputPos : Lists.newArrayList(corVarOutputPos.entrySet())) {
        final Correlation corVar = rightOutputPos.getKey();
        if (!corVar.corr.equals(rel.getCorrelationId())) {
            continue;
        }
        final int newLeftPos = leftFrame.oldToNewOutputPos.get(corVar.field);
        final int newRightPos = rightOutputPos.getValue();
        conditions.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, RexInputRef.of(newLeftPos, newLeftOutput), new RexInputRef(newLeftFieldCount + newRightPos, newRightOutput.get(newRightPos).getType())));
        // remove this cor var from output position mapping
        corVarOutputPos.remove(corVar);
    }
    // vars that are not used in the join key.
    for (Correlation corVar : corVarOutputPos.keySet()) {
        int newPos = corVarOutputPos.get(corVar) + newLeftFieldCount;
        corVarOutputPos.put(corVar, newPos);
    }
    // then add any cor var from the left input. Do not need to change
    // output positions.
    corVarOutputPos.putAll(leftFrame.corVarOutputPos);
    // Create the mapping between the output of the old correlation rel
    // and the new join rel
    final Map<Integer, Integer> mapOldToNewOutputPos = Maps.newHashMap();
    int oldLeftFieldCount = oldLeft.getRowType().getFieldCount();
    int oldRightFieldCount = oldRight.getRowType().getFieldCount();
    assert rel.getRowType().getFieldCount() == oldLeftFieldCount + oldRightFieldCount;
    // Left input positions are not changed.
    mapOldToNewOutputPos.putAll(leftFrame.oldToNewOutputPos);
    // Right input positions are shifted by newLeftFieldCount.
    for (int i = 0; i < oldRightFieldCount; i++) {
        mapOldToNewOutputPos.put(i + oldLeftFieldCount, rightFrame.oldToNewOutputPos.get(i) + newLeftFieldCount);
    }
    final RexNode condition = RexUtil.composeConjunction(rexBuilder, conditions, false);
    RelNode newJoin = LogicalJoin.create(leftFrame.r, rightFrame.r, condition, ImmutableSet.<CorrelationId>of(), rel.getJoinType().toJoinType());
    return register(rel, newJoin, mapOldToNewOutputPos, corVarOutputPos);
}
Also used : ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) NavigableMap(java.util.NavigableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) RexNode(org.apache.calcite.rex.RexNode)

Example 23 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project flink by apache.

the class FlinkRelDecorrelator method decorrelate.

private RelNode decorrelate(RelNode root) {
    // first adjust count() expression if any
    HepProgram program = HepProgram.builder().addRuleInstance(new AdjustProjectForCountAggregateRule(false)).addRuleInstance(new AdjustProjectForCountAggregateRule(true)).addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterCorrelateRule.INSTANCE).build();
    HepPlanner planner = createPlanner(program);
    planner.setRoot(root);
    root = planner.findBestExp();
    // Perform decorrelation.
    map.clear();
    final Frame frame = getInvoke(root, null);
    if (frame != null) {
        // has been rewritten; apply rules post-decorrelation
        final HepProgram program2 = HepProgram.builder().addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(FilterJoinRule.JOIN).build();
        final HepPlanner planner2 = createPlanner(program2);
        final RelNode newRoot = frame.r;
        planner2.setRoot(newRoot);
        return planner2.findBestExp();
    }
    return root;
}
Also used : HepProgram(org.apache.calcite.plan.hep.HepProgram) RelNode(org.apache.calcite.rel.RelNode) HepPlanner(org.apache.calcite.plan.hep.HepPlanner)

Example 24 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project drill by apache.

the class InsertLocalExchangeVisitor method visitExchange.

@Override
public Prel visitExchange(ExchangePrel prel, Void value) throws RuntimeException {
    Prel child = ((Prel) prel.getInput()).accept(this, null);
    //   If DeMuxExchange is enabled, insert a UnorderedDeMuxExchangePrel after HashToRandomExchangePrel.
    if (!(prel instanceof HashToRandomExchangePrel)) {
        return (Prel) prel.copy(prel.getTraitSet(), Collections.singletonList(((RelNode) child)));
    }
    Prel newPrel = child;
    final HashToRandomExchangePrel hashPrel = (HashToRandomExchangePrel) prel;
    final List<String> childFields = child.getRowType().getFieldNames();
    List<RexNode> removeUpdatedExpr = null;
    if (isMuxEnabled) {
        // Insert Project Operator with new column that will be a hash for HashToRandomExchange fields
        final List<DistributionField> distFields = hashPrel.getFields();
        final List<String> outputFieldNames = Lists.newArrayList(childFields);
        final RexBuilder rexBuilder = prel.getCluster().getRexBuilder();
        final List<RelDataTypeField> childRowTypeFields = child.getRowType().getFieldList();
        final HashExpressionCreatorHelper<RexNode> hashHelper = new RexNodeBasedHashExpressionCreatorHelper(rexBuilder);
        final List<RexNode> distFieldRefs = Lists.newArrayListWithExpectedSize(distFields.size());
        for (int i = 0; i < distFields.size(); i++) {
            final int fieldId = distFields.get(i).getFieldId();
            distFieldRefs.add(rexBuilder.makeInputRef(childRowTypeFields.get(fieldId).getType(), fieldId));
        }
        final List<RexNode> updatedExpr = Lists.newArrayListWithExpectedSize(childRowTypeFields.size());
        removeUpdatedExpr = Lists.newArrayListWithExpectedSize(childRowTypeFields.size());
        for (RelDataTypeField field : childRowTypeFields) {
            RexNode rex = rexBuilder.makeInputRef(field.getType(), field.getIndex());
            updatedExpr.add(rex);
            removeUpdatedExpr.add(rex);
        }
        outputFieldNames.add(HashPrelUtil.HASH_EXPR_NAME);
        // distribution seed
        final RexNode distSeed = rexBuilder.makeBigintLiteral(BigDecimal.valueOf(HashPrelUtil.DIST_SEED));
        updatedExpr.add(HashPrelUtil.createHashBasedPartitionExpression(distFieldRefs, distSeed, hashHelper));
        RelDataType rowType = RexUtil.createStructType(prel.getCluster().getTypeFactory(), updatedExpr, outputFieldNames);
        ProjectPrel addColumnprojectPrel = new ProjectPrel(child.getCluster(), child.getTraitSet(), child, updatedExpr, rowType);
        newPrel = new UnorderedMuxExchangePrel(addColumnprojectPrel.getCluster(), addColumnprojectPrel.getTraitSet(), addColumnprojectPrel);
    }
    newPrel = new HashToRandomExchangePrel(prel.getCluster(), prel.getTraitSet(), newPrel, ((HashToRandomExchangePrel) prel).getFields());
    if (isDeMuxEnabled) {
        HashToRandomExchangePrel hashExchangePrel = (HashToRandomExchangePrel) newPrel;
        // Insert a DeMuxExchange to narrow down the number of receivers
        newPrel = new UnorderedDeMuxExchangePrel(prel.getCluster(), prel.getTraitSet(), hashExchangePrel, hashExchangePrel.getFields());
    }
    if (isMuxEnabled) {
        // remove earlier inserted Project Operator - since it creates issues down the road in HashJoin
        RelDataType removeRowType = RexUtil.createStructType(newPrel.getCluster().getTypeFactory(), removeUpdatedExpr, childFields);
        ProjectPrel removeColumnProjectPrel = new ProjectPrel(newPrel.getCluster(), newPrel.getTraitSet(), newPrel, removeUpdatedExpr, removeRowType);
        return removeColumnProjectPrel;
    }
    return newPrel;
}
Also used : ProjectPrel(org.apache.drill.exec.planner.physical.ProjectPrel) HashToRandomExchangePrel(org.apache.drill.exec.planner.physical.HashToRandomExchangePrel) RelDataType(org.apache.calcite.rel.type.RelDataType) ExchangePrel(org.apache.drill.exec.planner.physical.ExchangePrel) UnorderedDeMuxExchangePrel(org.apache.drill.exec.planner.physical.UnorderedDeMuxExchangePrel) UnorderedMuxExchangePrel(org.apache.drill.exec.planner.physical.UnorderedMuxExchangePrel) Prel(org.apache.drill.exec.planner.physical.Prel) HashToRandomExchangePrel(org.apache.drill.exec.planner.physical.HashToRandomExchangePrel) ProjectPrel(org.apache.drill.exec.planner.physical.ProjectPrel) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) UnorderedMuxExchangePrel(org.apache.drill.exec.planner.physical.UnorderedMuxExchangePrel) RexBuilder(org.apache.calcite.rex.RexBuilder) UnorderedDeMuxExchangePrel(org.apache.drill.exec.planner.physical.UnorderedDeMuxExchangePrel) DistributionField(org.apache.drill.exec.planner.physical.DrillDistributionTrait.DistributionField) RexNode(org.apache.calcite.rex.RexNode)

Example 25 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project drill by apache.

the class JoinPrelRenameVisitor method visitJoin.

@Override
public Prel visitJoin(JoinPrel prel, Void value) throws RuntimeException {
    List<RelNode> children = Lists.newArrayList();
    for (Prel child : prel) {
        child = child.accept(this, null);
        children.add(child);
    }
    final int leftCount = children.get(0).getRowType().getFieldCount();
    List<RelNode> reNamedChildren = Lists.newArrayList();
    RelNode left = prel.getJoinInput(0, children.get(0));
    RelNode right = prel.getJoinInput(leftCount, children.get(1));
    reNamedChildren.add(left);
    reNamedChildren.add(right);
    return (Prel) prel.copy(prel.getTraitSet(), reNamedChildren);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Prel(org.apache.drill.exec.planner.physical.Prel) JoinPrel(org.apache.drill.exec.planner.physical.JoinPrel)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)2169 RexNode (org.apache.calcite.rex.RexNode)586 ArrayList (java.util.ArrayList)510 Test (org.junit.jupiter.api.Test)423 RelBuilder (org.apache.calcite.tools.RelBuilder)406 RelDataType (org.apache.calcite.rel.type.RelDataType)304 RexBuilder (org.apache.calcite.rex.RexBuilder)270 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)263 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)258 RexInputRef (org.apache.calcite.rex.RexInputRef)201 RelTraitSet (org.apache.calcite.plan.RelTraitSet)191 List (java.util.List)185 Project (org.apache.calcite.rel.core.Project)182 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)169 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)166 Pair (org.apache.calcite.util.Pair)163 AggregateCall (org.apache.calcite.rel.core.AggregateCall)159 TimestampString (org.apache.calcite.util.TimestampString)154 HashMap (java.util.HashMap)151 RelOptCluster (org.apache.calcite.plan.RelOptCluster)151