use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate in project hive by apache.
the class HiveRelDecorrelator method decorrelateRel.
public Frame decorrelateRel(Filter rel) {
//
// Rewrite logic:
//
// 1. If a Filter references a correlated field in its filter
// condition, rewrite the Filter to be
// Filter
// Join(cross product)
// OriginalFilterInput
// ValueGenerator(produces distinct sets of correlated variables)
// and rewrite the correlated fieldAccess in the filter condition to
// reference the Join output.
//
// 2. If Filter does not reference correlated variables, simply
// rewrite the filter condition using new 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;
}
Frame oldInputFrame = frame;
// and produce the correlated variables in the new output.
if (cm.mapRefRelToCorRef.containsKey(rel)) {
frame = decorrelateInputWithValueGenerator(rel);
}
boolean valueGenerator = true;
if (frame.r == oldInputFrame.r) {
// this means correated value generator wasn't generated
valueGenerator = false;
}
boolean isSemiJoin = false;
if (oldInput instanceof LogicalCorrelate) {
isSemiJoin = ((LogicalCorrelate) oldInput).getJoinType() == JoinRelType.SEMI || ((LogicalCorrelate) oldInput).getJoinType() == JoinRelType.ANTI;
}
if (isSemiJoin && !cm.mapRefRelToCorRef.containsKey(rel)) {
// this conditions need to be pushed into semi-join since this condition
// corresponds to IN
Join join = ((Join) frame.r);
final List<RexNode> conditions = new ArrayList<>();
RexNode joinCond = join.getCondition();
conditions.add(joinCond);
conditions.add(decorrelateExpr(rel.getCondition(), valueGenerator));
final RexNode condition = RexUtil.composeConjunction(rexBuilder, conditions, false);
RelNode newRel;
if (((LogicalCorrelate) oldInput).getJoinType() == JoinRelType.SEMI) {
newRel = HiveSemiJoin.getSemiJoin(frame.r.getCluster(), frame.r.getTraitSet(), join.getLeft(), join.getRight(), condition);
} else {
newRel = HiveAntiJoin.getAntiJoin(frame.r.getCluster(), frame.r.getTraitSet(), join.getLeft(), join.getRight(), condition);
}
return register(rel, newRel, frame.oldToNewOutputs, frame.corDefOutputs);
}
// Replace the filter expression to reference output of the join
// Map filter to the new filter over join
relBuilder.push(frame.r).filter((decorrelateExpr(rel.getCondition(), valueGenerator)));
// input rel.
return register(rel, relBuilder.build(), frame.oldToNewOutputs, frame.corDefOutputs);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate in project hive by apache.
the class HiveRelDecorrelator method decorrelateRel.
/**
* Rewrite LogicalFilter.
*
* @param rel the filter rel to rewrite
*/
public Frame decorrelateRel(LogicalFilter rel) {
//
// Rewrite logic:
//
// 1. If a LogicalFilter references a correlated field in its filter
// condition, rewrite the LogicalFilter to be
// LogicalFilter
// LogicalJoin(cross product)
// OriginalFilterInput
// ValueGenerator(produces distinct sets of correlated variables)
// and rewrite the correlated fieldAccess in the filter condition to
// reference the LogicalJoin output.
//
// 2. If LogicalFilter does not reference correlated variables, simply
// rewrite the filter condition using new 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;
}
// and produce the correlated variables in the new output.
if (cm.mapRefRelToCorRef.containsKey(rel)) {
frame = decorrelateInputWithValueGenerator(rel);
}
boolean valueGenerator = true;
if (frame.r == oldInput) {
// this means correated value generator wasn't generated
valueGenerator = false;
}
if (oldInput instanceof LogicalCorrelate && ((LogicalCorrelate) oldInput).getJoinType() == SemiJoinType.SEMI && !cm.mapRefRelToCorRef.containsKey(rel)) {
// this conditions need to be pushed into semi-join since this condition
// corresponds to IN
HiveSemiJoin join = ((HiveSemiJoin) frame.r);
final List<RexNode> conditions = new ArrayList<>();
RexNode joinCond = join.getCondition();
conditions.add(joinCond);
conditions.add(decorrelateExpr(rel.getCondition(), valueGenerator));
final RexNode condition = RexUtil.composeConjunction(rexBuilder, conditions, false);
RelNode newRel = HiveSemiJoin.getSemiJoin(frame.r.getCluster(), frame.r.getTraitSet(), join.getLeft(), join.getRight(), condition, join.getLeftKeys(), join.getRightKeys());
return register(rel, newRel, frame.oldToNewOutputs, frame.corDefOutputs);
}
// Replace the filter expression to reference output of the join
// Map filter to the new filter over join
relBuilder.push(frame.r).filter(decorrelateExpr(rel.getCondition(), valueGenerator));
// input rel.
return register(rel, relBuilder.build(), frame.oldToNewOutputs, frame.corDefOutputs);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate in project hive by apache.
the class HiveRelDecorrelator method createCopyHook.
private Function2<RelNode, RelNode, Void> createCopyHook() {
return new Function2<RelNode, RelNode, Void>() {
@Override
public Void apply(RelNode oldNode, RelNode newNode) {
if (cm.mapRefRelToCorRef.containsKey(oldNode)) {
final CorelMap corelMap = new CorelMapBuilder().build(newNode);
// to figure out new cor refs and put that into map
if (!corelMap.mapRefRelToCorRef.isEmpty()) {
cm.mapRefRelToCorRef.putAll(newNode, corelMap.mapRefRelToCorRef.get(newNode));
}
}
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;
}
};
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate in project beam by apache.
the class BeamUnnestRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
LogicalCorrelate correlate = call.rel(0);
RelNode outer = call.rel(1);
RelNode uncollect = call.rel(2);
if (correlate.getCorrelationId().getId() != 0) {
// Only one level of correlation nesting is supported
return;
}
if (correlate.getRequiredColumns().cardinality() != 1) {
// can only unnest a single column
return;
}
if (correlate.getJoinType() != JoinRelType.INNER) {
return;
}
if (!(uncollect instanceof Uncollect)) {
// Drop projection
uncollect = ((SingleRel) uncollect).getInput();
if (uncollect instanceof RelSubset) {
uncollect = ((RelSubset) uncollect).getOriginal();
}
if (!(uncollect instanceof Uncollect)) {
return;
}
}
RelNode project = ((Uncollect) uncollect).getInput();
if (project instanceof RelSubset) {
project = ((RelSubset) project).getOriginal();
}
if (!(project instanceof LogicalProject)) {
return;
}
if (((LogicalProject) project).getProjects().size() != 1) {
// can only unnest a single column
return;
}
RexNode exp = ((LogicalProject) project).getProjects().get(0);
if (!(exp instanceof RexFieldAccess)) {
return;
}
RexFieldAccess fieldAccess = (RexFieldAccess) exp;
// Innermost field index comes first (e.g. struct.field1.field2 => [2, 1])
ImmutableList.Builder<Integer> fieldAccessIndices = ImmutableList.builder();
while (true) {
fieldAccessIndices.add(fieldAccess.getField().getIndex());
if (!(fieldAccess.getReferenceExpr() instanceof RexFieldAccess)) {
break;
}
fieldAccess = (RexFieldAccess) fieldAccess.getReferenceExpr();
}
call.transformTo(new BeamUnnestRel(correlate.getCluster(), correlate.getTraitSet().replace(BeamLogicalConvention.INSTANCE), convert(outer, outer.getTraitSet().replace(BeamLogicalConvention.INSTANCE)), call.rel(2).getRowType(), fieldAccessIndices.build()));
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate in project calcite by apache.
the class SqlToRelConverter method createJoin.
protected RelNode createJoin(Blackboard bb, RelNode leftRel, RelNode rightRel, RexNode joinCond, JoinRelType joinType) {
assert joinCond != null;
final CorrelationUse p = getCorrelationUse(bb, rightRel);
if (p != null) {
LogicalCorrelate corr = LogicalCorrelate.create(leftRel, p.r, p.id, p.requiredColumns, SemiJoinType.of(joinType));
if (!joinCond.isAlwaysTrue()) {
final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY;
return factory.createFilter(corr, joinCond);
}
return corr;
}
final Join originalJoin = (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel, rightRel, joinCond, ImmutableSet.<CorrelationId>of(), joinType, false);
return RelOptUtil.pushDownJoinConditions(originalJoin, relBuilder);
}
Aggregations