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;
}
};
}
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;
}
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);
}
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;
}
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;
}
};
}
Aggregations