caicancai commented on code in PR #4779:
URL: https://github.com/apache/calcite/pull/4779#discussion_r3068888477
##########
core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java:
##########
@@ -6581,6 +6653,37 @@ private static class CorrelationUse {
}
}
+ /** Wrapper around information collected by {@link #getCorrelationInfo}. */
+ private static class ResolvedCorrelationInfo {
+ public final List<CorrelationId> correlNames;
+ public final ImmutableBitSet requiredColumns;
+ public final Map<Pair<CorrelationId, Integer>, Integer> fieldMapping;
+
+ ResolvedCorrelationInfo(List<CorrelationId> correlNames, ImmutableBitSet
requiredColumns,
+ Map<Pair<CorrelationId, Integer>, Integer> fieldMapping) {
+ this.correlNames = correlNames;
+ this.requiredColumns = requiredColumns;
+ this.fieldMapping = fieldMapping;
+ }
+ }
+
+ /** Wrapper around optionally returned results from {@link
#massageExpressionsForCorrelation}. */
+ private static class MassagedCorrelationExpressions {
+ /** Modified expressions. */
+ public final List<RexNode> exprs;
Review Comment:
private
##########
core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java:
##########
@@ -3350,29 +3351,92 @@ protected RelNode createAsofJoin(
if (correlNames.isEmpty()) {
// None of the correlating variables originated in this scope.
return null;
+ } else {
+ return new ResolvedCorrelationInfo(correlNames, requiredColumns.build(),
fieldMapping);
+ }
+ }
+
+ private @Nullable CorrelationUse getCorrelationUse(Blackboard bb, final
RelNode r0) {
+ final Set<CorrelationId> correlatedVariables =
+ RelOptUtil.getVariablesUsed(r0);
+ if (correlatedVariables.isEmpty()) {
+ return null;
+ }
+
+ ResolvedCorrelationInfo correlationInfo = getCorrelationInfo(bb,
correlatedVariables);
+ if (correlationInfo == null) {
+ // None of the correlating variables originated in this scope.
+ return null;
}
RelNode r = r0;
- if (correlNames.size() > 1) {
+ if (correlationInfo.correlNames.size() > 1) {
// The same table was referenced more than once.
// So we deduplicate.
r =
- DeduplicateCorrelateVariables.go(rexBuilder, correlNames.get(0),
- Util.skip(correlNames), r0);
+ DeduplicateCorrelateVariables.go(rexBuilder,
correlationInfo.correlNames.get(0),
+ Util.skip(correlationInfo.correlNames), r0);
// Add new node to leaves.
leaves.put(r, r.getRowType().getFieldCount());
}
// If there are field mappings (due to aggregation), rewrite the RelNode
tree
// to update correlation variable row type and field indices
- if (!fieldMapping.isEmpty()) {
+ if (!correlationInfo.fieldMapping.isEmpty()) {
r =
r.accept(
- new CorrelationFieldMappingShuttle(rexBuilder,
correlNames.get(0),
- bb.root().getRowType(), fieldMapping));
+ new CorrelationFieldMappingShuttle(rexBuilder,
correlationInfo.correlNames.get(0),
+ bb.root().getRowType(), correlationInfo.fieldMapping));
}
- return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
+ return new CorrelationUse(correlationInfo.correlNames.get(0),
correlationInfo.requiredColumns,
+ r);
+ }
+
+ /** Before building a RelNode tree with the provided expressions, detect and
resolve correlation
+ * names, rewrite expressions, and return a callback to be called after the
tree is built.
+ * Returns null if no correlation is detected.
+ */
+ private @Nullable MassagedCorrelationExpressions
massageExpressionsForCorrelation(Blackboard bb,
+ final List<RexNode> exprs) {
+ Set<CorrelationId> correlatedVariables = new HashSet<>();
+ for (RexNode e : exprs) {
+ correlatedVariables.addAll(RelOptUtil.getVariablesUsed(e));
+ }
+ if (correlatedVariables.isEmpty()) {
+ return null;
+ }
+
+ ResolvedCorrelationInfo correlationInfo = getCorrelationInfo(bb,
correlatedVariables);
+ if (correlationInfo == null) {
+ // None of the correlating variables originated in this scope.
+ return null;
+ }
+
+ List<RexNode> newExprs = new ArrayList<>(exprs);
+ Consumer<RelNode> callback = (RelNode r) -> { };
Review Comment:
The callback first assigns a null operation, which is then overridden within
the if block. If someone later inserts code between the two assignments and
uses the callback again, the incorrect (null operation) version will be used.
##########
.gitignore:
##########
@@ -33,9 +34,7 @@
/.vscode/*
# IDEA
-/out
Review Comment:
.gitignore changes should be in a separate PR
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]