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