mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed bugs: mdev-13780 CTE not found, mdev-14184 recursive CTE not found
The support of embedded CTEs was not correct in the cases when embedded CTEs were used multiple times. The problems occurred with both non-recursive (bug mdev-13780) and recursive (bug mdev-14184) embedded CTEs.
This commit is contained in:
@ -1079,3 +1079,52 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
|
||||
NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# MDEV-13780: tower of embedding CTEs with multiple usage of them
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (3), (2), (4), (7), (1), (2), (5);
|
||||
with cte_e as
|
||||
(
|
||||
with cte_o as
|
||||
(
|
||||
with cte_i as (select * from t1 where a < 7)
|
||||
select * from cte_i where a > 1
|
||||
)
|
||||
select * from cte_o as cto_o1 where a < 3
|
||||
union
|
||||
select * from cte_o as cto_o2 where a > 4
|
||||
)
|
||||
select * from cte_e as cte_e1 where a > 1
|
||||
union
|
||||
select * from cte_e as cte_e2;
|
||||
a
|
||||
2
|
||||
5
|
||||
explain extended with cte_e as
|
||||
(
|
||||
with cte_o as
|
||||
(
|
||||
with cte_i as (select * from t1 where a < 7)
|
||||
select * from cte_i where a > 1
|
||||
)
|
||||
select * from cte_o as cto_o1 where a < 3
|
||||
union
|
||||
select * from cte_o as cto_o2 where a > 4
|
||||
)
|
||||
select * from cte_e as cte_e1 where a > 1
|
||||
union
|
||||
select * from cte_e as cte_e2;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 14 100.00 Using where
|
||||
2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
|
||||
6 UNION <derived9> ALL NULL NULL NULL NULL 14 100.00
|
||||
9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
|
||||
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
Note 1003 with cte_e as (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2`
|
||||
drop table t1;
|
||||
|
@ -2875,3 +2875,25 @@ f
|
||||
2
|
||||
set standard_compliant_cte=default;
|
||||
DROP TABLE t;
|
||||
#
|
||||
# mdev-14184: recursive CTE embedded into CTE with multiple references
|
||||
#
|
||||
WITH
|
||||
cte1 AS (
|
||||
SELECT n FROM (
|
||||
WITH RECURSIVE rec_cte(n) AS (
|
||||
SELECT 1 as n1
|
||||
UNION ALL
|
||||
SELECT n+1 as n2 FROM rec_cte WHERE n < 3
|
||||
) SELECT n FROM rec_cte
|
||||
) AS X
|
||||
),
|
||||
cte2 as (
|
||||
SELECT 2 FROM cte1
|
||||
)
|
||||
SELECT *
|
||||
FROM cte1;
|
||||
n
|
||||
1
|
||||
2
|
||||
3
|
||||
|
@ -743,3 +743,31 @@ eval $q;
|
||||
eval explain $q;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-13780: tower of embedding CTEs with multiple usage of them
|
||||
--echo #
|
||||
|
||||
create table t1 (a int);
|
||||
insert into t1 values (3), (2), (4), (7), (1), (2), (5);
|
||||
|
||||
let $q=
|
||||
with cte_e as
|
||||
(
|
||||
with cte_o as
|
||||
(
|
||||
with cte_i as (select * from t1 where a < 7)
|
||||
select * from cte_i where a > 1
|
||||
)
|
||||
select * from cte_o as cto_o1 where a < 3
|
||||
union
|
||||
select * from cte_o as cto_o2 where a > 4
|
||||
)
|
||||
select * from cte_e as cte_e1 where a > 1
|
||||
union
|
||||
select * from cte_e as cte_e2;
|
||||
|
||||
eval $q;
|
||||
eval explain extended $q;
|
||||
|
||||
drop table t1;
|
||||
|
@ -1928,3 +1928,22 @@ set standard_compliant_cte=default;
|
||||
|
||||
DROP TABLE t;
|
||||
|
||||
--echo #
|
||||
--echo # mdev-14184: recursive CTE embedded into CTE with multiple references
|
||||
--echo #
|
||||
|
||||
WITH
|
||||
cte1 AS (
|
||||
SELECT n FROM (
|
||||
WITH RECURSIVE rec_cte(n) AS (
|
||||
SELECT 1 as n1
|
||||
UNION ALL
|
||||
SELECT n+1 as n2 FROM rec_cte WHERE n < 3
|
||||
) SELECT n FROM rec_cte
|
||||
) AS X
|
||||
),
|
||||
cte2 as (
|
||||
SELECT 2 FROM cte1
|
||||
)
|
||||
SELECT *
|
||||
FROM cte1;
|
||||
|
@ -349,8 +349,11 @@ void With_element::check_dependencies_in_select(st_select_lex *sl,
|
||||
/* Now look for the dependencies in the subqueries of sl */
|
||||
st_select_lex_unit *inner_unit= sl->first_inner_unit();
|
||||
for (; inner_unit; inner_unit= inner_unit->next_unit())
|
||||
{
|
||||
if (!inner_unit->with_element)
|
||||
check_dependencies_in_unit(inner_unit, ctxt, in_subq, dep_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -838,7 +841,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
|
||||
with_table->next_global= spec_tables;
|
||||
}
|
||||
res= &lex->unit;
|
||||
res->set_with_clause(owner);
|
||||
|
||||
lex->unit.include_down(with_table->select_lex);
|
||||
lex->unit.set_slave(with_select);
|
||||
@ -847,6 +849,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
|
||||
insert_chain_before(
|
||||
(st_select_lex_node **) &(old_lex->all_selects_list),
|
||||
with_select));
|
||||
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
|
||||
res= NULL;
|
||||
lex_end(lex);
|
||||
err:
|
||||
if (arena)
|
||||
@ -990,14 +994,18 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
||||
and it was unsuccesful. Yet for units cloned from the spec it has not
|
||||
been done yet.
|
||||
*/
|
||||
if (with_elem && sl->master_unit() == with_elem->spec)
|
||||
With_clause *attached_with_clause=sl->get_with_clause();
|
||||
if (attached_with_clause &&
|
||||
(found= attached_with_clause->find_table_def(table, NULL)))
|
||||
break;
|
||||
With_clause *with_clause=sl->get_with_clause();
|
||||
if (with_clause)
|
||||
if (with_elem)
|
||||
{
|
||||
With_element *barrier= with_clause->with_recursive ? NULL : with_elem;
|
||||
if ((found= with_clause->find_table_def(table, barrier)))
|
||||
With_clause *containing_with_clause= with_elem->get_owner();
|
||||
With_element *barrier= containing_with_clause->with_recursive ?
|
||||
NULL : with_elem;
|
||||
if ((found= containing_with_clause->find_table_def(table, barrier)))
|
||||
break;
|
||||
sl= sl->master_unit()->outer_select();
|
||||
}
|
||||
master_unit= sl->master_unit();
|
||||
/* Do not look for the table's definition beyond the scope of the view */
|
||||
|
Reference in New Issue
Block a user