1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-28201: Server crashes upon SHOW ANALYZE/EXPLAIN FORMAT=JSON

- Describe the lifetime of EXPLAIN data structures in
  sql_explain.h:ExplainDataStructureLifetime.

- Make Item_field::set_field() call set_refers_to_temp_table()
  when it refers to a temp. table.
- Introduce QT_DONT_ACCESS_TMP_TABLES flag for Item::print.
  It directs Item_field::print to not try access its the
  temp table.
- Introduce Explain_query::notify_tables_are_closed()
  and call it right before the query closes its tables.
- Make Explain data stuctures' print_explain_json() methods
  accept "no_tmp_tbl" parameter which means pass
  QT_DONT_ACCESS_TMP_TABLES when printing items.
- Make Show_explain_request::call_in_target_thread() not call
  set_current_thd(). This wasn't needed as the code inside
  lex->print_explain() uses output->thd anyway. output->thd
  refers to the SHOW command's THD object.
This commit is contained in:
Sergei Petrunia
2022-04-04 12:32:22 +03:00
parent 02c3babdec
commit 3f68c2169e
22 changed files with 319 additions and 163 deletions

View File

@@ -2998,14 +2998,18 @@ void Show_explain_request::call_in_target_thread()
target_thd->query_charset());
DBUG_ASSERT(current_thd == target_thd);
set_current_thd(request_thd);
/*
When producing JSON output, one should not change current_thd.
(If one does that, they will hit an assert when printing constant item
fields).
*/
if (target_thd->lex->print_explain(explain_buf, 0 /* explain flags*/,
is_analyze, is_json_format,
&printed_anything))
{
failed_to_produce= TRUE;
}
set_current_thd(target_thd);
if (!printed_anything)
failed_to_produce= TRUE;
@@ -3024,6 +3028,8 @@ int select_result_explain_buffer::send_data(List<Item> &items)
Switch to the receiveing thread, so that we correctly count memory used
by it. This is needed as it's the receiving thread that will free the
memory.
(TODO: Now that we don't change current_thd in
Show_explain_request::call_in_target_thread, is this necessary anymore?)
*/
set_current_thd(thd);
fill_record(thd, dst_table, dst_table->field, items, TRUE, FALSE);