summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2020-06-05 10:38:40 -0700
committerIgor Babaev <igor@askmonty.org>2020-06-05 11:00:07 -0700
commita8c200c73c96d35b9e58fdcde0987f0ac5cb9b1a (patch)
treee8e28673cf922cc0ab46a42c4cdd2a5ae0048a3b /sql
parentfff7897e3ad421c61cf5372606044750732deba4 (diff)
downloadmariadb-git-a8c200c73c96d35b9e58fdcde0987f0ac5cb9b1a.tar.gz
MDEV-22042 Server crash in Item_field::print on ANALYZE FORMAT=JSON
When processing a query with a recursive CTE a temporary table is used for each recursive reference of the CTE. As any temporary table it uses its own mem-root for table definition structures. Due to specifics of the current implementation of ANALYZE stmt command this mem-root can be freed only at the very of query processing. Such deallocation of mem-root memory happens in close_thread_tables(). The function looks through the list of the tmp tables rec_tables attached to the THD of the query and frees corresponding mem-roots. If the query uses a stored function then such list is created for each query of the function. When a new rec_list has to be created the old one has to be saved and then restored at the proper moment. The bug occurred because only one rec_list for the query containing CTE was created. As a result close_thread_tables() freed tmp mem-roots used for rec_tables prematurely destroying some data needed for the output produced by the ANALYZE command.
Diffstat (limited to 'sql')
-rw-r--r--sql/sp_head.cc4
1 files changed, 4 insertions, 0 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 464f2df1506..6a650183fb8 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1126,6 +1126,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
backup_arena;
query_id_t old_query_id;
TABLE *old_derived_tables;
+ TABLE *old_rec_tables;
LEX *old_lex;
Item_change_list old_change_list;
String old_packet;
@@ -1201,6 +1202,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
old_query_id= thd->query_id;
old_derived_tables= thd->derived_tables;
thd->derived_tables= 0;
+ old_rec_tables= thd->rec_tables;
+ thd->rec_tables= 0;
save_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode= m_sql_mode;
save_abort_on_warning= thd->abort_on_warning;
@@ -1468,6 +1471,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
thd->set_query_id(old_query_id);
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
+ thd->rec_tables= old_rec_tables;
thd->variables.sql_mode= save_sql_mode;
thd->abort_on_warning= save_abort_on_warning;
thd->m_reprepare_observer= save_reprepare_observer;