Commit 32868483 authored by Oleg Smirnov's avatar Oleg Smirnov Committed by Sergei Petrunia

MDEV-10000 Add EXPLAIN [FORMAT=JSON] FOR CONNECTION syntax support

EXPLAIN FOR CONNECTION is a MySQL-compatible syntax for SHOW EXPLAIN.
This commit also adds support for FORMAT=JSON to SHOW EXPLAIN,
so the possible options to get JSON-formatted output are:
- SHOW EXPLAIN FORMAT=JSON FOR $con
- EXPLAIN FORMAT=JSON FOR CONNECTION $con
parent 51b28b24
...@@ -9,18 +9,30 @@ insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C; ...@@ -9,18 +9,30 @@ insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
alter table t1 add b int, add c int, add filler char(32); alter table t1 add b int, add c int, add filler char(32);
update t1 set b=a, c=a, filler='fooo'; update t1 set b=a, c=a, filler='fooo';
alter table t1 add key(a), add key(b); alter table t1 add key(a), add key(b);
show explain for;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
explain for connection;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
show explain for 2000000000; show explain for 2000000000;
ERROR HY000: Unknown thread id: 2000000000 ERROR HY000: Unknown thread id: 2000000000
explain for connection 2000000000;
ERROR HY000: Unknown thread id: 2000000000
show explain for (select max(a) from t0); show explain for (select max(a) from t0);
ERROR HY000: You may only use constant expressions in this statement ERROR HY000: You may only use constant expressions in this statement
explain for connection (select max(a) from t0);
ERROR HY000: You may only use constant expressions in this statement
connect con1, localhost, root,,; connect con1, localhost, root,,;
connection con1; connection con1;
SET @old_debug= @@session.debug; SET @old_debug= @@session.debug;
connection default; connection default;
show explain for $thr2; show explain for $thr2;
ERROR HY000: Target is not running an EXPLAINable command ERROR HY000: Target is not running an EXPLAINable command
explain for connection $thr2;
ERROR HY000: Target is not running an EXPLAINable command
show explain for $thr1; show explain for $thr1;
ERROR HY000: Target is not running an EXPLAINable command ERROR HY000: Target is not running an EXPLAINable command
explain for connection $thr1;
ERROR HY000: Target is not running an EXPLAINable command
connection con1; connection con1;
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=1;
SET debug_dbug='+d,show_explain_probe_join_exec_start'; SET debug_dbug='+d,show_explain_probe_join_exec_start';
...@@ -31,6 +43,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -31,6 +43,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 999 Using where; Using index 1 SIMPLE t1 range a a 5 NULL 999 Using where; Using index
Warnings: Warnings:
Note 1003 select count(*) from t1 where a < 100000 Note 1003 select count(*) from t1 where a < 100000
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 999 Using where; Using index
Warnings:
Note 1003 select count(*) from t1 where a < 100000
connection con1; connection con1;
count(*) count(*)
1000 1000
...@@ -44,6 +61,16 @@ Note 1003 select max(c) from t1 where a < 10 ...@@ -44,6 +61,16 @@ Note 1003 select max(c) from t1 where a < 10
connection con1; connection con1;
max(c) max(c)
9 9
select max(c) from t1 where a < 10;
connection default;
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using index condition
Warnings:
Note 1003 select max(c) from t1 where a < 10
connection con1;
max(c)
9
# We can catch EXPLAIN, too. # We can catch EXPLAIN, too.
set @show_expl_tmp= @@optimizer_switch; set @show_expl_tmp= @@optimizer_switch;
set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on'; set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on';
...@@ -57,6 +84,17 @@ Note 1003 explain select max(c) from t1 where a < 10 ...@@ -57,6 +84,17 @@ Note 1003 explain select max(c) from t1 where a < 10
connection con1; connection con1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan 1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan
# Same for EXPLAIN FOR CONNECTION
explain select max(c) from t1 where a < 10;
connection default;
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan
Warnings:
Note 1003 explain select max(c) from t1 where a < 10
connection con1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan
set optimizer_switch= @show_expl_tmp; set optimizer_switch= @show_expl_tmp;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# UNION, first branch # UNION, first branch
...@@ -78,7 +116,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -78,7 +116,7 @@ id select_type table type possible_keys key key_len ref rows Extra
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# UNION, second branch # UNION, second branch
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start'; SET debug_dbug='+d,show_explain_probe_join_exec_start';
explain select a from t0 A union select a+1 from t0 B; explain select a from t0 A union select a+1 from t0 B;
connection default; connection default;
...@@ -144,17 +182,18 @@ SET debug_dbug=@old_debug; ...@@ -144,17 +182,18 @@ SET debug_dbug=@old_debug;
# correlated subquery, explain # correlated subquery, explain
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=1;
SET debug_dbug='+d,show_explain_probe_join_exec_start'; SET debug_dbug='+d,show_explain_probe_join_exec_start';
select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; explain select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1;
connection default; connection default;
show explain for $thr2; show explain for $thr2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY a ALL NULL NULL NULL NULL 10 Using where 1 PRIMARY a ALL NULL NULL NULL NULL 10 Using where
2 DEPENDENT SUBQUERY b ALL NULL NULL NULL NULL 10 Using where 2 DEPENDENT SUBQUERY b ALL NULL NULL NULL NULL 10 Using where
Warnings: Warnings:
Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 Note 1003 explain select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1
connection con1; connection con1;
a (select max(a) from t0 b where b.a+a.a<10) id select_type table type possible_keys key key_len ref rows Extra
0 9 1 PRIMARY a ALL NULL NULL NULL NULL 10 Using where
2 DEPENDENT SUBQUERY b ALL NULL NULL NULL NULL 10 Using where
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# correlated subquery, select, while inside the subquery # correlated subquery, select, while inside the subquery
set @show_explain_probe_select_id=2; set @show_explain_probe_select_id=2;
...@@ -235,6 +274,26 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -235,6 +274,26 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings: Warnings:
Note 1003 update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 Note 1003 update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3
connection con1; connection con1;
#
# EXPLAIN FOR CONNECTION for an UPDATE
#
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
connection default;
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3
connection con1;
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# #
...@@ -261,6 +320,29 @@ connection con1; ...@@ -261,6 +320,29 @@ connection con1;
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# #
# Attempt EXPLAIN FOR CONNECTION for a DELETE
#
create table t2 as select a as a, a as dummy from t0 limit 2;
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
connection default;
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3
connection con1;
drop table t2;
SET debug_dbug=@old_debug;
#
# Multiple SHOW EXPLAIN calls for one select # Multiple SHOW EXPLAIN calls for one select
# #
create table t2 as select a as a, a as dummy from t0 limit 3; create table t2 as select a as a, a as dummy from t0 limit 3;
...@@ -294,6 +376,39 @@ a SUBQ ...@@ -294,6 +376,39 @@ a SUBQ
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
# #
# Multiple EXPLAIN FOR CONNECTION calls for one select
#
create table t2 as select a as a, a as dummy from t0 limit 3;
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2;
connection default;
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2
explain for connection $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
Warnings:
Note 1003 select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2
connection con1;
a SUBQ
0 0
1 0
2 0
drop table t2;
SET debug_dbug=@old_debug;
#
# SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort" # SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort"
# #
explain select * from t0 order by a; explain select * from t0 order by a;
......
...@@ -44,15 +44,34 @@ alter table t1 add b int, add c int, add filler char(32); ...@@ -44,15 +44,34 @@ alter table t1 add b int, add c int, add filler char(32);
update t1 set b=a, c=a, filler='fooo'; update t1 set b=a, c=a, filler='fooo';
alter table t1 add key(a), add key(b); alter table t1 add key(a), add key(b);
#
# Try to call SHOW EXPLAIN with a missing thread ID
#
--error ER_PARSE_ERROR
show explain for;
#
# Also test MySQL-compatible syntax EXPLAIN FOR CONNECTION which was introduced for MDEV-10000
# #
# Try killing a non-existent thread --error ER_PARSE_ERROR
explain for connection;
#
# Try to call SHOW EXPLAIN/EXPLAIN FOR CONNECTION for a non-existent thread
# #
--error ER_NO_SUCH_THREAD --error ER_NO_SUCH_THREAD
show explain for 2000000000; show explain for 2000000000;
--error ER_NO_SUCH_THREAD
explain for connection 2000000000;
--error ER_SET_CONSTANTS_ONLY --error ER_SET_CONSTANTS_ONLY
show explain for (select max(a) from t0); show explain for (select max(a) from t0);
--error ER_SET_CONSTANTS_ONLY
explain for connection (select max(a) from t0);
# #
# Setup two threads and their ids # Setup two threads and their ids
# #
...@@ -67,14 +86,20 @@ connection default; ...@@ -67,14 +86,20 @@ connection default;
--error ER_TARGET_NOT_EXPLAINABLE --error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr2; evalp show explain for $thr2;
--error ER_TARGET_NOT_EXPLAINABLE
evalp explain for connection $thr2;
# SHOW EXPLAIN FOR <ourselves> # SHOW EXPLAIN FOR <ourselves>
--error ER_TARGET_NOT_EXPLAINABLE --error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr1; evalp show explain for $thr1;
--error ER_TARGET_NOT_EXPLAINABLE
evalp explain for connection $thr1;
let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr2; let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr2;
# #
# Test SHOW EXPLAIN for simple queries # Test SHOW EXPLAIN/EXPLAIN FOR CONNECTION for simple queries
# #
connection con1; connection con1;
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=1;
...@@ -84,6 +109,7 @@ send select count(*) from t1 where a < 100000; ...@@ -84,6 +109,7 @@ send select count(*) from t1 where a < 100000;
connection default; connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
evalp show explain for $thr2; evalp show explain for $thr2;
evalp explain for connection $thr2;
connection con1; connection con1;
reap; reap;
...@@ -96,6 +122,14 @@ connection con1; ...@@ -96,6 +122,14 @@ connection con1;
reap; reap;
send select max(c) from t1 where a < 10;
connection default;
--source include/wait_condition.inc
evalp explain for connection $thr2;
connection con1;
reap;
--echo # We can catch EXPLAIN, too. --echo # We can catch EXPLAIN, too.
set @show_expl_tmp= @@optimizer_switch; set @show_expl_tmp= @@optimizer_switch;
set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on'; set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on';
...@@ -105,6 +139,14 @@ connection default; ...@@ -105,6 +139,14 @@ connection default;
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
--echo # Same for EXPLAIN FOR CONNECTION
send explain select max(c) from t1 where a < 10;
connection default;
--source include/wait_condition.inc
evalp explain for connection $thr2;
connection con1;
reap;
set optimizer_switch= @show_expl_tmp; set optimizer_switch= @show_expl_tmp;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
...@@ -121,7 +163,7 @@ SET debug_dbug=@old_debug; ...@@ -121,7 +163,7 @@ SET debug_dbug=@old_debug;
--echo # UNION, second branch --echo # UNION, second branch
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start'; SET debug_dbug='+d,show_explain_probe_join_exec_start';
send explain select a from t0 A union select a+1 from t0 B; send explain select a from t0 A union select a+1 from t0 B;
connection default; connection default;
...@@ -169,7 +211,7 @@ SET debug_dbug=@old_debug; ...@@ -169,7 +211,7 @@ SET debug_dbug=@old_debug;
--echo # correlated subquery, explain --echo # correlated subquery, explain
set @show_explain_probe_select_id=1; set @show_explain_probe_select_id=1;
SET debug_dbug='+d,show_explain_probe_join_exec_start'; SET debug_dbug='+d,show_explain_probe_join_exec_start';
send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; send explain select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1;
connection default; connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
evalp show explain for $thr2; evalp show explain for $thr2;
...@@ -249,9 +291,25 @@ evalp show explain for $thr2; ...@@ -249,9 +291,25 @@ evalp show explain for $thr2;
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
--echo #
--echo # EXPLAIN FOR CONNECTION for an UPDATE
--echo #
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
connection default;
--source include/wait_condition.inc
evalp explain for connection $thr2;
--source include/wait_condition.inc
evalp explain for connection $thr2;
connection con1;
reap;
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
--echo # --echo #
--echo # Attempt SHOW EXPLAIN for a DELETE (UPD: now works) --echo # Attempt SHOW EXPLAIN for a DELETE (UPD: now works)
--echo # --echo #
...@@ -271,6 +329,23 @@ reap; ...@@ -271,6 +329,23 @@ reap;
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
--echo #
--echo # Attempt EXPLAIN FOR CONNECTION for a DELETE
--echo #
create table t2 as select a as a, a as dummy from t0 limit 2;
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
connection default;
--source include/wait_condition.inc
evalp explain for connection $thr2;
--source include/wait_condition.inc
evalp explain for connection $thr2;
connection con1;
reap;
drop table t2;
SET debug_dbug=@old_debug;
--echo # --echo #
--echo # Multiple SHOW EXPLAIN calls for one select --echo # Multiple SHOW EXPLAIN calls for one select
--echo # --echo #
...@@ -290,6 +365,26 @@ reap; ...@@ -290,6 +365,26 @@ reap;
drop table t2; drop table t2;
SET debug_dbug=@old_debug; SET debug_dbug=@old_debug;
--echo #
--echo # Multiple EXPLAIN FOR CONNECTION calls for one select
--echo #
create table t2 as select a as a, a as dummy from t0 limit 3;
set @show_explain_probe_select_id=2;
SET debug_dbug='+d,show_explain_probe_join_exec_start';
send select t2.a, ((select max(a) from t0 where t2.a + t0.a <3) >3) as SUBQ from t2;
connection default;
--source include/wait_condition.inc
evalp explain for connection $thr2;
--source include/wait_condition.inc
evalp explain for connection $thr2;
--source include/wait_condition.inc
evalp explain for connection $thr2;
connection con1;
reap;
drop table t2;
SET debug_dbug=@old_debug;
--echo # --echo #
--echo # SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort" --echo # SHOW EXPLAIN for SELECT ... ORDER BY with "Using filesort"
--echo # --echo #
......
This diff is collapsed.
This diff is collapsed.
...@@ -1023,7 +1023,8 @@ enum enum_schema_tables ...@@ -1023,7 +1023,8 @@ enum enum_schema_tables
SCH_ENABLED_ROLES, SCH_ENABLED_ROLES,
SCH_ENGINES, SCH_ENGINES,
SCH_EVENTS, SCH_EVENTS,
SCH_EXPLAIN, SCH_EXPLAIN_TABULAR,
SCH_EXPLAIN_JSON,
SCH_FILES, SCH_FILES,
SCH_GLOBAL_STATUS, SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES, SCH_GLOBAL_VARIABLES,
......
...@@ -8804,6 +8804,8 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, ...@@ -8804,6 +8804,8 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
continue; continue;
value=v++; value=v++;
/* Ensure the end of the list of values is not reached */
DBUG_ASSERT(value);
bool vers_sys_field= table->versioned() && field->vers_sys_field(); bool vers_sys_field= table->versioned() && field->vers_sys_field();
......
...@@ -215,7 +215,7 @@ int Explain_query::print_explain(select_result_sink *output, ...@@ -215,7 +215,7 @@ int Explain_query::print_explain(select_result_sink *output,
} }
void Explain_query::print_explain_json(select_result_sink *output, int Explain_query::print_explain_json(select_result_sink *output,
bool is_analyze) bool is_analyze)
{ {
Json_writer writer; Json_writer writer;
...@@ -230,7 +230,7 @@ void Explain_query::print_explain_json(select_result_sink *output, ...@@ -230,7 +230,7 @@ void Explain_query::print_explain_json(select_result_sink *output,
/* Start printing from node with id=1 */ /* Start printing from node with id=1 */
Explain_node *node= get_node(1); Explain_node *node= get_node(1);
if (!node) if (!node)
return; /* No query plan */ return 1; /* No query plan */
node->print_explain_json(this, &writer, is_analyze); node->print_explain_json(this, &writer, is_analyze);
} }
...@@ -243,6 +243,7 @@ void Explain_query::print_explain_json(select_result_sink *output, ...@@ -243,6 +243,7 @@ void Explain_query::print_explain_json(select_result_sink *output,
Item_string(thd, buf->ptr(), buf->length(), cs), Item_string(thd, buf->ptr(), buf->length(), cs),
thd->mem_root); thd->mem_root);
output->send_data(item_list); output->send_data(item_list);
return 0;
} }
......
...@@ -478,7 +478,7 @@ class Explain_query : public Sql_alloc ...@@ -478,7 +478,7 @@ class Explain_query : public Sql_alloc
/* Return tabular EXPLAIN output as a text string */ /* Return tabular EXPLAIN output as a text string */
bool print_explain_str(THD *thd, String *out_str, bool is_analyze); bool print_explain_str(THD *thd, String *out_str, bool is_analyze);
void print_explain_json(select_result_sink *output, bool is_analyze); int print_explain_json(select_result_sink *output, bool is_analyze);
/* If true, at least part of EXPLAIN can be printed */ /* If true, at least part of EXPLAIN can be printed */
bool have_query_plan() { return insert_plan || upd_del_plan|| get_node(1) != NULL; } bool have_query_plan() { return insert_plan || upd_del_plan|| get_node(1) != NULL; }
......
...@@ -5820,12 +5820,16 @@ bool st_select_lex::is_merged_child_of(st_select_lex *ancestor) ...@@ -5820,12 +5820,16 @@ bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
*/ */
int LEX::print_explain(select_result_sink *output, uint8 explain_flags, int LEX::print_explain(select_result_sink *output, uint8 explain_flags,
bool is_analyze, bool *printed_anything) bool is_analyze, bool is_json_format,
bool *printed_anything)
{ {
int res; int res;
if (explain && explain->have_query_plan()) if (explain && explain->have_query_plan())
{ {
res= explain->print_explain(output, explain_flags, is_analyze); if (is_json_format)
res= explain->print_explain_json(output, is_analyze);
else
res= explain->print_explain(output, explain_flags, is_analyze);
*printed_anything= true; *printed_anything= true;
} }
else else
......
...@@ -3795,8 +3795,14 @@ struct LEX: public Query_tables_list ...@@ -3795,8 +3795,14 @@ struct LEX: public Query_tables_list
bool save_prep_leaf_tables(); bool save_prep_leaf_tables();
int print_explain(select_result_sink *output, uint8 explain_flags, int print_explain(select_result_sink *output, uint8 explain_flags,
<<<<<<< HEAD
bool is_analyze, bool *printed_anything); bool is_analyze, bool *printed_anything);
bool restore_set_statement_var(); bool restore_set_statement_var();
=======
bool is_analyze, bool is_json_format,
bool *printed_anything);
void restore_set_statement_var();
>>>>>>> 54281b6e74e... MDEV-10000 Add EXPLAIN [FORMAT=JSON] FOR CONNECTION syntax support
void init_last_field(Column_definition *field, const LEX_CSTRING *name); void init_last_field(Column_definition *field, const LEX_CSTRING *name);
bool last_field_generated_always_as_row_start_or_end(Lex_ident *p, bool last_field_generated_always_as_row_start_or_end(Lex_ident *p,
......
...@@ -3000,7 +3000,8 @@ void Show_explain_request::call_in_target_thread() ...@@ -3000,7 +3000,8 @@ void Show_explain_request::call_in_target_thread()
DBUG_ASSERT(current_thd == target_thd); DBUG_ASSERT(current_thd == target_thd);
set_current_thd(request_thd); set_current_thd(request_thd);
if (target_thd->lex->print_explain(explain_buf, 0 /* explain flags*/, if (target_thd->lex->print_explain(explain_buf, 0 /* explain flags*/,
false /*TODO: analyze? */, &printed_anything)) false /*TODO: analyze? */,
is_json_format, &printed_anything))
{ {
failed_to_produce= TRUE; failed_to_produce= TRUE;
} }
...@@ -3121,7 +3122,8 @@ void select_result_text_buffer::save_to(String *res) ...@@ -3121,7 +3122,8 @@ void select_result_text_buffer::save_to(String *res)
Store the SHOW EXPLAIN output in the temporary table. Store the SHOW EXPLAIN output in the temporary table.
*/ */
int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond,
bool json_format)
{ {
const char *calling_user; const char *calling_user;
THD *tmp; THD *tmp;
...@@ -3166,6 +3168,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) ...@@ -3166,6 +3168,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
bool timed_out; bool timed_out;
int timeout_sec= 30; int timeout_sec= 30;
Show_explain_request explain_req; Show_explain_request explain_req;
explain_req.is_json_format= json_format;
select_result_explain_buffer *explain_buf; select_result_explain_buffer *explain_buf;
explain_buf= new select_result_explain_buffer(thd, table->table); explain_buf= new select_result_explain_buffer(thd, table->table);
...@@ -3228,6 +3231,18 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond) ...@@ -3228,6 +3231,18 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
} }
int fill_show_explain_tabular(THD *thd, TABLE_LIST *table, COND *cond)
{
return fill_show_explain(thd, table, cond, false /*json_format*/);
}
int fill_show_explain_json(THD *thd, TABLE_LIST *table, COND *cond)
{
return fill_show_explain(thd, table, cond, true /*json_format*/);
}
struct processlist_callback_arg struct processlist_callback_arg
{ {
processlist_callback_arg(THD *thd_arg, TABLE *table_arg): processlist_callback_arg(THD *thd_arg, TABLE *table_arg):
...@@ -9622,7 +9637,7 @@ ST_FIELD_INFO keycache_fields_info[]= ...@@ -9622,7 +9637,7 @@ ST_FIELD_INFO keycache_fields_info[]=
}; };
ST_FIELD_INFO show_explain_fields_info[]= ST_FIELD_INFO show_explain_tabular_fields_info[]=
{ {
Column("id", SLonglong(3), NULLABLE, "id"), Column("id", SLonglong(3), NULLABLE, "id"),
Column("select_type", Varchar(19), NOT_NULL, "select_type"), Column("select_type", Varchar(19), NOT_NULL, "select_type"),
...@@ -9638,6 +9653,13 @@ ST_FIELD_INFO show_explain_fields_info[]= ...@@ -9638,6 +9653,13 @@ ST_FIELD_INFO show_explain_fields_info[]=
}; };
ST_FIELD_INFO show_explain_json_fields_info[]=
{
Column("EXPLAIN", Longtext(MAX_FIELD_VARCHARLENGTH), NOT_NULL, "EXPLAIN"),
CEnd()
};
ST_FIELD_INFO check_constraints_fields_info[]= ST_FIELD_INFO check_constraints_fields_info[]=
{ {
Column("CONSTRAINT_CATALOG", Catalog(), NOT_NULL, OPEN_FULL_TABLE), Column("CONSTRAINT_CATALOG", Catalog(), NOT_NULL, OPEN_FULL_TABLE),
...@@ -9698,8 +9720,10 @@ ST_SCHEMA_TABLE schema_tables[]= ...@@ -9698,8 +9720,10 @@ ST_SCHEMA_TABLE schema_tables[]=
{"EVENTS", Show::events_fields_info, 0, {"EVENTS", Show::events_fields_info, 0,
0, make_old_format, 0, -1, -1, 0, 0}, 0, make_old_format, 0, -1, -1, 0, 0},
#endif #endif
{"EXPLAIN", Show::show_explain_fields_info, 0, fill_show_explain, {"EXPLAIN", Show::show_explain_tabular_fields_info, 0, fill_show_explain_tabular,
make_old_format, 0, -1, -1, TRUE /*hidden*/ , 0}, make_old_format, 0, -1, -1, TRUE /*hidden*/ , 0},
{"EXPLAIN_JSON", Show::show_explain_json_fields_info, 0, fill_show_explain_json,
make_old_format, 0, -1, -1, TRUE /*hidden*/, 0},
{"FILES", Show::files_fields_info, 0, {"FILES", Show::files_fields_info, 0,
hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, hton_fill_schema_table, 0, 0, -1, -1, 0, 0},
{"GLOBAL_STATUS", Show::variables_fields_info, 0, {"GLOBAL_STATUS", Show::variables_fields_info, 0,
......
...@@ -164,6 +164,12 @@ class Show_explain_request : public Apc_target::Apc_call ...@@ -164,6 +164,12 @@ class Show_explain_request : public Apc_target::Apc_call
THD *target_thd; /* thd that we're running SHOW EXPLAIN for */ THD *target_thd; /* thd that we're running SHOW EXPLAIN for */
THD *request_thd; /* thd that run SHOW EXPLAIN command */ THD *request_thd; /* thd that run SHOW EXPLAIN command */
/*
Set to TRUE if you need the result in JSON format,
FALSE - in traditional tabular
*/
bool is_json_format= false;
/* If true, there was some error when producing EXPLAIN output. */ /* If true, there was some error when producing EXPLAIN output. */
bool failed_to_produce; bool failed_to_produce;
......
...@@ -1692,6 +1692,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1692,6 +1692,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
normal_key_options normal_key_opts all_key_opt normal_key_options normal_key_opts all_key_opt
spatial_key_options fulltext_key_options normal_key_opt spatial_key_options fulltext_key_options normal_key_opt
fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
explain_for_connection
keep_gcc_happy keep_gcc_happy
key_using_alg key_using_alg
part_column_list part_column_list
...@@ -1942,6 +1943,7 @@ verb_clause: ...@@ -1942,6 +1943,7 @@ verb_clause:
| do | do
| drop | drop
| execute | execute
| explain_for_connection
| flush | flush
| get_diagnostics | get_diagnostics
| grant | grant
...@@ -13934,12 +13936,17 @@ show_param: ...@@ -13934,12 +13936,17 @@ show_param:
Lex->spname= $3; Lex->spname= $3;
Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT; Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
} }
| describe_command FOR_SYM expr | describe_command opt_format_json FOR_SYM expr
/*
The alternaltive syntax for this command is MySQL-compatible
EXPLAIN FOR CONNECTION
*/
{ {
Lex->sql_command= SQLCOM_SHOW_EXPLAIN; Lex->sql_command= SQLCOM_SHOW_EXPLAIN;
if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN))) if (unlikely(prepare_schema_table(thd, Lex, 0,
Lex->explain_json ? SCH_EXPLAIN_JSON : SCH_EXPLAIN_TABULAR)))
MYSQL_YYABORT; MYSQL_YYABORT;
add_value_to_list(thd, $3); add_value_to_list(thd, $4);
} }
| IDENT_sys remember_tok_start wild_and_where | IDENT_sys remember_tok_start wild_and_where
{ {
...@@ -14111,6 +14118,21 @@ opt_describe_column: ...@@ -14111,6 +14118,21 @@ opt_describe_column:
} }
; ;
explain_for_connection:
/*
EXPLAIN FOR CONNECTION is an alternative syntax for
SHOW EXPLAIN FOR command. It was introduced for compatibility
with MySQL which implements EXPLAIN FOR CONNECTION command
*/
describe_command opt_format_json FOR_SYM CONNECTION_SYM expr
{
Lex->sql_command= SQLCOM_SHOW_EXPLAIN;
if (unlikely(prepare_schema_table(thd, Lex, 0,
Lex->explain_json ? SCH_EXPLAIN_JSON : SCH_EXPLAIN_TABULAR)))
MYSQL_YYABORT;
add_value_to_list(thd, $5);
}
;
/* flush things */ /* flush things */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment