starocean999 commented on code in PR #65682:
URL: https://github.com/apache/doris/pull/65682#discussion_r3679346770


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraphv2/HyperGraph.java:
##########
@@ -330,23 +404,75 @@ public void updateNode(int idx, Group group) {
          *      latest join edges index
          */
         private Pair<BitSet, Long> buildForDPhyper(GroupExpression 
groupExpression) {
+            return buildForDPhyper(groupExpression, false);
+        }
+
+        private Pair<BitSet, Long> buildForDPhyper(GroupExpression 
groupExpression, boolean isNullableSide) {
             // process Project
             if (isValidProject(groupExpression.getPlan())) {
                 LogicalProject<?> project = (LogicalProject<?>) 
groupExpression.getPlan();
-                Pair<BitSet, Long> res = 
buildForDPhyper(groupExpression.child(0).getLogicalExpressions().get(0));
+                Pair<BitSet, Long> res = buildForDPhyper(
+                        
groupExpression.child(0).getLogicalExpressions().get(0), isNullableSide);
+                // Start a new layer for this Project. Each source Project 
becomes one
+                // LogicalProject layer, preserving materialization boundaries 
for
+                // volatile expressions (e.g., uuid()) that 
PlanUtils.canMergeWithProjections
+                // would otherwise reject.
+                List<NamedExpression> savedLayer = 
this.currentProjectedAliasLayer;
+                this.currentProjectedAliasLayer = new ArrayList<>();
                 for (NamedExpression expr : project.getProjects()) {
                     if (expr instanceof Alias) {
-                        this.addAlias((Alias) expr, res.second);
+                        this.addAlias((Alias) expr, res.second, 
isNullableSide);
                     }
                 }
+                // Flush the layer if non-empty. If aliases for this key 
already
+                // exist, resolve cross-layer references (e.g., z = x + 1 where
+                // x was defined by an earlier Project on the same subtree) and
+                // merge into the existing single layer. Cross-layer resolution
+                // is safe because volatile/non-movable expressions are already
+                // excluded by isValidProject.
+                if (!this.currentProjectedAliasLayer.isEmpty()) {
+                    long key = res.second;
+                    List<NamedExpression> existing = 
nodeToProjectedAliases.get(key);
+                    if (existing != null) {
+                        Map<Slot, Expression> replaceMap = new 
LinkedHashMap<>();
+                        for (NamedExpression a : existing) {
+                            if (a instanceof Alias) {
+                                replaceMap.put(a.toSlot(), ((Alias) 
a).child());
+                            }
+                        }
+                        for (NamedExpression expr : 
currentProjectedAliasLayer) {
+                            existing.add((NamedExpression) 
ExpressionUtils.replace(expr, replaceMap));

Review Comment:
   this is  a Fail-safe. There should not be continuous project nodes in 
reality. 



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