Skip to content

Commit 720fa46

Browse files
authored
fix(query): expr children with projectset not fold count (#10827)
* fix(query): expr children with projectset not fold count * if expr contains ProjectSet, not prune unused column * ProjectSet precise_cardinality set None * add count() from (unnest()) explain result * fix ci: unnest explain result read bytes result diff * modify explain test result diff
1 parent 61f46fa commit 720fa46

File tree

5 files changed

+124
-20
lines changed

5 files changed

+124
-20
lines changed

src/query/sql/src/planner/optimizer/heuristic/prune_unused_columns.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use common_exception::ErrorCode;
1616
use common_exception::Result;
1717

18+
use crate::optimizer::util::contaions_project_set;
1819
use crate::optimizer::ColumnSet;
1920
use crate::optimizer::SExpr;
2021
use crate::plans::Aggregate;
@@ -99,6 +100,14 @@ impl UnusedColumnPruner {
99100

100101
RelOperator::EvalScalar(p) => {
101102
let mut used = vec![];
103+
if contaions_project_set(expr) {
104+
return Ok(SExpr::create_unary(
105+
RelOperator::EvalScalar(EvalScalar {
106+
items: p.items.clone(),
107+
}),
108+
expr.child(0)?.clone(),
109+
));
110+
}
102111
// Only keep columns needed by parent plan.
103112
for s in p.items.iter() {
104113
if !required.contains(&s.index) {

src/query/sql/src/planner/optimizer/util.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// limitations under the License.
1414

1515
use super::SExpr;
16+
use crate::plans::Operator;
17+
use crate::plans::RelOp;
1618
use crate::plans::RelOperator;
1719
use crate::MetadataRef;
1820

@@ -28,3 +30,16 @@ pub fn contains_local_table_scan(s_expr: &SExpr, metadata: &MetadataRef) -> bool
2830
false
2931
}
3032
}
33+
34+
/// Check the expr contains ProjectSet op.
35+
pub fn contaions_project_set(s_expr: &SExpr) -> bool {
36+
if let Some(child) = s_expr.children().iter().next() {
37+
// Check children
38+
return match child.plan.rel_op() {
39+
RelOp::ProjectSet => true,
40+
_ => contaions_project_set(child),
41+
};
42+
}
43+
44+
false
45+
}

src/query/sql/src/planner/plans/project_set.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ impl Operator for ProjectSet {
5757
child_prop.output_columns.insert(srf.index);
5858
}
5959

60+
// ProjectSet is set-returning functions, precise_cardinality set None
61+
child_prop.statistics.precise_cardinality = None;
6062
Ok(child_prop)
6163
}
6264

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
statement ok
2+
use default;
3+
4+
statement ok
5+
drop table if exists fold_count;
6+
7+
statement ok
8+
create table fold_count(id array(int), c1 string);
9+
10+
statement ok
11+
insert into fold_count values([1,2,3,4], 'x');
12+
13+
query T
14+
explain select count() from (select unnest(id), c1 from fold_count)
15+
----
16+
EvalScalar
17+
├── expressions: [count() (#4)]
18+
├── estimated rows: 1.00
19+
└── AggregateFinal
20+
├── group by: []
21+
├── aggregate functions: [count()]
22+
├── estimated rows: 1.00
23+
└── AggregatePartial
24+
├── group by: []
25+
├── aggregate functions: [count()]
26+
├── estimated rows: 1.00
27+
└── EvalScalar
28+
├── expressions: [get(unnest (#2))]
29+
├── estimated rows: 1.00
30+
└── ProjectSet
31+
├── estimated rows: 1.00
32+
├── set returning functions: unnest(CAST(fold_count.id (#0) AS Array(Int32 NULL)))
33+
└── TableScan
34+
├── table: default.default.fold_count
35+
├── read rows: 1
36+
├── read bytes: 87
37+
├── partitions total: 1
38+
├── partitions scanned: 1
39+
├── pruning stats: [segments: <range pruning: 1 to 1>, blocks: <range pruning: 1 to 1, bloom pruning: 0 to 0>]
40+
├── push downs: [filters: [], limit: NONE]
41+
└── estimated rows: 1.00
42+
43+
statement ok
44+
drop table fold_count;
45+
146
statement ok
247
drop database if exists project_set
348

@@ -10,32 +55,38 @@ use project_set
1055
query T
1156
explain select number from (select unnest([1,2,3]), number from numbers(10)) t
1257
----
13-
ProjectSet
58+
EvalScalar
59+
├── expressions: [get(unnest (#1))]
1460
├── estimated rows: 10.00
15-
├── set returning functions: unnest([1, 2, 3])
16-
└── TableScan
17-
├── table: default.system.numbers
18-
├── read rows: 10
19-
├── read bytes: 80
20-
├── partitions total: 1
21-
├── partitions scanned: 1
22-
├── push downs: [filters: [], limit: NONE]
23-
└── estimated rows: 10.00
61+
└── ProjectSet
62+
├── estimated rows: 10.00
63+
├── set returning functions: unnest([1, 2, 3])
64+
└── TableScan
65+
├── table: default.system.numbers
66+
├── read rows: 10
67+
├── read bytes: 80
68+
├── partitions total: 1
69+
├── partitions scanned: 1
70+
├── push downs: [filters: [], limit: NONE]
71+
└── estimated rows: 10.00
2472

2573
query T
2674
explain select number from (select unnest([1,2,3,number]), number from numbers(10)) t
2775
----
28-
ProjectSet
76+
EvalScalar
77+
├── expressions: [get(unnest (#1))]
2978
├── estimated rows: 10.00
30-
├── set returning functions: unnest(CAST(array(1, 2, 3, numbers.number (#0)) AS Array(UInt64 NULL)))
31-
└── TableScan
32-
├── table: default.system.numbers
33-
├── read rows: 10
34-
├── read bytes: 80
35-
├── partitions total: 1
36-
├── partitions scanned: 1
37-
├── push downs: [filters: [], limit: NONE]
38-
└── estimated rows: 10.00
79+
└── ProjectSet
80+
├── estimated rows: 10.00
81+
├── set returning functions: unnest(CAST(array(1, 2, 3, numbers.number (#0)) AS Array(UInt64 NULL)))
82+
└── TableScan
83+
├── table: default.system.numbers
84+
├── read rows: 10
85+
├── read bytes: 80
86+
├── partitions total: 1
87+
├── partitions scanned: 1
88+
├── push downs: [filters: [], limit: NONE]
89+
└── estimated rows: 10.00
3990

4091
statement ok
4192
drop database project_set

tests/sqllogictests/suites/query/02_function/02_0062_function_unnest

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,33 @@ drop table t;
369369
statement ok
370370
drop table t2;
371371

372+
statement ok
373+
drop table if exists fold_count;
374+
375+
statement ok
376+
create table fold_count(id array(int), c1 string);
377+
378+
statement ok
379+
insert into fold_count values([1,2,3,4], 'x')
380+
381+
query T
382+
select concat(c,'y') as b from (select concat(c::String, c1) as c from (select unnest(id) as c, c1 from fold_count));
383+
----
384+
1xy
385+
2xy
386+
3xy
387+
4xy
388+
389+
query I
390+
select count(b) from (select concat(c,'y') as b from (select concat(c::String, c1) as c from (select unnest(id) as c, c1 from fold_count)));
391+
----
392+
4
393+
394+
query I
395+
select count() from (select unnest(id), c1 from fold_count)
396+
----
397+
4
398+
372399
statement ok
373400
DROP DATABASE db_02_0062;
374401

0 commit comments

Comments
 (0)