mihaibudiu commented on code in PR #4750:
URL: https://github.com/apache/calcite/pull/4750#discussion_r2715355108


##########
core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java:
##########
@@ -1952,53 +1951,147 @@ private static boolean isWidening(RelDataType type, 
RelDataType type1) {
       return null;
     }
 
+    // 1. Collect all CorRefs involved
+    final CorelMap localCorelMap = new CorelMapBuilder().build(rel);
+    final List<CorRef> corVarList = new 
ArrayList<>(localCorelMap.mapRefRelToCorRef.values());
+    Collections.sort(corVarList);
+
+    // 2. Ensure CorVars are present in inputs (adding ValueGenerators if 
needed)
     Frame newLeftFrame = leftFrame;
-    boolean joinConditionContainsFieldAccess = 
RexUtil.containsFieldAccess(rel.getCondition());
-    if (joinConditionContainsFieldAccess && isCorVarDefined) {
-      final CorelMap localCorelMap = new CorelMapBuilder().build(rel);
-      final List<CorRef> corVarList = new 
ArrayList<>(localCorelMap.mapRefRelToCorRef.values());
-      Collections.sort(corVarList);
+    Frame newRightFrame = rightFrame;
+    final NavigableMap<CorDef, Integer> leftCorDefOutputs = new TreeMap<>();
+    final NavigableMap<CorDef, Integer> rightCorDefOutputs = new TreeMap<>();
+    boolean generatesNullsOnRight = rel.getJoinType().generatesNullsOnRight();
+    boolean generatesNullsOnLeft = rel.getJoinType().generatesNullsOnLeft();
+
+    if (isCorVarDefined) {
+      // ensure CorVars are present in left input
+      if (generatesNullsOnRight || 
RexUtil.containsFieldAccess(rel.getCondition())) {
+        newLeftFrame = supplyMissingCorVars(oldLeft, leftFrame, corVarList, 
leftCorDefOutputs);
+        rightCorDefOutputs.putAll(rightFrame.corDefOutputs);
+      }
+      // ensure CorVars are present in right input
+      if (generatesNullsOnLeft) {
+        newRightFrame = supplyMissingCorVars(oldRight, rightFrame, corVarList, 
rightCorDefOutputs);
+        leftCorDefOutputs.putAll(leftFrame.corDefOutputs);
+      }
+    } else {
+      leftCorDefOutputs.putAll(leftFrame.corDefOutputs);
+      rightCorDefOutputs.putAll(rightFrame.corDefOutputs);
+    }
+
+    // 3. Build Join Conditions
+    final List<RexNode> joinConditions = new ArrayList<>();
+    RexNode originalCond = decorrelateExpr(castNonNull(currentRel), map, cm, 
rel.getCondition());
+    if (!originalCond.isAlwaysTrue()) {
+      joinConditions.add(originalCond);
+    }
 
-      final NavigableMap<CorDef, Integer> corDefOutputs = new TreeMap<>();
-      newLeftFrame = createFrameWithValueGenerator(oldLeft, leftFrame, 
corVarList, corDefOutputs);
+    if (generatesNullsOnLeft || generatesNullsOnRight) {
+      List<RexNode> conds =
+          buildCorDefJoinConditions(leftCorDefOutputs, rightCorDefOutputs,
+              newLeftFrame.r, newRightFrame.r, relBuilder);
+      joinConditions.addAll(conds);
     }
 
+    RexNode finalCondition = joinConditions.isEmpty()
+        ? relBuilder.literal(true)
+        : RexUtil.composeConjunction(relBuilder.getRexBuilder(), 
joinConditions);
+
     RelNode newJoin = relBuilder
         .push(newLeftFrame.r)
-        .push(rightFrame.r)
-        .join(rel.getJoinType(),
-            decorrelateExpr(castNonNull(currentRel), map, cm, 
rel.getCondition()),
-            ImmutableSet.of())
+        .push(newRightFrame.r)
+        .join(rel.getJoinType(), finalCondition, ImmutableSet.of())
         .build();
 
-    // Create the mapping between the output of the old correlation rel
-    // and the new join rel
-    Map<Integer, Integer> mapOldToNewOutputs = new HashMap<>();
-
-    int oldLeftFieldCount = oldLeft.getRowType().getFieldCount();
+    // 4. Handle Full Join Projections (Coalesce)
+    NavigableMap<CorDef, Integer> corDefOutputs = new 
TreeMap<>(newLeftFrame.corDefOutputs);
     int newLeftFieldCount = newLeftFrame.r.getRowType().getFieldCount();
+    if (rel.getJoinType() == JoinRelType.FULL && isCorVarDefined) {

Review Comment:
   here it would help if you could show in a comment a fragment of a plan that 
gets produced by this code fragment.



-- 
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