diff options
-rw-r--r-- | mysql-test/r/explain_json.result | 41 | ||||
-rw-r--r-- | mysql-test/t/explain_json.test | 27 | ||||
-rw-r--r-- | sql/item.cc | 8 | ||||
-rw-r--r-- | sql/my_json_writer.cc | 2 | ||||
-rw-r--r-- | sql/my_json_writer.h | 8 | ||||
-rw-r--r-- | sql/mysqld.h | 6 | ||||
-rw-r--r-- | sql/sql_explain.cc | 12 | ||||
-rw-r--r-- | sql/sql_parse.cc | 16 |
8 files changed, 100 insertions, 20 deletions
diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result new file mode 100644 index 00000000000..de902a7c31a --- /dev/null +++ b/mysql-test/r/explain_json.result @@ -0,0 +1,41 @@ +drop table if exists t0,t1; +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +explain format=json select * from t0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t0", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + } + } +} +explain format=json select * from t0 where 1>2; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "message": "Impossible WHERE" + } + } +} +explain format=json select * from t0 where a<3; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t0", + "access_type": "ALL", + "rows": 10, + "filtered": 100, + "attached_condition": "(t0.a < 3)" + } + } +} +drop table t0; diff --git a/mysql-test/t/explain_json.test b/mysql-test/t/explain_json.test new file mode 100644 index 00000000000..e9306101f81 --- /dev/null +++ b/mysql-test/t/explain_json.test @@ -0,0 +1,27 @@ +# +# EXPLAIN FORMAT=JSON tests. These are tests developed for MariaDB. +# +--disable_warnings +drop table if exists t0,t1; +--enable_warnings + +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +explain format=json select * from t0; + +explain format=json select * from t0 where 1>2; + +explain format=json select * from t0 where a<3; + +#create table t1 (a int, b int, filler char(32), key(a)); +#insert into t1 +#select +# A.a + B.a* 10 + C.a * 100, +# A.a + B.a* 10 + C.a * 100, +# 'filler' +#from t0 A, t0 B, t0 C; +# +#explain format=json select * from t0,t1 where t1.a=t0.a; + +drop table t0; diff --git a/sql/item.cc b/sql/item.cc index 21baf779781..8b1ceac7420 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2583,7 +2583,13 @@ void Item_ident::print(String *str, enum_query_type query_type) } if (db_name && db_name[0] && !alias_name_used) { - if (!(cached_table && cached_table->belong_to_view && + /* + When printing EXPLAIN, don't print database name when it's the same as + current database. + */ + bool skip_db= (query_type & QT_EXPLAIN) && !strcmp(thd->db, db_name); + if (!skip_db && + !(cached_table && cached_table->belong_to_view && cached_table->belong_to_view->compact_view_format)) { append_identifier(thd, str, d_name, (uint)strlen(d_name)); diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 206597da59e..d07b13a3d65 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -100,7 +100,7 @@ void Json_writer::add_double(double val) start_element(); char buf[64]; - my_snprintf(buf, sizeof(buf), "%lf", val); + my_snprintf(buf, sizeof(buf), "%lg", val); output.append(buf); element_started= false; } diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index 403d7e0688c..101df7c3215 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -1,5 +1,11 @@ /* Todo: SkySQL copyrights */ + +/* + A class to write well-formed JSON documents. The documents are also formatted + for human readability. +*/ + class Json_writer { public: @@ -25,7 +31,7 @@ public: first_child(true) {} private: - // stack of (name, bool is_object_or_array) elements. + // TODO: a stack of (name, bool is_object_or_array) elements. int indent_level; enum { INDENT_SIZE = 2 }; diff --git a/sql/mysqld.h b/sql/mysqld.h index a1656a49047..5a7419bf32b 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -611,9 +611,13 @@ enum enum_query_type /// Without character set introducers. QT_WITHOUT_INTRODUCERS= (1 << 1), /// view internal representation (like QT_ORDINARY except ORDER BY clause) - QT_VIEW_INTERNAL= (1 << 2) + QT_VIEW_INTERNAL= (1 << 2), + /// This value means focus on readability, not on ability to parse back, etc. + QT_EXPLAIN= (1 << 4) }; + + /* query_id */ typedef int64 query_id_t; extern query_id_t global_query_id; diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 496e113162a..846868197ac 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -774,10 +774,17 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai static void write_item(Json_writer *writer, Item *item) { + THD *thd= current_thd; char item_buf[256]; String str(item_buf, sizeof(item_buf), &my_charset_bin); str.length(0); - item->print(&str ,QT_ORDINARY); + + ulonglong save_option_bits= thd->variables.option_bits; + thd->variables.option_bits &= ~OPTION_QUOTE_SHOW_CREATE; + + item->print(&str, QT_EXPLAIN); + + thd->variables.option_bits= save_option_bits; writer->add_str(str.c_ptr_safe()); } @@ -848,7 +855,8 @@ void Explain_table_access::print_explain_json(Json_writer *writer, writer->add_member("key").add_str(key_str); /* `used_key_parts` */ - writer->add_member("used_key_parts").add_str("TODO"); + if (key_str.length()) + writer->add_member("used_key_parts").add_str("TODO"); StringBuffer<64> key_len_str; fill_key_len_str(&key_len_str); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ab2ef71d22b..ed2f76a223e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5269,21 +5269,9 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) top-level LIMIT */ result->reset_offset_limit(); - if (thd->lex->explain_json) + if (lex->explain_json) { - /* - Json_writer writer; - writer.start_object(); - thd->lex->explain->print_explain_json(&writer, thd->lex->analyze_stmt); - writer.end_object(); - - const 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)); - result->send_data(item_list); - */ - thd->lex->explain->print_explain_json(result, thd->lex->analyze_stmt); + lex->explain->print_explain_json(result, lex->analyze_stmt); } else { |