diff options
author | Igor Babaev <igor@askmonty.org> | 2018-09-07 20:10:04 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2018-09-07 20:10:45 -0700 |
commit | 4d991abd4fc7f60e758ec46301b0dd2bee71245c (patch) | |
tree | 3e8762387f950f8adb62910da5b274a49e01dbec /sql/sql_derived.cc | |
parent | 59950df533ab7231c77a59ec3e27cef855318939 (diff) | |
download | mariadb-git-4d991abd4fc7f60e758ec46301b0dd2bee71245c.tar.gz |
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.
Diffstat (limited to 'sql/sql_derived.cc')
-rw-r--r-- | sql/sql_derived.cc | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0147271f068..44f8d74790f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1083,6 +1083,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_ASSERT(derived->table && derived->table->is_created()); select_union *derived_result= derived->derived_result; SELECT_LEX *save_current_select= lex->current_select; + bool derived_recursive_is_filled= false; if (derived_is_recursive) { @@ -1095,6 +1096,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) { /* In this case all iteration are performed */ res= derived->fill_recursive(thd); + derived_recursive_is_filled= true; } } else if (unit->is_union()) @@ -1150,7 +1152,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) } } - if (res || (!lex->describe && !derived_is_recursive)) + if (res || (!lex->describe && + (!derived_is_recursive || + derived_recursive_is_filled))) unit->cleanup(); lex->current_select= save_current_select; |