Commit d634638c authored by Sergey Petrunya's avatar Sergey Petrunya

[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 ...)
parent 8b7bbcf4
...@@ -165,7 +165,11 @@ set @show_explain_probe_select_id=1; ...@@ -165,7 +165,11 @@ set @show_explain_probe_select_id=1;
set debug_dbug='+d,show_explain_probe_join_exec_end'; 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; select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1;
show explain for $thr2; 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) a (select max(a) from t0 b where b.a+a.a<10)
0 9 0 9
set debug_dbug=@old_debug; set debug_dbug=@old_debug;
...@@ -343,7 +347,11 @@ SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a; ...@@ -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: # FIXED by "conservative assumptions about when QEP is available" fix:
# NOTE: current code will not show "Using join buffer": # NOTE: current code will not show "Using join buffer":
show explain for $thr2; 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 a
1 1
2 2
...@@ -428,7 +436,10 @@ set @show_explain_probe_select_id=1; ...@@ -428,7 +436,10 @@ set @show_explain_probe_select_id=1;
set debug_dbug='+d,show_explain_probe_join_exec_end'; set debug_dbug='+d,show_explain_probe_join_exec_end';
select * from t0 where 1>10; select * from t0 where 1>10;
show explain for $thr2; 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 a
set debug_dbug=@old_debug; set debug_dbug=@old_debug;
# #
...@@ -440,7 +451,10 @@ set @show_explain_probe_select_id=1; ...@@ -440,7 +451,10 @@ set @show_explain_probe_select_id=1;
set debug_dbug='+d,show_explain_probe_join_exec_end'; set debug_dbug='+d,show_explain_probe_join_exec_end';
select * from t0,t3 where t3.a=112233; select * from t0,t3 where t3.a=112233;
show explain for $thr2; 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 a a
set debug_dbug=@old_debug; set debug_dbug=@old_debug;
drop table t3; drop table t3;
...@@ -545,7 +559,12 @@ set @show_explain_probe_select_id=1; ...@@ -545,7 +559,12 @@ set @show_explain_probe_select_id=1;
set debug_dbug='+d,show_explain_probe_join_exec_end'; 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`); SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`);
show explain for $thr2; 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 <subquery2> 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 pk a1
set debug_dbug=@old_debug; set debug_dbug=@old_debug;
DROP TABLE t2; DROP TABLE t2;
...@@ -651,7 +670,7 @@ SELECT a + 1 FROM v1; ...@@ -651,7 +670,7 @@ SELECT a + 1 FROM v1;
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 <derived2> ALL NULL NULL NULL NULL 2 1 PRIMARY <derived2> 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: Warnings:
Note 1003 SELECT a + 1 FROM v1 Note 1003 SELECT a + 1 FROM v1
a + 1 a + 1
...@@ -1061,7 +1080,7 @@ show explain for $thr2; ...@@ -1061,7 +1080,7 @@ 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 alias1 ALL NULL NULL NULL NULL 14 1 PRIMARY alias1 ALL NULL NULL NULL NULL 14
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 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: Warnings:
Note 1003 SELECT max(a+b+c) FROM t1 AS alias1, ( SELECT * FROM t2 ) AS alias 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 WHERE EXISTS ( SELECT * FROM t3 WHERE b = c ) OR a <= 10
......
...@@ -202,7 +202,6 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; ...@@ -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; send 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
--error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
...@@ -349,7 +348,7 @@ connection default; ...@@ -349,7 +348,7 @@ connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
--echo # FIXED by "conservative assumptions about when QEP is available" fix: --echo # FIXED by "conservative assumptions about when QEP is available" fix:
--echo # NOTE: current code will not show "Using join buffer": --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; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
...@@ -428,7 +427,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; ...@@ -428,7 +427,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end';
send select * from t0 where 1>10; send select * from t0 where 1>10;
connection default; connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
--error ER_TARGET_NOT_EXPLAINABLE #--error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
...@@ -444,7 +443,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end'; ...@@ -444,7 +443,7 @@ set debug_dbug='+d,show_explain_probe_join_exec_end';
send select * from t0,t3 where t3.a=112233; send select * from t0,t3 where t3.a=112233;
connection default; connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
--error ER_TARGET_NOT_EXPLAINABLE # --error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
...@@ -540,7 +539,7 @@ send ...@@ -540,7 +539,7 @@ send
SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`); SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`);
connection default; connection default;
--source include/wait_condition.inc --source include/wait_condition.inc
--error ER_TARGET_NOT_EXPLAINABLE # --error ER_TARGET_NOT_EXPLAINABLE
evalp show explain for $thr2; evalp show explain for $thr2;
connection con1; connection con1;
reap; reap;
......
...@@ -217,6 +217,8 @@ public: ...@@ -217,6 +217,8 @@ public:
/* Produce a tabular EXPLAIN output */ /* Produce a tabular EXPLAIN output */
int print_explain(select_result_sink *output, uint8 explain_flags); 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; MEM_ROOT *mem_root;
private: private:
Dynamic_array<QPF_union*> unions; Dynamic_array<QPF_union*> unions;
......
...@@ -3495,6 +3495,18 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) ...@@ -3495,6 +3495,18 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
is_correlated_unit|= sl->is_correlated; is_correlated_unit|= sl->is_correlated;
inner_join->select_options= save_options; inner_join->select_options= save_options;
un->thd->lex->current_select= save_select; 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) if (empty_union_result)
{ {
/* /*
...@@ -4182,7 +4194,7 @@ int LEX::print_explain(select_result_sink *output, uint8 explain_flags, ...@@ -4182,7 +4194,7 @@ int LEX::print_explain(select_result_sink *output, uint8 explain_flags,
bool *printed_anything) //TODO: remove printed_anything bool *printed_anything) //TODO: remove printed_anything
{ {
int res; 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); res= query_plan_footprint->print_explain(output, explain_flags);
*printed_anything= true; *printed_anything= true;
......
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