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]