diff options
author | Igor Babaev <igor@askmonty.org> | 2020-06-05 10:38:40 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2020-06-05 11:00:07 -0700 |
commit | a8c200c73c96d35b9e58fdcde0987f0ac5cb9b1a (patch) | |
tree | e8e28673cf922cc0ab46a42c4cdd2a5ae0048a3b /sql | |
parent | fff7897e3ad421c61cf5372606044750732deba4 (diff) | |
download | mariadb-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.cc | 4 |
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; |