This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new ae1092b9dbb branch-3.0: [fix](nereids) set wrong intput tuple ids for 
JoinNode #54377 (#54839)
ae1092b9dbb is described below

commit ae1092b9dbb1f07978b153fae4255c6d47d815e4
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Aug 20 10:49:36 2025 +0800

    branch-3.0: [fix](nereids) set wrong intput tuple ids for JoinNode #54377 
(#54839)
    
    Cherry-picked from #54377
    
    Co-authored-by: minghong <[email protected]>
---
 .../glue/translator/PhysicalPlanTranslator.java    |  2 +-
 .../org/apache/doris/planner/AnalyticEvalNode.java |  4 +-
 .../apache/doris/planner/AssertNumRowsNode.java    |  6 +-
 .../org/apache/doris/planner/ExchangeNode.java     |  2 +-
 .../org/apache/doris/planner/HashJoinNode.java     | 16 ++---
 .../apache/doris/planner/JoinCostEvaluation.java   |  2 +-
 .../apache/doris/planner/NestedLoopJoinNode.java   |  8 +--
 .../java/org/apache/doris/planner/PlanNode.java    |  2 +-
 .../apache/doris/planner/TableFunctionNode.java    |  2 +-
 .../translate_tuple_id/join_input_tuple_id.groovy  | 71 ++++++++++++++++++++++
 10 files changed, 90 insertions(+), 25 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 7ffe57168c2..6dd4564bd56 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -1307,7 +1307,7 @@ public class PhysicalPlanTranslator extends 
DefaultPlanVisitor<PlanFragment, Pla
         TupleDescriptor tupleDescriptor = 
generateTupleDesc(generate.getGeneratorOutput(), null, context);
         List<TupleId> childOutputTupleIds = 
currentFragment.getPlanRoot().getOutputTupleIds();
         if (childOutputTupleIds == null || childOutputTupleIds.isEmpty()) {
-            childOutputTupleIds = currentFragment.getPlanRoot().getTupleIds();
+            childOutputTupleIds = 
currentFragment.getPlanRoot().getOutputTupleIds();
         }
         List<SlotId> outputSlotIds = 
Stream.concat(childOutputTupleIds.stream(),
                         Stream.of(tupleDescriptor.getId()))
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/AnalyticEvalNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/AnalyticEvalNode.java
index 7b5998717a2..20a920f4089 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/AnalyticEvalNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/AnalyticEvalNode.java
@@ -109,9 +109,7 @@ public class AnalyticEvalNode extends PlanNode {
             TupleDescriptor outputTupleDesc, Expr partitionByEq, Expr 
orderByEq,
             TupleDescriptor bufferedTupleDesc) {
         super(id,
-                (input.getOutputTupleDesc() != null
-                        ? 
Lists.newArrayList(input.getOutputTupleDesc().getId()) :
-                        input.getTupleIds()),
+                input.getOutputTupleIds(),
                 "ANALYTIC", StatisticalType.ANALYTIC_EVAL_NODE);
         Preconditions.checkState(!tupleIds.contains(outputTupleDesc.getId()));
         // we're materializing the input row augmented with the analytic 
output tuple
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
index a4c4aa42c65..8966a43adde 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
@@ -60,11 +60,7 @@ public class AssertNumRowsNode extends PlanNode {
         if (tupleDescriptor != null) {
             this.tupleIds.add(tupleDescriptor.getId());
         } else {
-            if (input.getOutputTupleDesc() != null) {
-                this.tupleIds.add(input.getOutputTupleDesc().getId());
-            } else {
-                this.tupleIds.addAll(input.getTupleIds());
-            }
+            this.tupleIds.addAll(input.getOutputTupleIds());
         }
 
         this.tblRefIds.addAll(input.getTblRefIds());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/ExchangeNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/ExchangeNode.java
index d904397a305..aeb5c39a58c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/ExchangeNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/ExchangeNode.java
@@ -125,7 +125,7 @@ public class ExchangeNode extends PlanNode {
             nullableTupleIds.add(outputTupleDesc.getId());
         } else {
             clearTupleIds();
-            tupleIds.addAll(getChild(0).getTupleIds());
+            tupleIds.addAll(getChild(0).getOutputTupleIds());
             tblRefIds.addAll(getChild(0).getTblRefIds());
             nullableTupleIds.addAll(getChild(0).getNullableTupleIds());
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java
index b664b7a26c8..e6f4e5fcba1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java
@@ -188,12 +188,12 @@ public class HashJoinNode extends JoinNodeBase {
 
         if (joinOp.equals(JoinOperator.LEFT_ANTI_JOIN) || 
joinOp.equals(JoinOperator.LEFT_SEMI_JOIN)
                 || joinOp.equals(JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN)) {
-            tupleIds.addAll(outer.getTupleIds());
+            tupleIds.addAll(outer.getOutputTupleIds());
         } else if (joinOp.equals(JoinOperator.RIGHT_ANTI_JOIN) || 
joinOp.equals(JoinOperator.RIGHT_SEMI_JOIN)) {
-            tupleIds.addAll(inner.getTupleIds());
+            tupleIds.addAll(inner.getOutputTupleIds());
         } else {
-            tupleIds.addAll(outer.getTupleIds());
-            tupleIds.addAll(inner.getTupleIds());
+            tupleIds.addAll(outer.getOutputTupleIds());
+            tupleIds.addAll(inner.getOutputTupleIds());
         }
 
         for (Expr eqJoinPredicate : eqJoinConjuncts) {
@@ -212,12 +212,12 @@ public class HashJoinNode extends JoinNodeBase {
         nullableTupleIds.addAll(inner.getNullableTupleIds());
         nullableTupleIds.addAll(outer.getNullableTupleIds());
         if (joinOp.equals(JoinOperator.FULL_OUTER_JOIN)) {
-            nullableTupleIds.addAll(outer.getTupleIds());
-            nullableTupleIds.addAll(inner.getTupleIds());
+            nullableTupleIds.addAll(outer.getOutputTupleIds());
+            nullableTupleIds.addAll(inner.getOutputTupleIds());
         } else if (joinOp.equals(JoinOperator.LEFT_OUTER_JOIN)) {
-            nullableTupleIds.addAll(inner.getTupleIds());
+            nullableTupleIds.addAll(inner.getOutputTupleIds());
         } else if (joinOp.equals(JoinOperator.RIGHT_OUTER_JOIN)) {
-            nullableTupleIds.addAll(outer.getTupleIds());
+            nullableTupleIds.addAll(outer.getOutputTupleIds());
         }
         vIntermediateTupleDescList = Lists.newArrayList(intermediateTuple);
         this.outputTupleDesc = outputTuple;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/JoinCostEvaluation.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/JoinCostEvaluation.java
index 28daa450c5a..f7a4395691d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/JoinCostEvaluation.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/JoinCostEvaluation.java
@@ -52,7 +52,7 @@ public class JoinCostEvaluation {
         PlanNode rhsTree = rightChildFragment.getPlanRoot();
         rhsTreeCardinality = rhsTree.getCardinality();
         rhsTreeAvgRowSize = rhsTree.getAvgRowSize();
-        rhsTreeTupleIdNum = rhsTree.getTupleIds().size();
+        rhsTreeTupleIdNum = rhsTree.getOutputTupleIds().size();
         PlanNode lhsTree = leftChildFragment.getPlanRoot();
         lhsTreeCardinality = lhsTree.getCardinality();
         lhsTreeAvgRowSize = lhsTree.getAvgRowSize();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
index e2a7504a98d..7cdd894ae4a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
@@ -123,12 +123,12 @@ public class NestedLoopJoinNode extends JoinNodeBase {
         nullableTupleIds.addAll(outer.getNullableTupleIds());
         nullableTupleIds.addAll(inner.getNullableTupleIds());
         if (joinOp.equals(JoinOperator.FULL_OUTER_JOIN)) {
-            nullableTupleIds.addAll(outer.getTupleIds());
-            nullableTupleIds.addAll(inner.getTupleIds());
+            nullableTupleIds.addAll(outer.getOutputTupleIds());
+            nullableTupleIds.addAll(inner.getOutputTupleIds());
         } else if (joinOp.equals(JoinOperator.LEFT_OUTER_JOIN)) {
-            nullableTupleIds.addAll(inner.getTupleIds());
+            nullableTupleIds.addAll(inner.getOutputTupleIds());
         } else if (joinOp.equals(JoinOperator.RIGHT_OUTER_JOIN)) {
-            nullableTupleIds.addAll(outer.getTupleIds());
+            nullableTupleIds.addAll(outer.getOutputTupleIds());
         }
         vIntermediateTupleDescList = Lists.newArrayList(intermediateTuple);
         outputTupleDesc = outputTuple;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java
index 31160b594d3..3ce099f93bb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanNode.java
@@ -175,7 +175,7 @@ public abstract class PlanNode extends TreeNode<PlanNode> 
implements PlanStats {
     private List<TupleDescriptor> intermediateOutputTupleDescList = 
Lists.newArrayList();
     private List<List<Expr>> intermediateProjectListList = 
Lists.newArrayList();
 
-    protected PlanNode(PlanNodeId id, ArrayList<TupleId> tupleIds, String 
planNodeName,
+    protected PlanNode(PlanNodeId id, List<TupleId> tupleIds, String 
planNodeName,
             StatisticalType statisticalType) {
         this.id = id;
         this.limit = -1;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
index ce5aa9d1972..75707b7302b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/TableFunctionNode.java
@@ -60,7 +60,7 @@ public class TableFunctionNode extends PlanNode {
             if (childOutputTupleIds != null && !childOutputTupleIds.isEmpty()) 
{
                 tupleIds.addAll(childOutputTupleIds);
             } else {
-                tupleIds.addAll(inputNode.getTupleIds());
+                tupleIds.addAll(inputNode.getOutputTupleIds());
             }
         }
         tupleIds.add(lateralViewTupleId);
diff --git 
a/regression-test/suites/nereids_p0/join/translate_tuple_id/join_input_tuple_id.groovy
 
b/regression-test/suites/nereids_p0/join/translate_tuple_id/join_input_tuple_id.groovy
new file mode 100644
index 00000000000..50dcc21009c
--- /dev/null
+++ 
b/regression-test/suites/nereids_p0/join/translate_tuple_id/join_input_tuple_id.groovy
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("join_input_tuple_id") {
+    sql """
+        drop table if exists t1;
+        create table t1(k int, v int) properties("replication_num"="1");
+        insert into t1 values (1, 1), (2, 2), (3,3);
+
+        drop table if exists t2;
+        create table t2(k int, v int) properties("replication_num"="1");
+        insert into t2 values (1, 1), (2, 2), (3,3);
+
+        drop table if exists t3;
+        create table t3(k int, v int) properties("replication_num"="1");
+        insert into t3 values (1, 1), (2, 2), (3,3);
+        set disable_join_reorder=true;
+    """
+
+    explain {
+        sql """
+            verbose select * 
+            from ((select k, v from t1) union all (select k, v from t2)) as u
+                join t3 on u.k+1 = t3.k
+        """
+        // verify that join's input tuple is union's output tuple id (5) not 
input tuple (4)
+        contains "tuple ids: 5 1N"
+
+//   7:VHASH JOIN(293)
+//   |  join op: INNER JOIN(BROADCAST)[]
+//   |  equal join conjunct: (expr_cast(k as BIGINT)[#13] = expr_(cast(k as 
BIGINT) - 1)[#4])
+//   |  cardinality=2
+//   |  vec output tuple id: 7
+//   |  output tuple id: 7
+//   |  vIntermediate tuple ids: 6 
+//   |  hash output slot ids: 2 3 11 12 
+//   |  isMarkJoin: false
+//   |  final projections: k[#14], v[#15], k[#17], v[#18]
+//   |  final project output tuple id: 7
+//   |  distribute expr lists: 
+//   |  distribute expr lists: 
+//   |  tuple ids: 5 1N 
+//   |  
+//   |----1:VEXCHANGE
+//   |       offset: 0
+//   |       distribute expr lists: 
+//   |       tuple ids: 1N 
+//   |    
+//   6:VUNION(276)
+//   |  child exprs: 
+//   |      k[#5] | v[#6]
+//   |      k[#7] | v[#8]
+//   |  final projections: k[#9], v[#10], CAST(k[#9] AS bigint)
+//   |  final project output tuple id: 5
+//   |  tuple ids: 4 
+    }
+}
\ No newline at end of file


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

Reply via email to