1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-17024 Crash on large query

This problem manifested itself when a join query used two or more
materialized CTE such that each of them employed the same recursive CTE.
The bug caused a crash. The crash happened because the cleanup()
function was performed premature for recursive CTE. This clean up was
induced by the cleanup of the first CTE referenced the recusrsive CTE.
This cleanup destroyed the structures that would allow to read from the
temporary table containing the rows of the recursive CTE and an attempt to read
these rows for the second CTE referencing the recursive CTE triggered a
crash.
The clean up for a recursive CTE R should be performed after the cleanup
of the last materialized CTE that uses R.
This commit is contained in:
Igor Babaev
2018-09-07 20:10:04 -07:00
parent 59950df533
commit 4d991abd4f
7 changed files with 222 additions and 5 deletions

View File

@ -2323,3 +2323,70 @@ RETURN
SELECT func();
DROP FUNCTION func;
--echo #
--echo # MDEV-17024: two materialized CTEs using the same recursive CTE
--echo #
create table t1 (id int);
insert into t1 values (1), (2), (3);
let $q=
with recursive
rcte(a) as
(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
cte1 as
(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
select * from cte1, cte2;
eval $q;
eval explain extended $q;
eval prepare stmt from "$q";
execute stmt;
execute stmt;
create table t2 (c1 int, c2 int);
eval create procedure p() insert into t2 $q;
call p();
select * from t2;
let $q1=
with recursive
rcte(a) as
(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
cte1 as
(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
select * from cte1;
eval $q1;
let $q2=
with recursive
rcte(a) as
(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
cte1 as
(select count(*) as c1 from t1),
cte2 as
(select count(*) as c2 from t2)
select * from cte1,cte2;
eval $q2;
let $q3=
with recursive
rcte(a) as
(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
cte1 as
(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
select * from cte1, cte2 where cte1.c1 = 3;
eval $q3;
drop procedure p;
drop table t1,t2;