Skip to content

Commit

Permalink
Fixed bug mdev-12368.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
igorbabaev committed Mar 27, 2017
1 parent 5a4537f commit ad7da60
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
35 changes: 35 additions & 0 deletions mysql-test/r/cte_recursive.result
Original file line number Diff line number Diff line change
Expand Up @@ -2453,3 +2453,38 @@ id name dob father mother
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL
drop table folks;
#
# mdev-12368: crash with mutually recursive CTE
# that arenot Standard compliant
#
create table value_nodes (v char(4));
create table module_nodes(m char(4));
create table module_arguments(m char(4), v char(4));
create table module_results(m char(4), v char(4));
with recursive
reached_values as
(
select v from value_nodes where v in ('v3','v7','v9')
union
select module_results.v from module_results, applied_modules
where module_results.m = applied_modules.m
),
applied_modules as
(
select module_nodes.m
from
module_nodes
left join
(
module_arguments
left join
reached_values
on module_arguments.v = reached_values.v
)
on reached_values.v is null and
module_nodes.m = module_arguments.m
where module_arguments.m is null
)
select * from reached_values;
ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'applied_modules'
drop table value_nodes, module_nodes, module_arguments, module_results;
39 changes: 39 additions & 0 deletions mysql-test/t/cte_recursive.test
Original file line number Diff line number Diff line change
Expand Up @@ -1559,3 +1559,42 @@ as
select * from ancestors;

drop table folks;

--echo #
--echo # mdev-12368: crash with mutually recursive CTE
--echo # that arenot Standard compliant
--echo #

create table value_nodes (v char(4));
create table module_nodes(m char(4));
create table module_arguments(m char(4), v char(4));
create table module_results(m char(4), v char(4));

--ERROR ER_NOT_STANDARD_COMPLIANT_RECURSIVE
with recursive
reached_values as
(
select v from value_nodes where v in ('v3','v7','v9')
union
select module_results.v from module_results, applied_modules
where module_results.m = applied_modules.m
),
applied_modules as
(
select module_nodes.m
from
module_nodes
left join
(
module_arguments
left join
reached_values
on module_arguments.v = reached_values.v
)
on reached_values.v is null and
module_nodes.m = module_arguments.m
where module_arguments.m is null
)
select * from reached_values;

drop table value_nodes, module_nodes, module_arguments, module_results;
9 changes: 6 additions & 3 deletions sql/sql_derived.cc
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
*/
if (res)
{
if (derived->table && !derived->is_with_table_recursive_reference())
free_tmp_table(thd, derived->table);
delete derived->derived_result;
if (!derived->is_with_table_recursive_reference())
{
if (derived->table)
free_tmp_table(thd, derived->table);
delete derived->derived_result;
}
}
else
{
Expand Down

0 comments on commit ad7da60

Please sign in to comment.