Skip to content

Commit 0d6a77f

Browse files
branch-4.0: [fix](topn-lazy-materialize) LazySlotPruning does not pass nullable attribute of global_row_id when visiting project. #58722 (#59588)
Cherry-picked from #58722 Co-authored-by: minghong <[email protected]>
1 parent c05db7d commit 0d6a77f

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/materialize/LazySlotPruning.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public Plan visitPhysicalProject(PhysicalProject<? extends Plan> project, Contex
196196
}
197197
Context childContext = context.withLazySlots(childLazySlots);
198198
child = child.accept(this, childContext);
199+
context.updateRowIdSlot(childContext.rowIdSlot);
199200
}
200201
if (child.getOutput().contains(context.rowIdSlot)) {
201202
List<NamedExpression> newProjections = new ArrayList<>();
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
suite("global_rowid_nullable") {
19+
sql """
20+
CREATE TABLE IF NOT EXISTS t1 (
21+
k1 INT NULL,
22+
k2 INT NULL,
23+
v1 INT NULL,
24+
v2 INT NULL
25+
)
26+
DISTRIBUTED BY HASH(k1) BUCKETS 3
27+
PROPERTIES (
28+
'replication_num' = '1'
29+
);
30+
insert into t1 values
31+
(1, 1, 10, 100),
32+
(2, 2, 20, 200),
33+
(3, 3, 30, 300);
34+
35+
CREATE TABLE IF NOT EXISTS t2 (
36+
k1 INT NULL,
37+
k2 INT NULL,
38+
v1 INT NULL,
39+
v2 INT NULL
40+
)
41+
DISTRIBUTED BY HASH(k1) BUCKETS 3
42+
PROPERTIES (
43+
'replication_num' = '1'
44+
);
45+
insert into t2 values
46+
(1, 1, 10, 100),
47+
(2, 2, 20, 200),
48+
(3, 3, 30, 300);
49+
50+
CREATE TABLE IF NOT EXISTS t3 (
51+
k1 INT NULL,
52+
k2 INT NULL,
53+
v1 INT NULL,
54+
v2 INT NULL
55+
)
56+
DISTRIBUTED BY HASH(k1) BUCKETS 3
57+
PROPERTIES (
58+
'replication_num' = '1'
59+
);
60+
insert into t3 values
61+
(1, 1, 10, 100),
62+
(2, 2, 20, 200),
63+
(3, 3, 30, 300);
64+
65+
set disable_join_reorder = true;
66+
"""
67+
68+
69+
/**
70+
the plan of the following sql should be like:
71+
PhysicalResultSink[608] ( outputExprs=[k1#0, x#12] )
72+
+--PhysicalProject[605]@ ( stats=null, projects=[k1#0, x#12] )
73+
+--PhysicalLazyMaterialize [Output= ([k1#0, x#12]), lazySlots= ([x#12])]
74+
+--PhysicalTopN[603]@12 ( stats=1, limit=1, offset=0, orderKeys=[k1#0 asc null first], phase=MERGE_SORT )
75+
+--PhysicalDistribute[600]@ ( stats=1, distributionSpec=DistributionSpecGather )
76+
+--PhysicalTopN[597]@14 ( stats=1, limit=1, offset=0, orderKeys=[k1#0 asc null first], phase=LOCAL_SORT )
77+
+--PhysicalProject[594]@11 ( stats=3.01, projects=[k1#0, __DORIS_GLOBAL_ROWID_COL__t3#13] )
78+
+--PhysicalHashJoin[592]@ ( stats=3.01, type=INNER_JOIN, hashCondition=[(k1#0 = k1#4)], otherCondition=[], markCondition=[], RFs=[RF0[k1#4->[k1#0](ndv/size = 3/4) , RF1[k1#4->[k1#0](ndv/size = 3/4) ] )
79+
|--PhysicalProject[518]@1 ( stats=3, projects=[k1#0] )
80+
| +--PhysicalOlapScan[t1]@0 ( stats=3, operativeSlots=[k1#0], virtualColumns=[], JRFs= RF0 RF1 )
81+
+--PhysicalDistribute[589]@ ( stats=3.01, distributionSpec=DistributionSpecReplicated )
82+
+--PhysicalProject[586]@9 ( stats=3.01, projects=[k1#4, __DORIS_GLOBAL_ROWID_COL__t3#13] )
83+
+--PhysicalFilter[584]@7 ( stats=3.01, predicates=OR[(k1#8 > 0),k1#8 IS NULL] )
84+
+--PhysicalHashJoin[581]@ ( stats=6, type=LEFT_OUTER_JOIN, hashCondition=[(k1#4 = k1#8)], otherCondition=[], markCondition=[] )
85+
|--PhysicalProject[523]@3 ( stats=3, projects=[k1#4] )
86+
| +--PhysicalOlapScan[t2]@2 ( stats=3, operativeSlots=[k1#4], virtualColumns=[] )
87+
+--PhysicalDistribute[578]@ ( stats=6, distributionSpec=DistributionSpecReplicated )
88+
+--PhysicalProject[575]@5 ( stats=6, projects=[k1#8, __DORIS_GLOBAL_ROWID_COL__t3#13] )
89+
+--PhysicalLazyMaterializeOlapScan[PhysicalOlapScan[t3]@4 ( stats=6, operativeSlots=[k1#8], virtualColumns=[] )]
90+
after join[581] global rowid column of t3 should be nullable.
91+
we construct new context when visiting project[586]. this case verifies that we handle nullable property of global rowid column correctly passed through project[586] in such scenario.
92+
*/
93+
sql """
94+
select t1.k1, tmp2.x
95+
from t1 join (
96+
select tmp.k1, tmp.v1 as x from (
97+
select t2.k1, t3.v1 from t2 left outer join t3 on t2.k1 = t3.k1 where t3.k1 > 0 or t3.k1 is null
98+
) as tmp
99+
100+
) as tmp2 on t1.k1 = tmp2.k1
101+
order by t1.k1
102+
limit 1;
103+
"""
104+
105+
}

0 commit comments

Comments
 (0)