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]

Reply via email to