use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class RelFieldTrimmer method trimChild.
/**
* Trims the fields of an input relational expression.
*
* @param rel Relational expression
* @param input Input relational expression, whose fields to trim
* @param fieldsUsed Bitmap of fields needed by the consumer
* @return New relational expression and its field mapping
*/
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
// Fields that define the collation cannot be discarded.
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
final ImmutableList<RelCollation> collations = mq.collations(input);
if (collations != null) {
for (RelCollation collation : collations) {
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
}
}
}
// fields.
for (final CorrelationId correlation : rel.getVariablesSet()) {
rel.accept(new CorrelationReferenceFinder() {
protected RexNode handle(RexFieldAccess fieldAccess) {
final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
if (v.id.equals(correlation)) {
fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
}
return fieldAccess;
}
});
}
return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class RelFieldTrimmer method result.
protected TrimResult result(RelNode r, final Mapping mapping) {
final RelBuilder relBuilder = REL_BUILDER.get();
final RexBuilder rexBuilder = relBuilder.getRexBuilder();
for (final CorrelationId correlation : r.getVariablesSet()) {
r = r.accept(new CorrelationReferenceFinder() {
protected RexNode handle(RexFieldAccess fieldAccess) {
final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
if (v.id.equals(correlation) && v.getType().getFieldCount() == mapping.getSourceCount()) {
final int old = fieldAccess.getField().getIndex();
final int new_ = mapping.getTarget(old);
final RelDataTypeFactory.Builder typeBuilder = relBuilder.getTypeFactory().builder();
for (int target : Util.range(mapping.getTargetCount())) {
typeBuilder.add(v.getType().getFieldList().get(mapping.getSource(target)));
}
final RexNode newV = rexBuilder.makeCorrel(typeBuilder.build(), v.id);
if (old != new_) {
return rexBuilder.makeFieldAccess(newV, new_);
}
}
return fieldAccess;
}
});
}
return new TrimResult(r, mapping);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class HiveSubQRemoveRelBuilder method join.
/** Creates a {@link org.apache.calcite.rel.core.Join} with correlating
* variables. */
public HiveSubQRemoveRelBuilder join(JoinRelType joinType, RexNode condition, Set<CorrelationId> variablesSet) {
Frame right = stack.pop();
final Frame left = stack.pop();
final RelNode join;
final boolean correlate = variablesSet.size() == 1;
RexNode postCondition = literal(true);
if (correlate) {
final CorrelationId id = Iterables.getOnlyElement(variablesSet);
final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right.rel);
if (!RelOptUtil.notContainsCorrelation(left.rel, id, Litmus.IGNORE)) {
throw new IllegalArgumentException("variable " + id + " must not be used by left input to correlation");
}
switch(joinType) {
case LEFT:
// Correlate does not have an ON clause.
// For a LEFT correlate, predicate must be evaluated first.
// For INNER, we can defer.
stack.push(right);
filter(condition.accept(new Shifter(left.rel, id, right.rel)));
right = stack.pop();
break;
default:
postCondition = condition;
}
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.of(joinType));
} else {
join = joinFactory.createJoin(left.rel, right.rel, condition, variablesSet, joinType, false);
}
final List<Pair<String, RelDataType>> pairs = new ArrayList<>();
pairs.addAll(left.right);
pairs.addAll(right.right);
stack.push(new Frame(join, ImmutableList.copyOf(pairs)));
filter(postCondition);
return this;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project flink by apache.
the class FlinkRelDecorrelator 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<Correlation> correlations, int valueGenFieldOffset, SortedMap<Correlation, Integer> mapCorVarToOutputPos) {
final Map<RelNode, List<Integer>> mapNewInputToOutputPos = new HashMap<>();
final Map<RelNode, Integer> mapNewInputToNewOffset = new HashMap<>();
// Add to map all the referenced positions (relative to each input rel).
for (Correlation 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> newLocalOutputPosList;
if (!mapNewInputToOutputPos.containsKey(newInput)) {
newLocalOutputPosList = Lists.newArrayList();
} else {
newLocalOutputPosList = mapNewInputToOutputPos.get(newInput);
}
final int newCorVarOffset = frame.oldToNewOutputPos.get(oldCorVarOffset);
// Add all unique positions referenced.
if (!newLocalOutputPosList.contains(newCorVarOffset)) {
newLocalOutputPosList.add(newCorVarOffset);
}
mapNewInputToOutputPos.put(newInput, newLocalOutputPosList);
}
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> joinedInputRelSet = Sets.newHashSet();
RelNode r = null;
for (Correlation corVar : correlations) {
final RelNode oldInput = getCorRel(corVar);
assert oldInput != null;
final RelNode newInput = map.get(oldInput).r;
assert newInput != null;
if (!joinedInputRelSet.contains(newInput)) {
RelNode project = RelOptUtil.createProject(newInput, mapNewInputToOutputPos.get(newInput));
RelNode distinct = RelOptUtil.createDistinctRel(project);
RelOptCluster cluster = distinct.getCluster();
joinedInputRelSet.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 (Correlation corVar : correlations) {
// The first input of a Correlator is always the rel defining
// the correlated variables.
final RelNode oldInput = getCorRel(corVar);
assert oldInput != null;
final Frame frame = map.get(oldInput);
final RelNode newInput = frame.r;
assert newInput != null;
final List<Integer> newLocalOutputPosList = mapNewInputToOutputPos.get(newInput);
final int newLocalOutputPos = frame.oldToNewOutputPos.get(corVar.field);
// newOutputPos is the index of the cor var in the referenced
// position list plus the offset of referenced position list of
// each newInput.
final int newOutputPos = newLocalOutputPosList.indexOf(newLocalOutputPos) + mapNewInputToNewOffset.get(newInput) + valueGenFieldOffset;
if (mapCorVarToOutputPos.containsKey(corVar)) {
assert mapCorVarToOutputPos.get(corVar) == newOutputPos;
}
mapCorVarToOutputPos.put(corVar, newOutputPos);
}
return r;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class HiveSubQRemoveRelBuilder method join.
public HiveSubQRemoveRelBuilder join(JoinRelType joinType, RexNode condition, Set<CorrelationId> variablesSet, boolean createSemiJoin) {
Frame right = stack.pop();
final Frame left = stack.pop();
final RelNode join;
final boolean correlate = variablesSet.size() == 1;
RexNode postCondition = literal(true);
if (correlate) {
final CorrelationId id = Iterables.getOnlyElement(variablesSet);
final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right.rel);
if (!RelOptUtil.notContainsCorrelation(left.rel, id, Litmus.IGNORE)) {
throw new IllegalArgumentException("variable " + id + " must not be used by left input to correlation");
}
switch(joinType) {
case LEFT:
// Correlate does not have an ON clause.
// For a LEFT correlate, predicate must be evaluated first.
// For INNER, we can defer.
stack.push(right);
filter(condition.accept(new Shifter(left.rel, id, right.rel)));
right = stack.pop();
break;
default:
postCondition = condition;
}
if (createSemiJoin) {
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.SEMI);
} else {
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.of(joinType));
}
} else {
join = joinFactory.createJoin(left.rel, right.rel, condition, variablesSet, joinType, false);
}
final List<Pair<String, RelDataType>> pairs = new ArrayList<>();
pairs.addAll(left.right);
pairs.addAll(right.right);
stack.push(new Frame(join, ImmutableList.copyOf(pairs)));
filter(postCondition);
return this;
}
Aggregations