From d634638c5613683dd0690c1ed40db1bb75877e1c Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 27 Jun 2013 18:52:47 +0400 Subject: [PATCH] [SHOW] EXPLAIN UPDATE/DELETE, code re-structuring - If a subquery is correlated wrt a const table, it will change from being a "DEPENDENT SUBQUERY" into "SUBQUERY", at the end of its parent's JOIN::optimize() call. Handle this, update the subquery's QPF. - Make show_explain.test to work = "Query plan already deleted" does not happen anymore. = Handle special case of queries that don't have top-level selects, like SET x = (SELECT ...) --- mysql-test/r/show_explain.result | 33 +++++++++++++++++++++++++------- mysql-test/t/show_explain.test | 9 ++++----- sql/opt_qpf.h | 4 +++- sql/sql_lex.cc | 14 +++++++++++++- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 2a6f0ca583b..3092fdc41bd 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -165,7 +165,11 @@ set @show_explain_probe_select_id=1; set debug_dbug='+d,show_explain_probe_join_exec_end'; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; show explain for $thr2; -ERROR HY000: Target is not running an EXPLAINable command +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 10 Using where +2 DEPENDENT SUBQUERY b ALL NULL NULL NULL NULL 10 Using where +Warnings: +Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1 a (select max(a) from t0 b where b.a+a.a<10) 0 9 set debug_dbug=@old_debug; @@ -343,7 +347,11 @@ SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; # FIXED by "conservative assumptions about when QEP is available" fix: # NOTE: current code will not show "Using join buffer": show explain for $thr2; -ERROR HY000: Target is not running an EXPLAINable command +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) +Warnings: +Note 1003 SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a a 1 2 @@ -428,7 +436,10 @@ set @show_explain_probe_select_id=1; set debug_dbug='+d,show_explain_probe_join_exec_end'; select * from t0 where 1>10; show explain for $thr2; -ERROR HY000: Target is not running an EXPLAINable command +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select * from t0 where 1>10 a set debug_dbug=@old_debug; # @@ -440,7 +451,10 @@ set @show_explain_probe_select_id=1; set debug_dbug='+d,show_explain_probe_join_exec_end'; select * from t0,t3 where t3.a=112233; show explain for $thr2; -ERROR HY000: Target is not running an EXPLAINable command +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL no matching row in const table +Warnings: +Note 1003 select * from t0,t3 where t3.a=112233 a a set debug_dbug=@old_debug; drop table t3; @@ -545,7 +559,12 @@ set @show_explain_probe_select_id=1; set debug_dbug='+d,show_explain_probe_join_exec_end'; SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`); show explain for $thr2; -ERROR HY000: Target is not running an EXPLAINable command +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY const distinct_key distinct_key 8 const,const 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +2 MATERIALIZED t2 index NULL a1 4 NULL 20 Using index +Warnings: +Note 1003 SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`) pk a1 set debug_dbug=@old_debug; DROP TABLE t2; @@ -651,7 +670,7 @@ SELECT a + 1 FROM v1; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 2 -2 DERIVED NULL NULL NULL NULL NULL NULL NULL Query plan already deleted +2 DERIVED t1 ALL NULL NULL NULL NULL 2 Warnings: Note 1003 SELECT a + 1 FROM v1 a + 1 @@ -1061,7 +1080,7 @@ show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 1 PRIMARY t2 ALL NULL NULL NULL NULL 20 -3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Query plan already deleted +3 SUBQUERY t3 ALL NULL NULL NULL NULL 20 Using where Warnings: Note 1003 SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10 diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index 52c680f57de..8ab1813f5bb 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -202,7 +202,6 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; send select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1; connection default; --source include/wait_condition.inc ---error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; connection con1; reap; @@ -349,7 +348,7 @@ connection default; --source include/wait_condition.inc --echo # FIXED by "conservative assumptions about when QEP is available" fix: --echo # NOTE: current code will not show "Using join buffer": ---error ER_TARGET_NOT_EXPLAINABLE +#--error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; connection con1; reap; @@ -428,7 +427,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; send select * from t0 where 1>10; connection default; --source include/wait_condition.inc ---error ER_TARGET_NOT_EXPLAINABLE +#--error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; connection con1; reap; @@ -444,7 +443,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; send select * from t0,t3 where t3.a=112233; connection default; --source include/wait_condition.inc ---error ER_TARGET_NOT_EXPLAINABLE +# --error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; connection con1; reap; @@ -540,7 +539,7 @@ send SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`); connection default; --source include/wait_condition.inc ---error ER_TARGET_NOT_EXPLAINABLE +# --error ER_TARGET_NOT_EXPLAINABLE evalp show explain for $thr2; connection con1; reap; diff --git a/sql/opt_qpf.h b/sql/opt_qpf.h index 35afcde10df..2af04ab28a7 100644 --- a/sql/opt_qpf.h +++ b/sql/opt_qpf.h @@ -216,7 +216,9 @@ public: /* Produce a tabular EXPLAIN output */ int print_explain(select_result_sink *output, uint8 explain_flags); - + + /* If true, at least part of EXPLAIN can be printed */ + bool have_query_plan() { return upd_del_plan!= NULL || get_node(1) != NULL; } MEM_ROOT *mem_root; private: Dynamic_array unions; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2e4eaf5b721..f5aa84b6f41 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3495,6 +3495,18 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) is_correlated_unit|= sl->is_correlated; inner_join->select_options= save_options; un->thd->lex->current_select= save_select; + /// psergey: + QPF_query *qpf; + if ((qpf= inner_join->thd->lex->query_plan_footprint)) + { + QPF_select *qp_sel; + if ((qp_sel= qpf->get_select(inner_join->select_lex->select_number))) + { + sl->set_explain_type(TRUE); + qp_sel->select_type= sl->type; + } + } + /// if (empty_union_result) { /* @@ -4182,7 +4194,7 @@ int LEX::print_explain(select_result_sink *output, uint8 explain_flags, bool *printed_anything) //TODO: remove printed_anything { int res; - if (query_plan_footprint) + if (query_plan_footprint && query_plan_footprint->have_query_plan()) { res= query_plan_footprint->print_explain(output, explain_flags); *printed_anything= true;