Skip to content

Commit b02aa15

Browse files
authored
fix: the output columns of cte related columns lack the columns required by cte itself (#17576)
* fix: the output columns of cte related columns lack the columns required by cte itself Signed-off-by: Kould <[email protected]> * fix: the output columns of cte related columns lack the columns required by cte itself Signed-off-by: Kould <[email protected]> * chore: codefmt Signed-off-by: Kould <[email protected]> --------- Signed-off-by: Kould <[email protected]>
1 parent 8987614 commit b02aa15

File tree

3 files changed

+69
-29
lines changed

3 files changed

+69
-29
lines changed

src/query/sql/src/executor/physical_plans/physical_union_all.rs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,45 @@ impl PhysicalPlanBuilder {
6262
// 1. Prune unused Columns.
6363
let metadata = self.metadata.read().clone();
6464
let lazy_columns = metadata.lazy_columns();
65-
required.extend(lazy_columns.clone());
66-
67-
let indices: Vec<usize> = (0..union_all.left_outputs.len())
68-
.filter(|index| required.contains(&union_all.output_indexes[*index]))
69-
.collect();
70-
71-
let (left_required, right_required) = if indices.is_empty() {
72-
(
73-
HashSet::from([union_all.left_outputs[0].0]),
74-
HashSet::from([union_all.right_outputs[0].0]),
75-
)
65+
required.extend(lazy_columns);
66+
67+
// if the union has a CTE, the output columns are not filtered
68+
// otherwise, if the output columns of the union do not contain the columns used by the plan in the union, the expression will fail to obtain data.
69+
let (left_required, right_required) = if !union_all.cte_scan_names.is_empty() {
70+
let left: ColumnSet = union_all
71+
.left_outputs
72+
.iter()
73+
.map(|(index, _)| *index)
74+
.collect();
75+
let right: ColumnSet = union_all
76+
.right_outputs
77+
.iter()
78+
.map(|(index, _)| *index)
79+
.collect();
80+
81+
(left, right)
7682
} else {
77-
indices.iter().fold(
83+
let indices: Vec<usize> = (0..union_all.left_outputs.len())
84+
.filter(|index| required.contains(&union_all.output_indexes[*index]))
85+
.collect();
86+
if indices.is_empty() {
7887
(
79-
HashSet::with_capacity(indices.len()),
80-
HashSet::with_capacity(indices.len()),
81-
),
82-
|(mut left, mut right), &index| {
83-
left.insert(union_all.left_outputs[index].0);
84-
right.insert(union_all.right_outputs[index].0);
85-
(left, right)
86-
},
87-
)
88+
HashSet::from([union_all.left_outputs[0].0]),
89+
HashSet::from([union_all.right_outputs[0].0]),
90+
)
91+
} else {
92+
indices.iter().fold(
93+
(
94+
HashSet::with_capacity(indices.len()),
95+
HashSet::with_capacity(indices.len()),
96+
),
97+
|(mut left, mut right), &index| {
98+
left.insert(union_all.left_outputs[index].0);
99+
right.insert(union_all.right_outputs[index].0);
100+
(left, right)
101+
},
102+
)
103+
}
88104
};
89105

90106
// 2. Build physical plan.

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,7 @@ impl Binder {
6363
RelOperator::RecursiveCteScan(plan) => {
6464
cte_scan_names.push(plan.table_name.clone());
6565
if cte_types.is_empty() {
66-
cte_types.extend(
67-
plan.fields
68-
.iter()
69-
.map(|f| f.data_type().clone())
70-
.collect::<Vec<DataType>>(),
71-
);
66+
cte_types.extend(plan.fields.iter().map(|f| f.data_type().clone()));
7267
}
7368
}
7469

tests/sqllogictests/suites/query/cte/cte.test

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,10 +578,10 @@ with t(tt) as (select number as tt from numbers(10)), t2(tt) AS MATERIALIZED (S
578578

579579
# https://github.com/databendlabs/databend/issues/17295
580580
statement ok
581-
create table t1(a int);
581+
create or replace table t1(a int);
582582

583583
statement ok
584-
create table t2(a int);
584+
create or replace table t2(a int);
585585

586586
query I
587587
WITH RECURSIVE
@@ -591,3 +591,32 @@ UNION all SELECT a from t2, closure where t2.a = closure.x
591591
) SELECT x FROM closure;
592592
----
593593
1
594+
595+
# https://github.com/databendlabs/databend/issues/17432
596+
statement ok
597+
CREATE OR REPLACE TABLE some_table (
598+
id INTEGER NOT NULL,
599+
"data" VARCHAR(50),
600+
parent_id INTEGER
601+
);
602+
603+
statement ok
604+
INSERT INTO some_table (id, "data", parent_id) VALUES (1, 'd1', NULL),(2, 'd2', 1),(3, 'd3', 1),(4, 'd4', 3),(5, 'd5', 3);
605+
606+
query T
607+
WITH RECURSIVE some_cte(id, "data", parent_id) AS
608+
(SELECT some_table.id AS id, some_table."data" AS "data", some_table.parent_id AS parent_id
609+
FROM some_table
610+
WHERE some_table."data" IN ('d2', 'd3', 'd4') UNION ALL SELECT some_table_1.id AS id, some_table_1."data" AS "data", some_table_1.parent_id AS parent_id
611+
FROM some_table AS some_table_1, some_cte AS c1
612+
WHERE some_table_1.id = c1.parent_id)
613+
SELECT some_cte."data"
614+
FROM some_cte
615+
WHERE some_cte."data" != 'd2';
616+
----
617+
d1
618+
d1
619+
d1
620+
d3
621+
d3
622+
d4

0 commit comments

Comments
 (0)