diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 6a142e676fa..874af6e720e 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -14,6 +14,7 @@ show explain for $thr2; ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command show explain for $thr1; ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command +set @show_explain_probe_select_id=1; set debug='d,show_explain_probe_1'; select count(*) from t1 where a < 100000; show explain for $thr2; @@ -21,7 +22,6 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index a a 5 NULL 1000 Using where; Using index count(*) 1000 -set debug='d,show_explain_probe_1'; select max(c) from t1 where a < 10; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra @@ -29,7 +29,6 @@ id select_type table type possible_keys key key_len ref rows Extra max(c) 9 set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on'; -set debug='d,show_explain_probe_1'; explain select max(c) from t1 where a < 10; show explain for $thr2; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index 1ee66e3ca2c..4ed625c5bca 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -1,6 +1,8 @@ # # Tests for SHOW EXPLAIN FOR functionality # +--source include/have_debug.inc + --disable_warnings drop table if exists t0, t1; --enable_warnings @@ -45,6 +47,7 @@ let $wait_condition= select State='show_explain_trap' from information_schema.pr # Test SHOW EXPLAIN for simple queries # connection con1; +set @show_explain_probe_select_id=1; set debug='d,show_explain_probe_1'; send select count(*) from t1 where a < 100000; @@ -55,7 +58,6 @@ connection con1; reap; -set debug='d,show_explain_probe_1'; send select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc @@ -65,7 +67,6 @@ reap; # We can catch EXPLAIN, too. set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_sort_keys=on'; -set debug='d,show_explain_probe_1'; send explain select max(c) from t1 where a < 10; connection default; --source include/wait_condition.inc @@ -73,6 +74,8 @@ evalp show explain for $thr2; connection con1; reap; +# Let's try with a subquery + ## TODO: Test this: multiple SHOW EXPLAIN calls in course of running of one select ## diff --git a/sql/item_func.cc b/sql/item_func.cc index 033537092d8..2bca34f0a76 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3871,7 +3871,7 @@ longlong Item_func_sleep::val_int() #define extra_size sizeof(double) -static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, +user_var_entry *get_variable(HASH *hash, LEX_STRING &name, bool create_if_not_exists) { user_var_entry *entry; diff --git a/sql/sql_class.h b/sql/sql_class.h index 5d55d7182fc..cec37de6a61 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3474,6 +3474,8 @@ class user_var_entry DTCollation collation; }; +user_var_entry *get_variable(HASH *hash, LEX_STRING &name, + bool create_if_not_exists); /* Unique -- class for unique (removing of duplicates). diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a9f07c337fa..3d2f7013a35 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3529,7 +3529,8 @@ void st_select_lex::set_explain_type(bool on_the_fly) if (this == master_unit()->fake_select_lex) type= "UNION RESULT"; - options|= SELECT_DESCRIBE; + if (!on_the_fly) + options|= SELECT_DESCRIBE; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 355b33fa353..1d2c8a10b75 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -262,8 +262,34 @@ void dbug_serve_apcs(THD *thd, int n_calls) } thd_proc_info(thd, save_proc_info); } + + +/* + Usage + + DBUG_EXECUTE_IF("show_explain_probe_2", + if (dbug_user_var_equals_int(thd, "select_id", select_id)) + dbug_serve_apcs(thd, 1); + ); + +*/ + +bool dbug_user_var_equals_int(THD *thd, const char *name, int value) +{ + user_var_entry *var; + LEX_STRING varname= {(char*)name, strlen(name)}; + if ((var= get_variable(&thd->user_vars, varname, FALSE))) + { + bool null_value; + longlong var_value= var->val_int(&null_value); + if (!null_value && var_value == value) + return TRUE; + } + return FALSE; +} #endif + /** This handles SELECT with and without UNION. */ @@ -2067,7 +2093,13 @@ void JOIN::exec_inner() int tmp_error; DBUG_ENTER("JOIN::exec"); - DBUG_EXECUTE_IF("show_explain_probe_1", dbug_serve_apcs(thd, 1);); + DBUG_EXECUTE_IF("show_explain_probe_2", dbug_serve_apcs(thd, 1);); + DBUG_EXECUTE_IF("show_explain_probe_1", + if (dbug_user_var_equals_int(thd, + "show_explain_probe_select_id", + select_lex->select_number)) + dbug_serve_apcs(thd, 1); + ); thd_proc_info(thd, "executing"); error= 0; @@ -20397,8 +20429,8 @@ void JOIN::clear() /** EXPLAIN handling. - Send a description about what how the select will be done to stdout. - + Produce lines explaining execution of *this* select (not including children + selects) @param on_the_fly TRUE <=> we're being executed on-the-fly, so don't make modifications to any select's data structures */