[Commits] 3394cb1: Fixed bug mdev-12368.

IgorBabaev igor at mariadb.com
Mon Mar 27 08:59:33 EEST 2017


revision-id: 3394cb183184716e5d2a4020893e838c4a5e0099 (mariadb-10.2.4-82-g3394cb1)
parent(s): 752422f1a7d71f80883603ee6984a55a92e5d5f9
author: Igor Babaev
committer: Igor Babaev
timestamp: 2017-03-26 22:59:33 -0700
message:

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.

---
 mysql-test/r/cte_recursive.result | 35 +++++++++++++++++++++++++++++++++++
 mysql-test/t/cte_recursive.test   | 39 +++++++++++++++++++++++++++++++++++++++
 sql/sql_derived.cc                |  9 ++++++---
 3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result
index 6d59d67..bfca93c 100644
--- a/mysql-test/r/cte_recursive.result
+++ b/mysql-test/r/cte_recursive.result
@@ -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;
diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test
index 37f66bb..592cdd4 100644
--- a/mysql-test/t/cte_recursive.test
+++ b/mysql-test/t/cte_recursive.test
@@ -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;
\ No newline at end of file
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 76cb27d..faf6dd7 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -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
   {


More information about the commits mailing list