mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-29361 Infinite recursive calls when detecting CTE dependencies
This patch resolves the problem of improper name resolution of table references to embedded CTEs for some queries. This improper binding could lead to - infinite sequence of calls of recursive functions - crashes due to resolution of null pointers - wrong result sets returned by queries - bogus error messages If the definition of a CTE contains with clauses then such CTE is called embedding CTE while CTEs from the with clauses are called embedded CTEs. If a table reference used in the definition of an embedded CTE cannot be resolved within the unit that contains this reference it still may be resolved against a CTE definition from the with clause with one of the embedding CTEs. A table reference can be resolved against a CTE definition if it used in the the scope of this definition and it refers to the name of the CTE. Table reference t is in the scope of the CTE definition of CTE cte if - the definition of cte is an element of a with clause declared as RECURSIVE and the reference t belongs either to the unit to which this with clause is attached or to one of the elements of this clause - the definition of cte is an element of a with clause without RECURSIVE specifier and the reference t belongs either to the unit to which this with clause is attached or to one of the elements from this clause that are placed before the definition of cte. If a table reference can be resolved against several CTE definitions then it is bound to the most embedded. The code before this patch not always resolved table references used in embedded CTE according to the above rules. Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
@ -5017,5 +5017,591 @@ t2 CREATE TABLE `t2` (
|
||||
set @@sql_mode=default;
|
||||
drop table t1,t2;
|
||||
#
|
||||
# MDEV-29361: Embedded recursive / non-recursive CTE within
|
||||
# the scope of another embedded CTE with the same name
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (4), (5);
|
||||
create table t2 (a int);
|
||||
insert into t2 values (6), (8);
|
||||
create table t3 (a int);
|
||||
insert into t3 values (1), (9);
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1;
|
||||
a
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2;
|
||||
a
|
||||
6
|
||||
8
|
||||
10
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
6
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with recursive
|
||||
x(a) as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select s1.a from x as s1, x
|
||||
where s1.a = x.a and
|
||||
x.a in (
|
||||
with recursive
|
||||
x(a) as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
6
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
6
|
||||
7
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with recursive
|
||||
y as
|
||||
(
|
||||
select a from t1 union select a+1 from y as r1 where a < 7
|
||||
)
|
||||
select * from y as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
y(a) as
|
||||
(
|
||||
select a+5 from t1
|
||||
)
|
||||
select * from y as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from x as r1
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from x as r1
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a < 5 and
|
||||
s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 42S02: Table 'test.x' doesn't exist
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with recursive
|
||||
x(a) as
|
||||
(
|
||||
select a+3 from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a < 8 and
|
||||
s1.a in (
|
||||
with recursive
|
||||
x(a) as
|
||||
(
|
||||
select a-2 from t2
|
||||
union
|
||||
select a+1 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
r
|
||||
7
|
||||
7
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
r
|
||||
6
|
||||
6
|
||||
create table x (a int);
|
||||
insert into x values (3), (7), (1), (5), (6);
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select ( select a from x as r1 ) as a from t1
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select ( select a from x ) as a from t1
|
||||
)
|
||||
select exists (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
r
|
||||
1
|
||||
1
|
||||
with
|
||||
cte_e as
|
||||
(
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select ( select a from x ) from t1
|
||||
)
|
||||
select exists (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte
|
||||
)
|
||||
select s1.*, s2.* from cte_e as s1, cte_e as s2;
|
||||
r r
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1;
|
||||
a
|
||||
4
|
||||
5
|
||||
2
|
||||
6
|
||||
7
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2;
|
||||
a
|
||||
6
|
||||
8
|
||||
5
|
||||
9
|
||||
3
|
||||
7
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1;
|
||||
a
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2;
|
||||
a
|
||||
6
|
||||
8
|
||||
10
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with recursive
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
6
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t1 union select a+1 from x as r1 where a < 7
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
4
|
||||
6
|
||||
7
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with recursive
|
||||
y as
|
||||
(
|
||||
select a from t1 union select a+1 from y as r1 where a < 7
|
||||
)
|
||||
select * from y as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
5
|
||||
6
|
||||
7
|
||||
with
|
||||
cte as
|
||||
(
|
||||
with
|
||||
y(a) as
|
||||
(
|
||||
select a+5 from t1
|
||||
)
|
||||
select * from y as s1
|
||||
where s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
)
|
||||
select * from cte;
|
||||
a
|
||||
9
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from x as r1
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a in (
|
||||
with
|
||||
recursive x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
r
|
||||
6
|
||||
6
|
||||
with
|
||||
cte as
|
||||
(
|
||||
select (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from x as r1
|
||||
)
|
||||
select * from x as s1
|
||||
where s1.a < 5 and
|
||||
s1.a in (
|
||||
with
|
||||
x as
|
||||
(
|
||||
select a from t2
|
||||
union
|
||||
select a+2 from x as r2 where a < 10
|
||||
)
|
||||
select a from x as s2
|
||||
)
|
||||
) as r
|
||||
from t3
|
||||
)
|
||||
select * from cte;
|
||||
r
|
||||
3
|
||||
3
|
||||
drop table t1,t2,t3,x;
|
||||
#
|
||||
# End of 10.3 tests
|
||||
#
|
||||
|
Reference in New Issue
Block a user