Skip to content

Commit ad7da60

Browse files
committed
Fixed bug mdev-12368.
Mutually recursive CTE could cause a crash of the server in the case when they were not Standard compliant. The crash happened in mysql_derived_prepare(), because the destructor the derived_result object created for a CTE that was mutually recursive with some others was called twice. Yet this destructor should not be called for resursive references.
1 parent 5a4537f commit ad7da60

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

mysql-test/r/cte_recursive.result

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,3 +2453,38 @@ id name dob father mother
24532453
8 Grandpa Ben 1940-10-21 NULL NULL
24542454
6 Grandgrandma Martha 1923-05-17 NULL NULL
24552455
drop table folks;
2456+
#
2457+
# mdev-12368: crash with mutually recursive CTE
2458+
# that arenot Standard compliant
2459+
#
2460+
create table value_nodes (v char(4));
2461+
create table module_nodes(m char(4));
2462+
create table module_arguments(m char(4), v char(4));
2463+
create table module_results(m char(4), v char(4));
2464+
with recursive
2465+
reached_values as
2466+
(
2467+
select v from value_nodes where v in ('v3','v7','v9')
2468+
union
2469+
select module_results.v from module_results, applied_modules
2470+
where module_results.m = applied_modules.m
2471+
),
2472+
applied_modules as
2473+
(
2474+
select module_nodes.m
2475+
from
2476+
module_nodes
2477+
left join
2478+
(
2479+
module_arguments
2480+
left join
2481+
reached_values
2482+
on module_arguments.v = reached_values.v
2483+
)
2484+
on reached_values.v is null and
2485+
module_nodes.m = module_arguments.m
2486+
where module_arguments.m is null
2487+
)
2488+
select * from reached_values;
2489+
ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'applied_modules'
2490+
drop table value_nodes, module_nodes, module_arguments, module_results;

mysql-test/t/cte_recursive.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,3 +1559,42 @@ as
15591559
select * from ancestors;
15601560

15611561
drop table folks;
1562+
1563+
--echo #
1564+
--echo # mdev-12368: crash with mutually recursive CTE
1565+
--echo # that arenot Standard compliant
1566+
--echo #
1567+
1568+
create table value_nodes (v char(4));
1569+
create table module_nodes(m char(4));
1570+
create table module_arguments(m char(4), v char(4));
1571+
create table module_results(m char(4), v char(4));
1572+
1573+
--ERROR ER_NOT_STANDARD_COMPLIANT_RECURSIVE
1574+
with recursive
1575+
reached_values as
1576+
(
1577+
select v from value_nodes where v in ('v3','v7','v9')
1578+
union
1579+
select module_results.v from module_results, applied_modules
1580+
where module_results.m = applied_modules.m
1581+
),
1582+
applied_modules as
1583+
(
1584+
select module_nodes.m
1585+
from
1586+
module_nodes
1587+
left join
1588+
(
1589+
module_arguments
1590+
left join
1591+
reached_values
1592+
on module_arguments.v = reached_values.v
1593+
)
1594+
on reached_values.v is null and
1595+
module_nodes.m = module_arguments.m
1596+
where module_arguments.m is null
1597+
)
1598+
select * from reached_values;
1599+
1600+
drop table value_nodes, module_nodes, module_arguments, module_results;

sql/sql_derived.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
789789
*/
790790
if (res)
791791
{
792-
if (derived->table && !derived->is_with_table_recursive_reference())
793-
free_tmp_table(thd, derived->table);
794-
delete derived->derived_result;
792+
if (!derived->is_with_table_recursive_reference())
793+
{
794+
if (derived->table)
795+
free_tmp_table(thd, derived->table);
796+
delete derived->derived_result;
797+
}
795798
}
796799
else
797800
{

0 commit comments

Comments
 (0)