Search in sources :

Example 1 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project flink by apache.

the class FlinkRelDecorrelator method createCopyHook.

private Function2<RelNode, RelNode, Void> createCopyHook() {
    return new Function2<RelNode, RelNode, Void>() {

        public Void apply(RelNode oldNode, RelNode newNode) {
            if (cm.mapRefRelToCorVar.containsKey(oldNode)) {
                cm.mapRefRelToCorVar.putAll(newNode, cm.mapRefRelToCorVar.get(oldNode));
            }
            if (oldNode instanceof LogicalCorrelate && newNode instanceof LogicalCorrelate) {
                LogicalCorrelate oldCor = (LogicalCorrelate) oldNode;
                CorrelationId c = oldCor.getCorrelationId();
                if (cm.mapCorVarToCorRel.get(c) == oldNode) {
                    cm.mapCorVarToCorRel.put(c, newNode);
                }
                if (generatedCorRels.contains(oldNode)) {
                    generatedCorRels.add((LogicalCorrelate) newNode);
                }
            }
            return null;
        }
    };
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Function2(org.apache.calcite.linq4j.function.Function2) LogicalCorrelate(org.apache.calcite.rel.logical.LogicalCorrelate) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Example 2 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project hive by apache.

the class HiveRelDecorrelator method createValueGenerator.

/**
 * Create RelNode tree that produces a list of correlated variables.
 *
 * @param correlations         correlated variables to generate
 * @param valueGenFieldOffset  offset in the output that generated columns
 *                             will start
 * @param mapCorVarToOutputPos output positions for the correlated variables
 *                             generated
 * @return RelNode the root of the resultant RelNode tree
 */
private RelNode createValueGenerator(Iterable<CorRef> correlations, int valueGenFieldOffset, SortedMap<CorDef, Integer> corDefOutputs) {
    final Map<RelNode, List<Integer>> mapNewInputToOutputs = new HashMap<>();
    final Map<RelNode, Integer> mapNewInputToNewOffset = new HashMap<>();
    // Add to map all the referenced positions (relative to each input rel).
    for (CorRef corVar : correlations) {
        final int oldCorVarOffset = corVar.field;
        final RelNode oldInput = getCorRel(corVar);
        assert oldInput != null;
        final Frame frame = map.get(oldInput);
        assert frame != null;
        final RelNode newInput = frame.r;
        final List<Integer> newLocalOutputs;
        if (!mapNewInputToOutputs.containsKey(newInput)) {
            newLocalOutputs = new ArrayList<>();
        } else {
            newLocalOutputs = mapNewInputToOutputs.get(newInput);
        }
        final int newCorVarOffset = frame.oldToNewOutputs.get(oldCorVarOffset);
        // Add all unique positions referenced.
        if (!newLocalOutputs.contains(newCorVarOffset)) {
            newLocalOutputs.add(newCorVarOffset);
        }
        mapNewInputToOutputs.put(newInput, newLocalOutputs);
    }
    int offset = 0;
    // Project only the correlated fields out of each inputRel
    // and join the projectRel together.
    // To make sure the plan does not change in terms of join order,
    // join these rels based on their occurrence in cor var list which
    // is sorted.
    final Set<RelNode> joinedInputs = new HashSet<>();
    RelNode r = null;
    for (CorRef corVar : correlations) {
        final RelNode oldInput = getCorRel(corVar);
        assert oldInput != null;
        final RelNode newInput = map.get(oldInput).r;
        assert newInput != null;
        if (!joinedInputs.contains(newInput)) {
            RelNode project = RelOptUtil.createProject(newInput, mapNewInputToOutputs.get(newInput));
            RelNode distinct = RelOptUtil.createDistinctRel(project);
            RelOptCluster cluster = distinct.getCluster();
            joinedInputs.add(newInput);
            mapNewInputToNewOffset.put(newInput, offset);
            offset += distinct.getRowType().getFieldCount();
            if (r == null) {
                r = distinct;
            } else {
                r = LogicalJoin.create(r, distinct, cluster.getRexBuilder().makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER);
            }
        }
    }
    // referencing correlated variables.
    for (CorRef corRef : correlations) {
        // The first input of a Correlator is always the rel defining
        // the correlated variables.
        final RelNode oldInput = getCorRel(corRef);
        assert oldInput != null;
        final Frame frame = map.get(oldInput);
        final RelNode newInput = frame.r;
        assert newInput != null;
        final List<Integer> newLocalOutputs = mapNewInputToOutputs.get(newInput);
        final int newLocalOutput = frame.oldToNewOutputs.get(corRef.field);
        // newOutput is the index of the cor var in the referenced
        // position list plus the offset of referenced position list of
        // each newInput.
        final int newOutput = newLocalOutputs.indexOf(newLocalOutput) + mapNewInputToNewOffset.get(newInput) + valueGenFieldOffset;
        corDefOutputs.put(corRef.def(), newOutput);
    }
    return r;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) HashMap(java.util.HashMap) HiveRelNode(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveRelNode) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) HashSet(java.util.HashSet)

Example 3 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class JoinToCorrelateRule method onMatch.

public void onMatch(RelOptRuleCall call) {
    assert matches(call);
    final LogicalJoin join = call.rel(0);
    RelNode right = join.getRight();
    final RelNode left = join.getLeft();
    final int leftFieldCount = left.getRowType().getFieldCount();
    final RelOptCluster cluster = join.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelBuilder relBuilder = call.builder();
    final CorrelationId correlationId = cluster.createCorrel();
    final RexNode corrVar = rexBuilder.makeCorrel(left.getRowType(), correlationId);
    final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
    // Replace all references of left input with FieldAccess(corrVar, field)
    final RexNode joinCondition = join.getCondition().accept(new RexShuttle() {

        @Override
        public RexNode visitInputRef(RexInputRef input) {
            int field = input.getIndex();
            if (field >= leftFieldCount) {
                return rexBuilder.makeInputRef(input.getType(), input.getIndex() - leftFieldCount);
            }
            requiredColumns.set(field);
            return rexBuilder.makeFieldAccess(corrVar, field);
        }
    });
    relBuilder.push(right).filter(joinCondition);
    RelNode newRel = LogicalCorrelate.create(left, relBuilder.build(), correlationId, requiredColumns.build(), SemiJoinType.of(join.getJoinType()));
    call.transformTo(newRel);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelBuilder(org.apache.calcite.tools.RelBuilder) RexShuttle(org.apache.calcite.rex.RexShuttle) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class RelDecorrelator method createValueGenerator.

/**
 * Create RelNode tree that produces a list of correlated variables.
 *
 * @param correlations         correlated variables to generate
 * @param valueGenFieldOffset  offset in the output that generated columns
 *                             will start
 * @param corDefOutputs        output positions for the correlated variables
 *                             generated
 * @return RelNode the root of the resultant RelNode tree
 */
private RelNode createValueGenerator(Iterable<CorRef> correlations, int valueGenFieldOffset, SortedMap<CorDef, Integer> corDefOutputs) {
    final Map<RelNode, List<Integer>> mapNewInputToOutputs = new HashMap<>();
    final Map<RelNode, Integer> mapNewInputToNewOffset = new HashMap<>();
    // Add to map all the referenced positions (relative to each input rel).
    for (CorRef corVar : correlations) {
        final int oldCorVarOffset = corVar.field;
        final RelNode oldInput = getCorRel(corVar);
        assert oldInput != null;
        final Frame frame = getFrame(oldInput, true);
        assert frame != null;
        final RelNode newInput = frame.r;
        final List<Integer> newLocalOutputs;
        if (!mapNewInputToOutputs.containsKey(newInput)) {
            newLocalOutputs = new ArrayList<>();
        } else {
            newLocalOutputs = mapNewInputToOutputs.get(newInput);
        }
        final int newCorVarOffset = frame.oldToNewOutputs.get(oldCorVarOffset);
        // Add all unique positions referenced.
        if (!newLocalOutputs.contains(newCorVarOffset)) {
            newLocalOutputs.add(newCorVarOffset);
        }
        mapNewInputToOutputs.put(newInput, newLocalOutputs);
    }
    int offset = 0;
    // Project only the correlated fields out of each input
    // and join the project together.
    // To make sure the plan does not change in terms of join order,
    // join these rels based on their occurrence in corVar list which
    // is sorted.
    final Set<RelNode> joinedInputs = new HashSet<>();
    RelNode r = null;
    for (CorRef corVar : correlations) {
        final RelNode oldInput = getCorRel(corVar);
        assert oldInput != null;
        final RelNode newInput = getFrame(oldInput, true).r;
        assert newInput != null;
        if (!joinedInputs.contains(newInput)) {
            RelNode project = RelOptUtil.createProject(newInput, mapNewInputToOutputs.get(newInput));
            RelNode distinct = relBuilder.push(project).distinct().build();
            RelOptCluster cluster = distinct.getCluster();
            joinedInputs.add(newInput);
            mapNewInputToNewOffset.put(newInput, offset);
            offset += distinct.getRowType().getFieldCount();
            if (r == null) {
                r = distinct;
            } else {
                r = LogicalJoin.create(r, distinct, cluster.getRexBuilder().makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER);
            }
        }
    }
    // referencing correlated variables.
    for (CorRef corRef : correlations) {
        // The first input of a Correlate is always the rel defining
        // the correlated variables.
        final RelNode oldInput = getCorRel(corRef);
        assert oldInput != null;
        final Frame frame = getFrame(oldInput, true);
        final RelNode newInput = frame.r;
        assert newInput != null;
        final List<Integer> newLocalOutputs = mapNewInputToOutputs.get(newInput);
        final int newLocalOutput = frame.oldToNewOutputs.get(corRef.field);
        // newOutput is the index of the corVar in the referenced
        // position list plus the offset of referenced position list of
        // each newInput.
        final int newOutput = newLocalOutputs.indexOf(newLocalOutput) + mapNewInputToNewOffset.get(newInput) + valueGenFieldOffset;
        corDefOutputs.put(corRef.def(), newOutput);
    }
    return r;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) HashMap(java.util.HashMap) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) HashSet(java.util.HashSet)

Example 5 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class RelDecorrelator method createCopyHook.

private Function2<RelNode, RelNode, Void> createCopyHook() {
    return new Function2<RelNode, RelNode, Void>() {

        public Void apply(RelNode oldNode, RelNode newNode) {
            if (cm.mapRefRelToCorRef.containsKey(oldNode)) {
                cm.mapRefRelToCorRef.putAll(newNode, cm.mapRefRelToCorRef.get(oldNode));
            }
            if (oldNode instanceof LogicalCorrelate && newNode instanceof LogicalCorrelate) {
                LogicalCorrelate oldCor = (LogicalCorrelate) oldNode;
                CorrelationId c = oldCor.getCorrelationId();
                if (cm.mapCorToCorRel.get(c) == oldNode) {
                    cm.mapCorToCorRel.put(c, newNode);
                }
                if (generatedCorRels.contains(oldNode)) {
                    generatedCorRels.add((LogicalCorrelate) newNode);
                }
            }
            return null;
        }
    };
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Function2(org.apache.calcite.linq4j.function.Function2) LogicalCorrelate(org.apache.calcite.rel.logical.LogicalCorrelate) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Aggregations

CorrelationId (org.apache.calcite.rel.core.CorrelationId)28 RelNode (org.apache.calcite.rel.RelNode)19 RexNode (org.apache.calcite.rex.RexNode)13 ArrayList (java.util.ArrayList)12 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)8 HashMap (java.util.HashMap)7 RelDataType (org.apache.calcite.rel.type.RelDataType)7 ImmutableList (com.google.common.collect.ImmutableList)6 List (java.util.List)6 LogicalCorrelate (org.apache.calcite.rel.logical.LogicalCorrelate)6 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)6 RexBuilder (org.apache.calcite.rex.RexBuilder)6 RelOptCluster (org.apache.calcite.plan.RelOptCluster)5 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)4 Map (java.util.Map)3 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)3 RelBuilder (org.apache.calcite.tools.RelBuilder)3 NlsString (org.apache.calcite.util.NlsString)3 HiveRelNode (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveRelNode)3 HashSet (java.util.HashSet)2