diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index bfca93cf6d6..7ec2b7a7072 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -2488,3 +2488,64 @@ 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; +# +# mdev-12375: query using one of two mutually recursive CTEs +# whose non-recursive part returns an empty set +# +create table value_nodes (v char(4)); +insert into value_nodes values +('v1'), ('v2'), ('v3'), ('v4'), ('v5'), ('v6'), ('v7'), ('v8'), ('v9'), +('v10'), ('v11'), ('v12'), ('v13'), ('v14'), ('v15'), ('v16'); +create table module_nodes(m char(4)); +insert into module_nodes values +('m1'), ('m2'), ('m3'), ('m4'), ('m5'), ('m6'), ('m7'); +create table module_arguments(m char(4), v char(4)); +insert into module_arguments values +('m1','v3'), ('m1','v9'), +('m2','v4'), ('m2','v3'), ('m2','v7'), +('m3','v6'), +('m4','v4'), ('m4','v1'), +('m5','v10'), ('m5','v8'), ('m5','v3'), +('m6','v8'), ('m6','v1'), +('m7','v11'), ('m7','v12'); +create table module_results(m char(4), v char(4)); +insert into module_results values +('m1','v4'), +('m2','v1'), ('m2','v6'), +('m3','v10'), +('m4','v8'), +('m5','v11'), ('m5','v9'), +('m6','v12'), ('m6','v4'), +('m7','v2'); +set statement max_recursive_iterations=2, standard_compliant_cte=0 for +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 * from module_nodes where 1=0 +union +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 applied_modules; +m +m1 +m2 +drop table value_nodes, module_nodes, module_arguments, module_results; diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index 592cdd4f8d1..dd49582e719 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -1597,4 +1597,67 @@ applied_modules as ) select * from reached_values; -drop table value_nodes, module_nodes, module_arguments, module_results; \ No newline at end of file +drop table value_nodes, module_nodes, module_arguments, module_results; + +--echo # +--echo # mdev-12375: query using one of two mutually recursive CTEs +--echo # whose non-recursive part returns an empty set +--echo # + +create table value_nodes (v char(4)); +insert into value_nodes values + ('v1'), ('v2'), ('v3'), ('v4'), ('v5'), ('v6'), ('v7'), ('v8'), ('v9'), + ('v10'), ('v11'), ('v12'), ('v13'), ('v14'), ('v15'), ('v16'); +create table module_nodes(m char(4)); +insert into module_nodes values + ('m1'), ('m2'), ('m3'), ('m4'), ('m5'), ('m6'), ('m7'); +create table module_arguments(m char(4), v char(4)); +insert into module_arguments values + ('m1','v3'), ('m1','v9'), + ('m2','v4'), ('m2','v3'), ('m2','v7'), + ('m3','v6'), + ('m4','v4'), ('m4','v1'), + ('m5','v10'), ('m5','v8'), ('m5','v3'), + ('m6','v8'), ('m6','v1'), + ('m7','v11'), ('m7','v12'); +create table module_results(m char(4), v char(4)); +insert into module_results values + ('m1','v4'), + ('m2','v1'), ('m2','v6'), + ('m3','v10'), + ('m4','v8'), + ('m5','v11'), ('m5','v9'), + ('m6','v12'), ('m6','v4'), + ('m7','v2'); + +set statement max_recursive_iterations=2, standard_compliant_cte=0 for +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 * from module_nodes where 1=0 + union + 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 applied_modules; + +drop table value_nodes, module_nodes, module_arguments, module_results; + diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 71d0e331101..f8fe8b0be00 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1247,7 +1247,7 @@ bool st_select_lex_unit::exec_recursive() thd->inc_examined_row_count(examined_rows); incr_table->file->info(HA_STATUS_VARIABLE); - if (incr_table->file->stats.records == 0) + if (with_element->level && incr_table->file->stats.records == 0) with_element->set_as_stabilized(); else with_element->level++;