github-actions[bot] commented on code in PR #65682:
URL: https://github.com/apache/doris/pull/65682#discussion_r3601957120


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraphv2/HyperGraph.java:
##########
@@ -385,15 +489,45 @@ public boolean addAlias(Alias alias, long subTreeNodes) {
             if (bitmap == 0) {
                 bitmap = subTreeNodes;
                 addToReplaceMap = false;
-                List<NamedExpression> aliasList = 
nodeToLiteralAlias.get(bitmap);
-                if (aliasList == null) {
-                    aliasList = new ArrayList<>(1);
-                    nodeToLiteralAlias.put(bitmap, aliasList);
+                // Constant aliases go into the current Project layer (set up 
by
+                // buildForDPhyper) and will be flushed to 
nodeToProjectedAliases
+                // keyed by the layer's subtree bitmap after the Project is 
processed.
+                if (currentProjectedAliasLayer != null) {
+                    currentProjectedAliasLayer.add(alias);
                 }
-                aliasList.add(alias);
             }
             Preconditions.checkArgument(bitmap > 0, "slot must belong to some 
table");
-            slotToHyperNodeMap.put(aliasSlot, bitmap);
+            // Map nullable-side alias slots to subTreeNodes instead of the 
minimal
+            // referenced bitmap. Otherwise a later join predicate like s=C.k 
sees s as
+            // {B} (its input slot) and creates a {B}--{C} edge, allowing 
DPHyp to join
+            // B and C before A — but s can only be emitted when {A,B} is 
complete.
+            // Using subTreeNodes (e.g. {A,B}) forces the predicate edge to 
require the
+            // full source subtree, matching the emission key in 
nodeToProjectedAliases.
+            // Note: always use subTreeNodes for nullable-side aliases. A 
Slot-forwarding
+            // alias (e.g. s=A.k) that shares a Project with expression 
aliases cannot
+            // safely use the minimal bitmap — its layer only emits at {A,B}, 
so exposing
+            // it as {A} would let DPHyp form predicate edges before the alias 
exists.
+            slotToHyperNodeMap.put(aliasSlot, isNullableSide ? subTreeNodes : 
bitmap);

Review Comment:
   [P1] Do not consume a projected alias across a split source endpoint
   
   Mapping `s` to its full source bitmap still permits that bitmap to be split 
between both children. For example:
   
   ```text
   X LEFT JOIN
     X
     InnerJoin(A.k = C.k, s = C.t)
       Project(A.k, B.k, coalesce(B.v, 0) AS s)  // source {A,B}
         InnerJoin(A.k = B.k)
           A
           B
       C
   ```
   
   DPHyp can build `{A,C}` via `A.k=C.k`, then combine `{A,C}` with `{B}` via 
the A-B edge. At that point `processMissedEdges` adds the unused `{A,B}--{C}` 
edge for `s=C.t`, because all of its reference nodes are in the union and it is 
not enforced-order. `proposeJoin` therefore creates `s=C.t` while neither child 
outputs ExprId `s`; only the later `proposeProject` call emits the `{A,B}` 
layer. This can leave the selected alternative with a join predicate bound to a 
missing child slot.
   
   This is distinct from the earlier minimal-endpoint cases: the endpoint is 
already `{A,B}`, but the missed-edge fallback consumes it while `{A,B}` is 
split. Reject such alternatives unless the alias layer has materialized wholly 
in one child (or safely substitute the predicate), and add a regression that 
makes `{A,C}` a connected candidate.
   



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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to