summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/explain_json.result41
-rw-r--r--mysql-test/t/explain_json.test27
-rw-r--r--sql/item.cc8
-rw-r--r--sql/my_json_writer.cc2
-rw-r--r--sql/my_json_writer.h8
-rw-r--r--sql/mysqld.h6
-rw-r--r--sql/sql_explain.cc12
-rw-r--r--sql/sql_parse.cc16
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
{