From a9d43d70f5d83ac652fd970f5b2b8dfdb77c1136 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 12 Aug 2014 18:14:56 +0400 Subject: [PATCH] EXPLAIN FORMAT=JSON: produce the 'ref' column. --- mysql-test/r/explain_json.result | 1 + sql/sql_explain.cc | 38 +++++++++++++++++++++++++++----- sql/sql_explain.h | 15 ++++++++----- sql/sql_select.cc | 36 +++++------------------------- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result index 6f38892ef05..8ef2b9f2e8c 100644 --- a/mysql-test/r/explain_json.result +++ b/mysql-test/r/explain_json.result @@ -64,6 +64,7 @@ EXPLAIN "key": "a", "used_key_parts": "TODO", "key_length": "5", + "ref": ["test.t0.a"], "rows": 1, "filtered": 100 } diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 846868197ac..f7fc3b106ce 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -253,7 +253,7 @@ static void push_string(List *item_list, String *str) system_charset_info)); } -static void push_string_list(List *item_list, List &lines, +static void push_string_list(List *item_list, String_list &lines, String *buf) { List_iterator_fast it(lines); @@ -677,10 +677,11 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai item_list.push_back(item_null); /* `ref` */ - if (ref_set) - push_string(&item_list, &ref); - else + StringBuffer<64> ref_list_buf; + if (ref_list.is_empty()) item_list.push_back(item_null); + else + push_string_list(&item_list, ref_list, &ref_list_buf); /* `rows` */ if (rows_set) @@ -772,6 +773,18 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai } +bool String_list::append_str(MEM_ROOT *mem_root, const char *str) +{ + size_t len= strlen(str); + char *cp; + if (!(cp = (char*)alloc_root(mem_root, len))) + return 1; + memcpy(cp, str, len+1); + push_back(cp); + return 0; +} + + static void write_item(Json_writer *writer, Item *item) { THD *thd= current_thd; @@ -857,12 +870,26 @@ void Explain_table_access::print_explain_json(Json_writer *writer, /* `used_key_parts` */ if (key_str.length()) writer->add_member("used_key_parts").add_str("TODO"); - + + /* `key_length` */ StringBuffer<64> key_len_str; fill_key_len_str(&key_len_str); if (key_len_str.length()) writer->add_member("key_length").add_str(key_len_str); + + /* `ref` */ + // TODO: need to print this as an array. + if (!ref_list.is_empty()) + { + List_iterator_fast it(ref_list); + const char *str; + writer->add_member("ref").start_array(); + while ((str= it++)) + writer->add_str(str); + writer->end_array(); + } + /* `rows` */ if (rows_set) writer->add_member("rows").add_ll(rows); @@ -873,6 +900,7 @@ void Explain_table_access::print_explain_json(Json_writer *writer, writer->add_member("r_rows").add_ll(avg_rows); } + /* `filtered` */ if (filtered_set) writer->add_member("filtered").add_double(filtered); diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 8708a74e661..26aa5753900 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -464,6 +464,13 @@ private: }; +class String_list: public List +{ +public: + bool append_str(MEM_ROOT *mem_root, const char *str); +}; + + /* EXPLAIN data structure for a single JOIN_TAB. */ @@ -489,9 +496,8 @@ public: StringBuffer<32> used_partitions; bool used_partitions_set; - /* Empty string means "NULL" will be printed */ - List possible_keys; - //StringBuffer<32> possible_keys_str; + /* Empty means "NULL" will be printed */ + String_list possible_keys; /* Index use: key name and length. @@ -509,8 +515,7 @@ public: */ Explain_index_use hash_next_key; - bool ref_set; /* not set means 'NULL' should be printed */ - StringBuffer<32> ref; + String_list ref_list; bool rows_set; /* not set means 'NULL' should be printed */ ha_rows rows; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f772c53ebb9..213a7eae647 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -23261,23 +23261,14 @@ void explain_append_mrr_info(QUICK_RANGE_SELECT *quick, String *res) /////////////////////////////////////////////////////////////////////////////// -// TODO: join with make_possible_keys_line ? -int append_possible_keys(MEM_ROOT *alloc, List &list, TABLE *table, +int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table, key_map possible_keys) { uint j; for (j=0 ; j < table->s->keys ; j++) { if (possible_keys.is_set(j)) - { - const char *key_name= table->key_info[j].name; - size_t len= strlen(key_name); - char *cp; - if (!(cp = (char*)alloc_root(alloc, len))) - return 1; - memcpy(cp, key_name, len+1); - list.push_back(cp); - } + list.append_str(alloc, table->key_info[j].name); } return 0; } @@ -23312,13 +23303,10 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab TABLE *table=tab->table; TABLE_LIST *table_list= tab->table->pos_in_table_list; - char buff4[512]; my_bool key_read; char table_name_buffer[SAFE_NAME_LEN]; - String tmp4(buff4,sizeof(buff4),cs); KEY *key_info= 0; uint key_len= 0; - tmp4.length(0); quick_type= -1; QUICK_SELECT_I *quick= NULL; @@ -23456,14 +23444,11 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab store_key **ref=tab->ref.key_copy; for (uint kp= 0; kp < tab->ref.key_parts; kp++) { - if (tmp4.length()) - tmp4.append(','); - if ((key_part_map(1) << kp) & tab->ref.const_ref_part_map) - tmp4.append("const"); + eta->ref_list.append_str(thd->mem_root, "const"); else { - tmp4.append((*ref)->name(), strlen((*ref)->name()), cs); + eta->ref_list.append_str(thd->mem_root, (*ref)->name()); ref++; } } @@ -23477,17 +23462,7 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab table->key_info[tab->index].key_length); } - if (key_info) - { - if (key_info && tab_type != JT_NEXT) - { - eta->ref.copy(tmp4); - eta->ref_set= true; - } - else - eta->ref_set= false; - } - else + if (!key_info) { if (table_list && /* SJM bushes don't have table_list */ table_list->schema_table && @@ -23517,7 +23492,6 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab if (key_name_buf.length()) eta->key.set(thd->mem_root, key_name_buf.c_ptr_safe(), -1); } - eta->ref_set= false; } /* "rows" */