morrySnow commented on code in PR #14490:
URL: https://github.com/apache/doris/pull/14490#discussion_r1030575257


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java:
##########
@@ -845,33 +851,43 @@ public PlanFragment 
visitPhysicalProject(PhysicalProject<? extends Plan> project
             }
         }
         PlanFragment inputFragment = project.child(0).accept(this, context);
-
         List<Expr> execExprList = project.getProjects()
                 .stream()
                 .map(e -> ExpressionTranslator.translate(e, context))
                 .collect(Collectors.toList());
         // TODO: fix the project alias of an aliased relation.
-        List<Slot> slotList = project.getOutput();
-        TupleDescriptor tupleDescriptor = generateTupleDesc(slotList, null, 
context);
+
         PlanNode inputPlanNode = inputFragment.getPlanRoot();
-        // For hash join node, use vSrcToOutputSMap to describe the expression 
calculation, use
-        // vIntermediateTupleDescList as input, and set vOutputTupleDesc as 
the final output.
-        // TODO: HashJoinNode's be implementation is not support projection 
yet, remove this after when supported.
-        if (inputPlanNode instanceof HashJoinNode) {
-            HashJoinNode hashJoinNode = (HashJoinNode) inputPlanNode;
-            hashJoinNode.setvOutputTupleDesc(tupleDescriptor);
-            hashJoinNode.setvSrcToOutputSMap(execExprList);
-            return inputFragment;
-        }
-        if (inputPlanNode instanceof NestedLoopJoinNode) {
-            NestedLoopJoinNode nestedLoopJoinNode = (NestedLoopJoinNode) 
inputPlanNode;
-            nestedLoopJoinNode.setvOutputTupleDesc(tupleDescriptor);
-            nestedLoopJoinNode.setvSrcToOutputSMap(execExprList);
-            return inputFragment;
+        if (isUnnecessaryProject(project)) {
+            List<NamedExpression> namedExpressions = project.getProjects();
+            for (NamedExpression n : namedExpressions) {
+                for (Expression e : n.children()) {
+                    SlotRef slotRef = context.findSlotRef(((SlotReference) 
e).getExprId());
+                    SlotReference slotReference = (SlotReference) e;
+                    context.addExprIdSlotRefPair(slotReference.getExprId(), 
slotRef);
+                }
+            }
+        } else {
+            List<Slot> slotList = project.getOutput();
+            TupleDescriptor tupleDescriptor = generateTupleDesc(slotList, 
null, context);
+            inputPlanNode.setProjectList(execExprList);
+            inputPlanNode.setOutputTupleDesc(tupleDescriptor);
+            // For hash join node, use vSrcToOutputSMap to describe the 
expression calculation, use
+            // vIntermediateTupleDescList as input, and set vOutputTupleDesc 
as the final output.
+            // TODO: HashJoinNode's be implementation is not support 
projection yet, remove this after when supported.
+            if (inputPlanNode instanceof HashJoinNode) {
+                HashJoinNode hashJoinNode = (HashJoinNode) inputPlanNode;
+                hashJoinNode.setvOutputTupleDesc(tupleDescriptor);
+                hashJoinNode.setvSrcToOutputSMap(execExprList);
+                return inputFragment;
+            }
+            if (inputPlanNode instanceof NestedLoopJoinNode) {
+                NestedLoopJoinNode nestedLoopJoinNode = (NestedLoopJoinNode) 
inputPlanNode;
+                nestedLoopJoinNode.setvOutputTupleDesc(tupleDescriptor);
+                nestedLoopJoinNode.setvSrcToOutputSMap(execExprList);
+                return inputFragment;

Review Comment:
   project on join node cannot be remove, this is a constraint on BE



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java:
##########
@@ -128,6 +128,12 @@ public PlanFragment translatePlan(PhysicalPlan 
physicalPlan, PlanTranslatorConte
             rootFragment = exchangeToMergeFragment(rootFragment, context);
         }
         List<Expr> outputExprs = Lists.newArrayList();
+        if (physicalPlan instanceof PhysicalProject) {
+            PhysicalProject project = (PhysicalProject) physicalPlan;
+            if (isUnnecessaryProject(project)) {
+                physicalPlan = (PhysicalPlan) physicalPlan.child(0);
+            }
+        }

Review Comment:
   after remove the root project node, we should set output exprs's order as 
them in the project to ensure the result is correct.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java:
##########
@@ -1162,4 +1178,19 @@ private PlanFragment 
constructShuffleJoin(AbstractPhysicalJoin<PhysicalPlan, Phy
 
         return joinFragment;
     }
+
+    private boolean isUnnecessaryProject(PhysicalProject project) {
+        List<NamedExpression> projects = project.getProjects();
+        for (NamedExpression p : projects) {
+            if (p.children().size() > 1) {
+                return false;
+            }
+            for (Expression e : p.children()) {
+                if (!(e instanceof SlotReference)) {
+                    return false;
+                }
+            }
+        }

Review Comment:
   ```
   1. project.output.size == project.child.output.size
   2. project.output.allMatch(expr -> expr instance of SlotReference || (expr 
instance Alias && expr.child instance of SlotReference))
   ```



-- 
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: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to