Java源码示例:org.apache.calcite.rel.core.Correlate
示例1
/** @see #dispatch */
public Result visit(Correlate e) {
final Result leftResult =
visitChild(0, e.getLeft())
.resetAlias(e.getCorrelVariable(), e.getRowType());
parseCorrelTable(e, leftResult);
final Result rightResult = visitChild(1, e.getRight());
final SqlNode rightLateral =
SqlStdOperatorTable.LATERAL.createCall(POS, rightResult.node);
final SqlNode rightLateralAs =
SqlStdOperatorTable.AS.createCall(POS, rightLateral,
new SqlIdentifier(rightResult.neededAlias, POS));
final SqlNode join =
new SqlJoin(POS,
leftResult.asFrom(),
SqlLiteral.createBoolean(false, POS),
JoinType.COMMA.symbol(POS),
rightLateralAs,
JoinConditionType.NONE.symbol(POS),
null);
return result(join, leftResult, rightResult);
}
示例2
private Function2<RelNode, RelNode, Void> createCopyHook() {
return (oldNode, newNode) -> {
if (cm.mapRefRelToCorRef.containsKey(oldNode)) {
cm.mapRefRelToCorRef.putAll(newNode,
cm.mapRefRelToCorRef.get(oldNode));
}
if (oldNode instanceof Correlate
&& newNode instanceof Correlate) {
Correlate oldCor = (Correlate) oldNode;
CorrelationId c = oldCor.getCorrelationId();
if (cm.mapCorToCorRel.get(c) == oldNode) {
cm.mapCorToCorRel.put(c, newNode);
}
if (generatedCorRels.contains(oldNode)) {
generatedCorRels.add((Correlate) newNode);
}
}
return null;
};
}
示例3
@Test void testCorrelateUniqueKeys() {
final String sql = "select *\n"
+ "from (select distinct deptno from emp) as e,\n"
+ " lateral (\n"
+ " select * from dept where dept.deptno = e.deptno)";
final RelNode rel = convertSql(sql);
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertThat(rel, isA((Class) Project.class));
final Project project = (Project) rel;
final Set<ImmutableBitSet> result = mq.getUniqueKeys(project);
assertThat(result, sortsAs("[{0}]"));
if (false) {
assertUniqueConsistent(project);
}
assertThat(project.getInput(), isA((Class) Correlate.class));
final Correlate correlate = (Correlate) project.getInput();
final Set<ImmutableBitSet> result2 = mq.getUniqueKeys(correlate);
assertThat(result2, sortsAs("[{0}]"));
if (false) {
assertUniqueConsistent(correlate);
}
}
示例4
/**
* Creates a FilterCorrelateRule.
*/
public FilterCorrelateRule(RelBuilderFactory builderFactory) {
super(
operand(Filter.class,
operand(Correlate.class, RelOptRule.any())),
builderFactory, "FilterCorrelateRule");
}
示例5
/**
* Pulls a {@link Project} above a {@link Correlate} from its RHS input.
* Enforces nullability for join output.
*
* @param correlate Correlate
* @param project the original project as the RHS input of the join
* @param isCount Positions which are calls to the <code>COUNT</code>
* aggregation function
* @return the subtree with the new Project at the root
*/
private RelNode aggregateCorrelatorOutput(Correlate correlate, LogicalProject project, Set<Integer> isCount) {
final RelNode left = correlate.getLeft();
final JoinRelType joinType = correlate.getJoinType().toJoinType();
// now create the new project
final List<Pair<RexNode, String>> newProjects = new ArrayList<>();
// Project everything from the LHS and then those from the original
// project
final List<RelDataTypeField> leftInputFields = left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjects.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator = joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr = removeCorrelationExpr(pair.left, projectPulledAboveLeftCorrelator, isCount);
newProjects.add(Pair.of(newProjExpr, pair.right));
}
return relBuilder.push(correlate).projectNamed(Pair.left(newProjects), Pair.right(newProjects), true).build();
}
示例6
@Override
public boolean matches(RelOptRuleCall call) {
Correlate correlate = call.rel(1);
// No need to call ProjectCorrelateTransposeRule if the current lateralJoin contains excludeCorrelationColumn set to true.
// This is needed as the project push into Lateral join rule changes the output row type which will fail assertions in ProjectCorrelateTransposeRule.
if (correlate instanceof DrillLateralJoinRel &&
((DrillLateralJoinRel)correlate).excludeCorrelateColumn) {
return false;
}
return true;
}
示例7
@Override
public Correlate copy(RelTraitSet traitSet,
RelNode left, RelNode right, CorrelationId correlationId,
ImmutableBitSet requiredColumns, SemiJoinType joinType) {
return new DrillLateralJoinRel(this.getCluster(), this.getTraitSet(), left, right, this.excludeCorrelateColumn, correlationId, requiredColumns,
this.getJoinType());
}
示例8
@Override
public Correlate copy(RelTraitSet traitSet,
RelNode left, RelNode right, CorrelationId correlationId,
ImmutableBitSet requiredColumns, SemiJoinType joinType) {
return new LateralJoinPrel(this.getCluster(), this.getTraitSet(), left, right, this.excludeCorrelateColumn, correlationId, requiredColumns,
this.getJoinType());
}
示例9
/**
* Pulls a {@link Project} above a {@link Correlate} from its RHS input.
* Enforces nullability for join output.
*
* @param correlate Correlate
* @param project the original project as the RHS input of the join
* @param isCount Positions which are calls to the <code>COUNT</code>
* aggregation function
* @return the subtree with the new Project at the root
*/
private RelNode aggregateCorrelatorOutput(
Correlate correlate,
LogicalProject project,
Set<Integer> isCount) {
final RelNode left = correlate.getLeft();
final JoinRelType joinType = correlate.getJoinType();
// now create the new project
final List<Pair<RexNode, String>> newProjects = new ArrayList<>();
// Project everything from the LHS and then those from the original
// project
final List<RelDataTypeField> leftInputFields =
left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjects.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator =
joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr =
removeCorrelationExpr(
pair.left,
projectPulledAboveLeftCorrelator,
isCount);
newProjects.add(Pair.of(newProjExpr, pair.right));
}
return relBuilder.push(correlate)
.projectNamed(Pair.left(newProjects), Pair.right(newProjects), true)
.build();
}
示例10
/**
* Pulls a {@link Project} above a {@link Correlate} from its RHS input.
* Enforces nullability for join output.
*
* @param correlate Correlate
* @param project the original project as the RHS input of the join
* @param isCount Positions which are calls to the <code>COUNT</code>
* aggregation function
* @return the subtree with the new Project at the root
*/
private RelNode aggregateCorrelatorOutput(
Correlate correlate,
LogicalProject project,
Set<Integer> isCount) {
final RelNode left = correlate.getLeft();
final JoinRelType joinType = correlate.getJoinType();
// now create the new project
final List<Pair<RexNode, String>> newProjects = new ArrayList<>();
// Project everything from the LHS and then those from the original
// project
final List<RelDataTypeField> leftInputFields =
left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjects.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator =
joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr =
removeCorrelationExpr(
pair.left,
projectPulledAboveLeftCorrelator,
isCount);
newProjects.add(Pair.of(newProjExpr, pair.right));
}
return relBuilder.push(correlate)
.projectNamed(Pair.left(newProjects), Pair.right(newProjects), true)
.build();
}
示例11
@Override
public Correlate copy(RelTraitSet traitSet,
RelNode left, RelNode right, CorrelationId correlationId,
ImmutableBitSet requiredColumns, SemiJoinType joinType) {
return new CorrelateRel(getCluster(), traitSet, left, right,
correlationId, requiredColumns, joinType);
}
示例12
public final T traverse(RelNode n) throws Exception {
List<T> inputStreams = new ArrayList<>();
for (RelNode input : n.getInputs()) {
inputStreams.add(traverse(input));
}
if (n instanceof Aggregate) {
return visitAggregate((Aggregate) n, inputStreams);
} else if (n instanceof Calc) {
return visitCalc((Calc) n, inputStreams);
} else if (n instanceof Collect) {
return visitCollect((Collect) n, inputStreams);
} else if (n instanceof Correlate) {
return visitCorrelate((Correlate) n, inputStreams);
} else if (n instanceof Delta) {
return visitDelta((Delta) n, inputStreams);
} else if (n instanceof Exchange) {
return visitExchange((Exchange) n, inputStreams);
} else if (n instanceof Project) {
return visitProject((Project) n, inputStreams);
} else if (n instanceof Filter) {
return visitFilter((Filter) n, inputStreams);
} else if (n instanceof Sample) {
return visitSample((Sample) n, inputStreams);
} else if (n instanceof Sort) {
return visitSort((Sort) n, inputStreams);
} else if (n instanceof TableModify) {
return visitTableModify((TableModify) n, inputStreams);
} else if (n instanceof TableScan) {
return visitTableScan((TableScan) n, inputStreams);
} else if (n instanceof Uncollect) {
return visitUncollect((Uncollect) n, inputStreams);
} else if (n instanceof Window) {
return visitWindow((Window) n, inputStreams);
} else if (n instanceof Join) {
return visitJoin((Join) n, inputStreams);
} else {
return defaultValue(n, inputStreams);
}
}
示例13
/**
* Creates a FilterCorrelateRule.
*/
public FilterCorrelateRule(RelBuilderFactory builderFactory) {
super(
operand(Filter.class,
operand(Correlate.class, RelOptRule.any())),
builderFactory, "FilterCorrelateRule");
}
示例14
public ProjectCorrelateTransposeRule(
PushProjector.ExprCondition preserveExprCondition,
RelBuilderFactory relFactory) {
super(
operand(Project.class,
operand(Correlate.class, any())),
relFactory, null);
this.preserveExprCondition = preserveExprCondition;
}
示例15
/**
* Pulls a {@link Project} above a {@link Correlate} from its RHS input.
* Enforces nullability for join output.
*
* @param correlate Correlate
* @param project the original project as the RHS input of the join
* @param isCount Positions which are calls to the <code>COUNT</code>
* aggregation function
* @return the subtree with the new Project at the root
*/
private RelNode aggregateCorrelatorOutput(
Correlate correlate,
Project project,
Set<Integer> isCount) {
final RelNode left = correlate.getLeft();
final JoinRelType joinType = correlate.getJoinType();
// now create the new project
final List<Pair<RexNode, String>> newProjects = new ArrayList<>();
// Project everything from the LHS and then those from the original
// project
final List<RelDataTypeField> leftInputFields =
left.getRowType().getFieldList();
for (int i = 0; i < leftInputFields.size(); i++) {
newProjects.add(RexInputRef.of2(i, leftInputFields));
}
// Marked where the projected expr is coming from so that the types will
// become nullable for the original projections which are now coming out
// of the nullable side of the OJ.
boolean projectPulledAboveLeftCorrelator =
joinType.generatesNullsOnRight();
for (Pair<RexNode, String> pair : project.getNamedProjects()) {
RexNode newProjExpr =
removeCorrelationExpr(
pair.left,
projectPulledAboveLeftCorrelator,
isCount);
newProjects.add(Pair.of(newProjExpr, pair.right));
}
return relBuilder.push(correlate)
.projectNamed(Pair.left(newProjects), Pair.right(newProjects), true)
.build();
}
示例16
@Override public RexNode visitInputRef(RexInputRef inputRef) {
if (currentRel instanceof Correlate) {
// if this rel references corVar
// and now it needs to be rewritten
// it must have been pulled above the Correlate
// replace the input ref to account for the LHS of the
// Correlate
final int leftInputFieldCount =
((Correlate) currentRel).getLeft().getRowType()
.getFieldCount();
RelDataType newType = inputRef.getType();
if (projectPulledAboveLeftCorrelator) {
newType =
typeFactory.createTypeWithNullability(newType, true);
}
int pos = inputRef.getIndex();
RexInputRef newInputRef =
new RexInputRef(leftInputFieldCount + pos, newType);
if ((isCount != null) && isCount.contains(pos)) {
return createCaseExpression(
newInputRef,
rexBuilder.makeExactLiteral(BigDecimal.ZERO),
newInputRef);
} else {
return newInputRef;
}
}
return inputRef;
}
示例17
RemoveCorrelationForScalarProjectRule(RelBuilderFactory relBuilderFactory) {
super(
operand(Correlate.class,
operand(RelNode.class, any()),
operand(Aggregate.class,
operand(Project.class,
operand(RelNode.class, any())))),
relBuilderFactory, null);
}
示例18
RemoveCorrelationForScalarAggregateRule(RelBuilderFactory relBuilderFactory) {
super(
operand(Correlate.class,
operand(RelNode.class, any()),
operand(Project.class,
operandJ(Aggregate.class, null, Aggregate::isSimple,
operand(Project.class,
operand(RelNode.class, any()))))),
relBuilderFactory, null);
}
示例19
AdjustProjectForCountAggregateRule(boolean flavor,
RelBuilderFactory relBuilderFactory) {
super(
flavor
? operand(Correlate.class,
operand(RelNode.class, any()),
operand(Project.class,
operand(Aggregate.class, any())))
: operand(Correlate.class,
operand(RelNode.class, any()),
operand(Aggregate.class, any())),
relBuilderFactory, null);
this.flavor = flavor;
}
示例20
@Override public RelNode visit(RelNode other) {
if (other instanceof Join) {
Join join = (Join) other;
try {
stack.push(join);
join.getCondition().accept(rexVisitor(join));
} finally {
stack.pop();
}
return visitJoin(join);
} else if (other instanceof Correlate) {
Correlate correlate = (Correlate) other;
mapCorToCorRel.put(correlate.getCorrelationId(), correlate);
return visitJoin(correlate);
} else if (other instanceof Filter) {
Filter filter = (Filter) other;
try {
stack.push(filter);
filter.getCondition().accept(rexVisitor(filter));
} finally {
stack.pop();
}
} else if (other instanceof Project) {
Project project = (Project) other;
try {
stack.push(project);
for (RexNode node : project.getProjects()) {
node.accept(rexVisitor(project));
}
} finally {
stack.pop();
}
}
return super.visit(other);
}
示例21
public Set<ImmutableBitSet> getUniqueKeys(Correlate rel, RelMetadataQuery mq,
boolean ignoreNulls) {
return mq.getUniqueKeys(rel.getLeft(), ignoreNulls);
}
示例22
public void onMatch(RelOptRuleCall call) {
final Filter filter = call.rel(0);
final Correlate corr = call.rel(1);
final List<RexNode> aboveFilters =
RelOptUtil.conjunctions(filter.getCondition());
final List<RexNode> leftFilters = new ArrayList<>();
final List<RexNode> rightFilters = new ArrayList<>();
// Try to push down above filters. These are typically where clause
// filters. They can be pushed down if they are not on the NULL
// generating side.
RelOptUtil.classifyFilters(
corr,
aboveFilters,
JoinRelType.INNER,
false,
!corr.getJoinType().toJoinType().generatesNullsOnLeft(),
!corr.getJoinType().toJoinType().generatesNullsOnRight(),
aboveFilters,
leftFilters,
rightFilters);
if (leftFilters.isEmpty()
&& rightFilters.isEmpty()) {
// no filters got pushed
return;
}
// Create Filters on top of the children if any filters were
// pushed to them.
final RexBuilder rexBuilder = corr.getCluster().getRexBuilder();
final RelBuilder relBuilder = call.builder();
final RelNode leftRel =
relBuilder.push(corr.getLeft()).filter(leftFilters).build();
final RelNode rightRel =
relBuilder.push(corr.getRight()).filter(rightFilters).build();
// Create the new Correlate
RelNode newCorrRel =
corr.copy(corr.getTraitSet(), ImmutableList.of(leftRel, rightRel));
call.getPlanner().onCopy(corr, newCorrRel);
if (!leftFilters.isEmpty()) {
call.getPlanner().onCopy(filter, leftRel);
}
if (!rightFilters.isEmpty()) {
call.getPlanner().onCopy(filter, rightRel);
}
// Create a Filter on top of the join if needed
relBuilder.push(newCorrRel);
relBuilder.filter(
RexUtil.fixUp(rexBuilder, aboveFilters,
RelOptUtil.getFieldTypeList(relBuilder.peek().getRowType())));
call.transformTo(relBuilder.build());
}
示例23
public ProjectCorrelateTransposeRule(PushProjector.ExprCondition preserveExprCondition,
RelBuilderFactory relFactory) {
super(operand(Project.class, operand(Correlate.class, any())), relFactory, null);
this.preserveExprCondition = preserveExprCondition;
}
示例24
@Override
public void onMatch(RelOptRuleCall call) {
Project origProj = call.rel(0);
final Correlate corr = call.rel(1);
// locate all fields referenced in the projection
// determine which inputs are referenced in the projection;
// if all fields are being referenced and there are no
// special expressions, no point in proceeding any further
PushProjector pushProject = new PushProjector(origProj, call.builder().literal(true), corr,
preserveExprCondition, call.builder());
if (pushProject.locateAllRefs()) {
return;
}
// create left and right projections, projecting only those
// fields referenced on each side
RelNode leftProjRel = pushProject.createProjectRefsAndExprs(corr.getLeft(), true, false);
RelNode rightProjRel = pushProject.createProjectRefsAndExprs(corr.getRight(), true, true);
Map<Integer, Integer> requiredColsMap = new HashMap<>();
// adjust requiredColumns that reference the projected columns
int[] adjustments = pushProject.getAdjustments();
BitSet updatedBits = new BitSet();
for (Integer col : corr.getRequiredColumns()) {
int newCol = col + adjustments[col];
updatedBits.set(newCol);
requiredColsMap.put(col, newCol);
}
RexBuilder rexBuilder = call.builder().getRexBuilder();
CorrelationId correlationId = corr.getCluster().createCorrel();
RexCorrelVariable rexCorrel = (RexCorrelVariable) rexBuilder.makeCorrel(leftProjRel.getRowType(),
correlationId);
// updates RexCorrelVariable and sets actual RelDataType for RexFieldAccess
rightProjRel = rightProjRel.accept(new RelNodesExprsHandler(
new RexFieldAccessReplacer(corr.getCorrelationId(), rexCorrel, rexBuilder, requiredColsMap)));
// create a new correlate with the projected children
Correlate newCorrRel = corr.copy(corr.getTraitSet(), leftProjRel, rightProjRel, correlationId,
ImmutableBitSet.of(BitSets.toIter(updatedBits)), corr.getJoinType());
// put the original project on top of the correlate, converting it to
// reference the modified projection list
RelNode topProject = pushProject.createNewProject(newCorrRel, adjustments);
call.transformTo(topProject);
}
示例25
@Override
public RelNode visit(LogicalCorrelate correlate) {
RelNode left = correlate.getLeft().accept(this);
leftInputs.put(correlate.getCorrelationId(), left);
RelNode right = correlate.getRight().accept(this);
// if right input wasn't changed or left input wasn't changed
// after rewriting right input, no need to create Correlate with new CorrelationId
if (correlate.getRight() == right
|| left == leftInputs.get(correlate.getCorrelationId())) {
if (correlate.getLeft() == left) {
return correlate;
}
// changed only inputs, but CorrelationId left the same
return correlate.copy(correlate.getTraitSet(), Arrays.asList(left, right));
}
Correlate newCorrelate = correlate.copy(correlate.getTraitSet(),
leftInputs.get(correlate.getCorrelationId()), right,
updatedCorrelationIds.get(correlate.getCorrelationId()),
ImmutableBitSet.of(left.getRowType().getFieldCount()), correlate.getJoinType());
RelBuilder builder = DrillRelFactories.LOGICAL_BUILDER.create(correlate.getCluster(), null);
builder.push(newCorrelate);
List<RexNode> topProjectExpressions = left.getRowType().getFieldList().stream()
.map(field -> builder.getRexBuilder().makeInputRef(newCorrelate, field.getIndex()))
.collect(Collectors.toList());
//Accommodate the new $COMPLEX_FIELD_NAME column.
int rightStartIndex = left.getRowType().getFieldList().size() + 1;
switch (correlate.getJoinType()) {
case LEFT:
case INNER:
// adds field from the right input of correlate to the top project
topProjectExpressions.addAll(right.getRowType().getFieldList().stream()
.map(field -> builder.getRexBuilder().makeInputRef(newCorrelate, field.getIndex() + rightStartIndex))
.collect(Collectors.toList()));
// fall through
case ANTI:
case SEMI:
builder.project(topProjectExpressions, correlate.getRowType().getFieldNames());
}
return builder.build();
}
示例26
public T visitCorrelate(Correlate correlate, List<T> inputStreams) throws Exception {
return defaultValue(correlate, inputStreams);
}
示例27
public InstanceAccessByIdRule() {
super(operand(Correlate.class, any()));
}
示例28
public Multimap<Class<? extends RelNode>, RelNode> getNodeTypes(Correlate rel,
RelMetadataQuery mq) {
return getNodeTypes(rel, Correlate.class, mq);
}
示例29
public Set<ImmutableBitSet> getUniqueKeys(Correlate rel, RelMetadataQuery mq,
boolean ignoreNulls) {
return mq.getUniqueKeys(rel.getLeft(), ignoreNulls);
}
示例30
public void onMatch(RelOptRuleCall call) {
final Filter filter = call.rel(0);
final Correlate corr = call.rel(1);
final List<RexNode> aboveFilters =
RelOptUtil.conjunctions(filter.getCondition());
final List<RexNode> leftFilters = new ArrayList<>();
final List<RexNode> rightFilters = new ArrayList<>();
// Try to push down above filters. These are typically where clause
// filters. They can be pushed down if they are not on the NULL
// generating side.
RelOptUtil.classifyFilters(
corr,
aboveFilters,
corr.getJoinType(),
false,
true,
!corr.getJoinType().generatesNullsOnRight(),
aboveFilters,
leftFilters,
rightFilters);
if (leftFilters.isEmpty()
&& rightFilters.isEmpty()) {
// no filters got pushed
return;
}
// Create Filters on top of the children if any filters were
// pushed to them.
final RexBuilder rexBuilder = corr.getCluster().getRexBuilder();
final RelBuilder relBuilder = call.builder();
final RelNode leftRel =
relBuilder.push(corr.getLeft()).filter(leftFilters).build();
final RelNode rightRel =
relBuilder.push(corr.getRight()).filter(rightFilters).build();
// Create the new Correlate
RelNode newCorrRel =
corr.copy(corr.getTraitSet(), ImmutableList.of(leftRel, rightRel));
call.getPlanner().onCopy(corr, newCorrRel);
if (!leftFilters.isEmpty()) {
call.getPlanner().onCopy(filter, leftRel);
}
if (!rightFilters.isEmpty()) {
call.getPlanner().onCopy(filter, rightRel);
}
// Create a Filter on top of the join if needed
relBuilder.push(newCorrRel);
relBuilder.filter(
RexUtil.fixUp(rexBuilder, aboveFilters,
RelOptUtil.getFieldTypeList(relBuilder.peek().getRowType())));
call.transformTo(relBuilder.build());
}