summaryrefslogtreecommitdiff
path: root/sql/sql_explain.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_explain.cc')
-rw-r--r--sql/sql_explain.cc384
1 files changed, 257 insertions, 127 deletions
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 92f221513f2..15ee67a0318 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -23,6 +23,7 @@
#include "sql_select.h"
#include "my_json_writer.h"
#include "opt_range.h"
+#include "sql_expression_cache.h"
const char * STR_DELETING_ALL_ROWS= "Deleting all rows";
const char * STR_IMPOSSIBLE_WHERE= "Impossible WHERE";
@@ -203,7 +204,8 @@ int Explain_query::print_explain(select_result_sink *output,
}
-void Explain_query::print_explain_json(select_result_sink *output, bool is_analyze)
+void Explain_query::print_explain_json(select_result_sink *output,
+ bool is_analyze)
{
Json_writer writer;
writer.start_object();
@@ -226,7 +228,9 @@ void Explain_query::print_explain_json(select_result_sink *output, bool is_analy
CHARSET_INFO *cs= system_charset_info;
List<Item> item_list;
String *buf= &writer.output;
- item_list.push_back(new Item_string(buf->ptr(), buf->length(), cs));
+ item_list.push_back(new (thd->mem_root)
+ Item_string(thd, buf->ptr(), buf->length(), cs),
+ thd->mem_root);
output->send_data(item_list);
}
@@ -256,19 +260,22 @@ bool Explain_query::print_explain_str(THD *thd, String *out_str,
}
-static void push_str(List<Item> *item_list, const char *str)
+static void push_str(THD *thd, List<Item> *item_list, const char *str)
{
- item_list->push_back(new Item_string_sys(str));
+ item_list->push_back(new (thd->mem_root) Item_string_sys(thd, str),
+ thd->mem_root);
}
-static void push_string(List<Item> *item_list, String *str)
+static void push_string(THD *thd, List<Item> *item_list, String *str)
{
- item_list->push_back(new Item_string_sys(str->ptr(), str->length()));
+ item_list->push_back(new (thd->mem_root)
+ Item_string_sys(thd, str->ptr(), str->length()),
+ thd->mem_root);
}
-static void push_string_list(List<Item> *item_list, String_list &lines,
- String *buf)
+static void push_string_list(THD *thd, List<Item> *item_list,
+ String_list &lines, String *buf)
{
List_iterator_fast<char> it(lines);
char *line;
@@ -282,7 +289,7 @@ static void push_string_list(List<Item> *item_list, String_list &lines,
buf->append(line);
}
- push_string(item_list, buf);
+ push_string(thd, item_list, buf);
}
@@ -315,79 +322,89 @@ int print_explain_row(select_result_sink *result,
double r_filtered,
const char *extra)
{
- Item *item_null= new Item_null();
+ THD *thd= result->thd;
+ MEM_ROOT *mem_root= thd->mem_root;
+ Item *item_null= new (mem_root) Item_null(thd);
List<Item> item_list;
Item *item;
- item_list.push_back(new Item_int((int32) select_number));
- item_list.push_back(new Item_string_sys(select_type));
- item_list.push_back(new Item_string_sys(table_name));
+ item_list.push_back(new (mem_root) Item_int(thd, (int32) select_number),
+ mem_root);
+ item_list.push_back(new (mem_root) Item_string_sys(thd, select_type),
+ mem_root);
+ item_list.push_back(new (mem_root) Item_string_sys(thd, table_name),
+ mem_root);
if (options & DESCRIBE_PARTITIONS)
{
if (partitions)
{
- item_list.push_back(new Item_string_sys(partitions));
+ item_list.push_back(new (mem_root) Item_string_sys(thd, partitions),
+ mem_root);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
const char *jtype_str= join_type_str[jtype];
- item_list.push_back(new Item_string_sys(jtype_str));
+ item_list.push_back(new (mem_root) Item_string_sys(thd, jtype_str),
+ mem_root);
/* 'possible_keys' */
if (possible_keys && !possible_keys->is_empty())
{
StringBuffer<64> possible_keys_buf;
- push_string_list(&item_list, *possible_keys, &possible_keys_buf);
+ push_string_list(thd, &item_list, *possible_keys, &possible_keys_buf);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* 'index */
- item= index ? new Item_string_sys(index) : item_null;
- item_list.push_back(item);
+ item= index ? new (mem_root) Item_string_sys(thd, index) : item_null;
+ item_list.push_back(item, mem_root);
/* 'key_len */
- item= key_len ? new Item_string_sys(key_len) : item_null;
- item_list.push_back(item);
+ item= key_len ? new (mem_root) Item_string_sys(thd, key_len) : item_null;
+ item_list.push_back(item, mem_root);
/* 'ref' */
- item= ref ? new Item_string_sys(ref) : item_null;
- item_list.push_back(item);
+ item= ref ? new (mem_root) Item_string_sys(thd, ref) : item_null;
+ item_list.push_back(item, mem_root);
/* 'rows' */
if (rows)
{
- item_list.push_back(new Item_int(*rows,
- MY_INT64_NUM_DECIMAL_DIGITS));
+ item_list.push_back(new (mem_root)
+ Item_int(thd, *rows, MY_INT64_NUM_DECIMAL_DIGITS),
+ mem_root);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* 'r_rows' */
if (is_analyze)
{
if (r_rows)
- item_list.push_back(new Item_float(*r_rows, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, *r_rows, 2),
+ mem_root);
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
/* 'filtered' */
const double filtered=100.0;
if (options & DESCRIBE_EXTENDED || is_analyze)
- item_list.push_back(new Item_float(filtered, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, filtered, 2), mem_root);
/* 'r_filtered' */
if (is_analyze)
- item_list.push_back(new Item_float(r_filtered, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, r_filtered, 2),
+ mem_root);
/* 'Extra' */
if (extra)
- item_list.push_back(new Item_string_sys(extra));
+ item_list.push_back(new (mem_root) Item_string_sys(thd, extra), mem_root);
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
if (result->send_data(item_list))
return 1;
@@ -430,7 +447,8 @@ int Explain_union::print_explain(Explain_query *query,
uint8 explain_flags,
bool is_analyze)
{
- //CHARSET_INFO *cs= system_charset_info;
+ THD *thd= output->thd;
+ MEM_ROOT *mem_root= thd->mem_root;
char table_name_buffer[SAFE_NAME_LEN];
/* print all UNION children, in order */
@@ -445,54 +463,56 @@ int Explain_union::print_explain(Explain_query *query,
/* Print a line with "UNION RESULT" */
List<Item> item_list;
- Item *item_null= new Item_null();
+ Item *item_null= new (mem_root) Item_null(thd);
/* `id` column */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `select_type` column */
- push_str(&item_list, fake_select_type);
+ push_str(thd, &item_list, fake_select_type);
/* `table` column: something like "<union1,2>" */
uint len= make_union_table_name(table_name_buffer);
- item_list.push_back(new Item_string_sys(table_name_buffer, len));
+ item_list.push_back(new (mem_root)
+ Item_string_sys(thd, table_name_buffer, len),
+ mem_root);
/* `partitions` column */
if (explain_flags & DESCRIBE_PARTITIONS)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `type` column */
- push_str(&item_list, join_type_str[JT_ALL]);
+ push_str(thd, &item_list, join_type_str[JT_ALL]);
/* `possible_keys` column */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `key` */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `key_len` */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `ref` */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `rows` */
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `r_rows` */
if (is_analyze)
{
double avg_rows= fake_select_lex_tracker.get_avg_rows();
- item_list.push_back(new Item_float(avg_rows, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, avg_rows, 2), mem_root);
}
/* `filtered` */
if (explain_flags & DESCRIBE_EXTENDED || is_analyze)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `r_filtered` */
if (is_analyze)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `Extra` */
StringBuffer<256> extra_buf;
@@ -500,7 +520,10 @@ int Explain_union::print_explain(Explain_query *query,
{
extra_buf.append(STRING_WITH_LEN("Using filesort"));
}
- item_list.push_back(new Item_string_sys(extra_buf.ptr(), extra_buf.length()));
+ item_list.push_back(new (mem_root)
+ Item_string_sys(thd, extra_buf.ptr(),
+ extra_buf.length()),
+ mem_root);
//output->unit.offset_limit_cnt= 0;
if (output->send_data(item_list))
@@ -520,6 +543,8 @@ void Explain_union::print_explain_json(Explain_query *query,
Json_writer_nesting_guard guard(writer);
char table_name_buffer[SAFE_NAME_LEN];
+ bool started_object= print_explain_json_cache(writer, is_analyze);
+
writer->add_member("query_block").start_object();
writer->add_member("union_result").start_object();
// using_temporary_table
@@ -560,6 +585,9 @@ void Explain_union::print_explain_json(Explain_query *query,
writer->end_object(); // union_result
writer->end_object(); // query_block
+
+ if (started_object)
+ writer->end_object();
}
@@ -640,6 +668,35 @@ void Explain_node::print_explain_json_for_children(Explain_query *query,
}
+bool Explain_node::print_explain_json_cache(Json_writer *writer,
+ bool is_analyze)
+{
+ if (cache_tracker)
+ {
+ cache_tracker->fetch_current_stats();
+ writer->add_member("expression_cache").start_object();
+ if (cache_tracker->state != Expression_cache_tracker::OK)
+ {
+ writer->add_member("state").
+ add_str(Expression_cache_tracker::state_str[cache_tracker->state]);
+ }
+
+ if (is_analyze)
+ {
+ longlong cache_reads= cache_tracker->hit + cache_tracker->miss;
+ writer->add_member("r_loops").add_ll(cache_reads);
+ if (cache_reads != 0)
+ {
+ double hit_ratio= double(cache_tracker->hit) / cache_reads * 100.0;
+ writer->add_member("r_hit_ratio").add_double(hit_ratio);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+
void Explain_select::replace_table(uint idx, Explain_table_access *new_tab)
{
delete join_tabs[idx];
@@ -661,38 +718,72 @@ int Explain_select::print_explain(Explain_query *query,
select_result_sink *output,
uint8 explain_flags, bool is_analyze)
{
+ THD *thd= output->thd;
+ MEM_ROOT *mem_root= thd->mem_root;
+
if (message)
{
List<Item> item_list;
- Item *item_null= new Item_null();
+ Item *item_null= new (mem_root) Item_null(thd);
- item_list.push_back(new Item_int((int32) select_id));
- item_list.push_back(new Item_string_sys(select_type));
+ item_list.push_back(new (mem_root) Item_int(thd, (int32) select_id),
+ mem_root);
+ item_list.push_back(new (mem_root) Item_string_sys(thd, select_type),
+ mem_root);
for (uint i=0 ; i < 7; i++)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
if (explain_flags & DESCRIBE_PARTITIONS)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* filtered */
if (is_analyze || explain_flags & DESCRIBE_EXTENDED)
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
if (is_analyze)
{
/* r_rows, r_filtered */
- item_list.push_back(item_null);
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
+ item_list.push_back(item_null, mem_root);
}
- item_list.push_back(new Item_string_sys(message));
+ item_list.push_back(new (mem_root) Item_string_sys(thd, message),
+ mem_root);
if (output->send_data(item_list))
return 1;
}
else
{
- bool using_tmp= using_temporary;
- bool using_fs= using_filesort;
+ bool using_tmp;
+ bool using_fs;
+
+ if (is_analyze)
+ {
+ /*
+ Get the data about "Using temporary; Using filesort" from execution
+ tracking system.
+ */
+ using_tmp= false;
+ using_fs= false;
+ Sort_and_group_tracker::Iterator iter(&ops_tracker);
+ enum_qep_action action;
+ Filesort_tracker *dummy;
+
+ while ((action= iter.get_next(&dummy)) != EXPL_ACTION_EOF)
+ {
+ if (action == EXPL_ACTION_FILESORT)
+ using_fs= true;
+ else if (action == EXPL_ACTION_TEMPTABLE)
+ using_tmp= true;
+ }
+ }
+ else
+ {
+ /* Use imprecise "estimates" we got with the query plan */
+ using_tmp= using_temporary;
+ using_fs= using_filesort;
+ }
+
for (uint i=0; i< n_join_tabs; i++)
{
join_tabs[i]->print_explain(output, explain_flags, is_analyze, select_id,
@@ -740,6 +831,8 @@ void Explain_select::print_explain_json(Explain_query *query,
Json_writer *writer, bool is_analyze)
{
Json_writer_nesting_guard guard(writer);
+
+ bool started_cache= print_explain_json_cache(writer, is_analyze);
if (message)
{
@@ -757,12 +850,13 @@ void Explain_select::print_explain_json(Explain_query *query,
{
writer->add_member("query_block").start_object();
writer->add_member("select_id").add_ll(select_id);
-
+
if (is_analyze && time_tracker.get_loops())
{
writer->add_member("r_loops").add_ll(time_tracker.get_loops());
writer->add_member("r_total_time_ms").add_double(time_tracker.get_time_ms());
}
+
if (exec_const_cond)
{
writer->add_member("const_condition");
@@ -770,47 +864,62 @@ void Explain_select::print_explain_json(Explain_query *query,
}
Filesort_tracker *first_table_sort= NULL;
+ bool first_table_sort_used= false;
int started_objects= 0;
if (is_analyze)
{
/* ANALYZE has collected this part of query plan independently */
- for (int i= ops_tracker.n_actions-1; i >= 0; i--)
+ if (ops_tracker.had_varied_executions())
+ {
+ writer->add_member("varied-sort-and-tmp").start_object();
+ started_objects++;
+ }
+ else
{
- if (ops_tracker.qep_actions[i] == EXPL_ACTION_FILESORT)
+ Sort_and_group_tracker::Iterator iter(&ops_tracker);
+ enum_qep_action action;
+ Filesort_tracker *fs_tracker;
+
+ while ((action= iter.get_next(&fs_tracker)) != EXPL_ACTION_EOF)
{
- if (i == 0)
+ if (action == EXPL_ACTION_FILESORT)
{
- /* filesort operation was the first in the pipeline */
- first_table_sort= &ops_tracker.filesort_tracker[0];
- break;
+ if (iter.is_last_element())
+ {
+ first_table_sort= fs_tracker;
+ break;
+ }
+ writer->add_member("filesort").start_object();
+ started_objects++;
+ fs_tracker->print_json_members(writer);
+ }
+ else if (action == EXPL_ACTION_TEMPTABLE)
+ {
+ writer->add_member("temporary_table").start_object();
+ started_objects++;
+ /*
+ if (tmp == EXPL_TMP_TABLE_BUFFER)
+ func= "buffer";
+ else if (tmp == EXPL_TMP_TABLE_GROUP)
+ func= "group-by";
+ else
+ func= "distinct";
+ writer->add_member("function").add_str(func);
+ */
+ }
+ else if (action == EXPL_ACTION_REMOVE_DUPS)
+ {
+ writer->add_member("duplicate_removal").start_object();
+ started_objects++;
}
- writer->add_member("filesort").start_object();
- started_objects++;
- }
- else if (ops_tracker.qep_actions[i] == EXPL_ACTION_TEMPTABLE)
- {
- writer->add_member("temporary_table").start_object();
- started_objects++;
- /*
- if (tmp == EXPL_TMP_TABLE_BUFFER)
- func= "buffer";
- else if (tmp == EXPL_TMP_TABLE_GROUP)
- func= "group-by";
else
- func= "distinct";
- writer->add_member("function").add_str(func);
- */
+ DBUG_ASSERT(0);
}
- else if (ops_tracker.qep_actions[i] == EXPL_ACTION_REMOVE_DUPS)
- {
- writer->add_member("duplicate_removal").start_object();
- started_objects++;
- }
- else
- DBUG_ASSERT(0);
}
+ if (first_table_sort)
+ first_table_sort_used= true;
}
else
{
@@ -828,13 +937,15 @@ void Explain_select::print_explain_json(Explain_query *query,
}
else
{
+ fprintf(stderr, "Weird!\n");
if (using_filesort)
- first_table_sort= &ops_tracker.filesort_tracker[0];
+ first_table_sort_used= true;
}
}
-
+
Explain_basic_join::print_explain_json_interns(query, writer, is_analyze,
- first_table_sort);
+ first_table_sort,
+ first_table_sort_used);
for (;started_objects; started_objects--)
writer->end_object();
@@ -842,6 +953,8 @@ void Explain_select::print_explain_json(Explain_query *query,
writer->end_object();
}
+ if (started_cache)
+ writer->end_object();
}
@@ -852,7 +965,7 @@ void Explain_basic_join::print_explain_json(Explain_query *query,
writer->add_member("query_block").start_object();
writer->add_member("select_id").add_ll(select_id);
- print_explain_json_interns(query, writer, is_analyze, NULL);
+ print_explain_json_interns(query, writer, is_analyze, NULL, false);
writer->end_object();
}
@@ -862,7 +975,8 @@ void Explain_basic_join::
print_explain_json_interns(Explain_query *query,
Json_writer *writer,
bool is_analyze,
- Filesort_tracker *first_table_sort)
+ Filesort_tracker *first_table_sort,
+ bool first_table_sort_used)
{
Json_writer_nesting_guard guard(writer);
for (uint i=0; i< n_join_tabs; i++)
@@ -871,7 +985,11 @@ print_explain_json_interns(Explain_query *query,
writer->add_member("duplicates_removal").start_object();
join_tabs[i]->print_explain_json(query, writer, is_analyze,
- (i==0)? first_table_sort : NULL);
+ first_table_sort,
+ first_table_sort_used);
+
+ first_table_sort= NULL;
+ first_table_sort_used= false;
if (join_tabs[i]->end_dups_weedout)
writer->end_object();
@@ -1016,58 +1134,60 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
uint select_id, const char *select_type,
bool using_temporary, bool using_filesort)
{
- //CHARSET_INFO *cs= system_charset_info;
+ THD *thd= output->thd;
+ MEM_ROOT *mem_root= thd->mem_root;
List<Item> item_list;
- Item *item_null= new Item_null();
+ Item *item_null= new (mem_root) Item_null(thd);
/* `id` column */
- item_list.push_back(new Item_int((int32) select_id));
+ item_list.push_back(new (mem_root) Item_int(thd, (int32) select_id),
+ mem_root);
/* `select_type` column */
- push_str(&item_list, select_type);
+ push_str(thd, &item_list, select_type);
/* `table` column */
- push_string(&item_list, &table_name);
+ push_string(thd, &item_list, &table_name);
/* `partitions` column */
if (explain_flags & DESCRIBE_PARTITIONS)
{
if (used_partitions_set)
{
- push_string(&item_list, &used_partitions);
+ push_string(thd, &item_list, &used_partitions);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
/* `type` column */
- push_str(&item_list, join_type_str[type]);
+ push_str(thd, &item_list, join_type_str[type]);
/* `possible_keys` column */
StringBuffer<64> possible_keys_buf;
if (possible_keys.is_empty())
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
else
- push_string_list(&item_list, possible_keys, &possible_keys_buf);
+ push_string_list(thd, &item_list, possible_keys, &possible_keys_buf);
/* `key` */
StringBuffer<64> key_str;
fill_key_str(&key_str, false);
if (key_str.length() > 0)
- push_string(&item_list, &key_str);
+ push_string(thd, &item_list, &key_str);
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `key_len` */
StringBuffer<64> key_len_str;
fill_key_len_str(&key_len_str);
if (key_len_str.length() > 0)
- push_string(&item_list, &key_len_str);
+ push_string(thd, &item_list, &key_len_str);
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `ref` */
StringBuffer<64> ref_list_buf;
@@ -1076,34 +1196,37 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
if (type == JT_FT)
{
/* Traditionally, EXPLAIN lines with type=fulltext have ref='' */
- push_str(&item_list, "");
+ push_str(thd, &item_list, "");
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
else
- push_string_list(&item_list, ref_list, &ref_list_buf);
+ push_string_list(thd, &item_list, ref_list, &ref_list_buf);
/* `rows` */
if (rows_set)
{
- item_list.push_back(new Item_int((longlong) (ulonglong) rows,
- MY_INT64_NUM_DECIMAL_DIGITS));
+ item_list.push_back(new (mem_root)
+ Item_int(thd, (longlong) (ulonglong) rows,
+ MY_INT64_NUM_DECIMAL_DIGITS),
+ mem_root);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
/* `r_rows` */
if (is_analyze)
{
if (!tracker.has_scans())
{
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
else
{
double avg_rows= tracker.get_avg_rows();
- item_list.push_back(new Item_float(avg_rows, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, avg_rows, 2),
+ mem_root);
}
}
@@ -1112,10 +1235,11 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
{
if (filtered_set)
{
- item_list.push_back(new Item_float(filtered, 2));
+ item_list.push_back(new (mem_root) Item_float(thd, filtered, 2),
+ mem_root);
}
else
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
/* `r_filtered` */
@@ -1123,14 +1247,16 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
{
if (!tracker.has_scans())
{
- item_list.push_back(item_null);
+ item_list.push_back(item_null, mem_root);
}
else
{
double r_filtered= tracker.get_filtered_after_where();
if (bka_type.is_using_jbuf())
r_filtered *= jbuf_tracker.get_filtered_after_where();
- item_list.push_back(new Item_float(r_filtered*100.0, 2));
+ item_list.push_back(new (mem_root)
+ Item_float(thd, r_filtered * 100.0, 2),
+ mem_root);
}
}
@@ -1164,7 +1290,10 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
extra_buf.append(STRING_WITH_LEN("Using filesort"));
}
- item_list.push_back(new Item_string_sys(extra_buf.ptr(), extra_buf.length()));
+ item_list.push_back(new (mem_root)
+ Item_string_sys(thd, extra_buf.ptr(),
+ extra_buf.length()),
+ mem_root);
if (output->send_data(item_list))
return 1;
@@ -1314,11 +1443,12 @@ void add_json_keyset(Json_writer *writer, const char *elem_name,
void Explain_table_access::print_explain_json(Explain_query *query,
Json_writer *writer,
bool is_analyze,
- Filesort_tracker *fs_tracker)
+ Filesort_tracker *fs_tracker,
+ bool first_table_sort_used)
{
Json_writer_nesting_guard guard(writer);
- if (fs_tracker)
+ if (first_table_sort_used)
{
/* filesort was invoked on this join tab before doing the join with the rest */
writer->add_member("read_sorted_file").start_object();
@@ -1346,7 +1476,7 @@ void Explain_table_access::print_explain_json(Explain_query *query,
}
writer->add_member("filesort").start_object();
if (is_analyze)
- fs_tracker->print_json(writer);
+ fs_tracker->print_json_members(writer);
}
if (bka_type.is_using_jbuf())
@@ -1537,7 +1667,7 @@ void Explain_table_access::print_explain_json(Explain_query *query,
writer->end_object();
}
- if (fs_tracker)
+ if (first_table_sort_used)
{
writer->end_object(); // filesort
writer->end_object(); // read_sorted_file
@@ -1976,7 +2106,7 @@ void Explain_update::print_explain_json(Explain_query *query,
{
writer->add_member("filesort").start_object();
if (is_analyze)
- filesort_tracker->print_json(writer);
+ filesort_tracker->print_json_members(writer);
doing_buffering= true;
}