MDEV-324: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN for a query with TEMPTABLE view loses 'DERIVED' line
- Make SHOW EXPLAIN code take into account that st_select_lex object without joins can be a full-featured SELECTs which were already executed and cleaned up.
This commit is contained in:
parent
2c1e737c6c
commit
5eecea8caf
@ -153,10 +153,7 @@ 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;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 select a, (select max(a) from t0 b where b.a+a.a<10) from t0 a where a<1
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
a (select max(a) from t0 b where b.a+a.a<10)
|
||||
0 9
|
||||
# Try to do SHOW EXPLAIN for a query that runs a SET command:
|
||||
@ -308,12 +305,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
|
||||
set debug_dbug='d,show_explain_in_find_all_keys';
|
||||
SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a;
|
||||
# NOTE: current code will not show "Using join buffer":
|
||||
# FIXED by "conservative assumptions about when QEP is available" fix:
|
||||
# NOTE: current code will not show "Using join buffer":
|
||||
show explain for $thr2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
a
|
||||
1
|
||||
2
|
||||
@ -366,10 +361,7 @@ set @show_explain_probe_select_id=2;
|
||||
set debug_dbug='d,show_explain_probe_join_exec_end';
|
||||
SELECT * FROM v1, t2;
|
||||
show explain for $thr2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Not yet optimized
|
||||
Warnings:
|
||||
Note 1003 SELECT * FROM v1, t2
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
a b
|
||||
8 4
|
||||
8 5
|
||||
@ -401,10 +393,7 @@ 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;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 select * from t0 where 1>10
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
a
|
||||
set debug_dbug='';
|
||||
#
|
||||
@ -416,10 +405,7 @@ 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;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 select * from t0,t3 where t3.a=112233
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
a a
|
||||
set debug_dbug='';
|
||||
drop table t3;
|
||||
@ -524,10 +510,7 @@ 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;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 SELECT * FROM t2 WHERE (5, 78) IN (SELECT `a1`, MAX(`a1`) FROM t2 GROUP BY `a1`)
|
||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||
pk a1
|
||||
set debug_dbug='';
|
||||
DROP TABLE t2;
|
||||
@ -616,4 +599,30 @@ t1 1 b 1 b A NULL NULL NULL YES BTREE
|
||||
t1 1 c 1 c A NULL NULL NULL YES BTREE
|
||||
set debug_dbug='';
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-324: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN for a query with TEMPTABLE view
|
||||
# loses 'DERIVED' line on the way without saying that the plan was already deleted
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
EXPLAIN SELECT a + 1 FROM v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2
|
||||
set debug_dbug='d,show_explain_probe_join_tab_preread';
|
||||
set @show_explain_probe_select_id=1;
|
||||
SELECT a + 1 FROM v1;
|
||||
show explain for $thr2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL Query plan already deleted
|
||||
Warnings:
|
||||
Note 1003 SELECT a + 1 FROM v1
|
||||
a + 1
|
||||
2
|
||||
3
|
||||
set debug_dbug='';
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
drop table t0;
|
||||
|
@ -191,6 +191,7 @@ 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_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -325,7 +326,9 @@ send SELECT alias.a FROM t2, ( SELECT * FROM t2 ) AS alias GROUP BY alias.a;
|
||||
|
||||
connection default;
|
||||
--source include/wait_condition.inc
|
||||
--echo # NOTE: current code will not show "Using join buffer":
|
||||
--echo # FIXED by "conservative assumptions about when QEP is available" fix:
|
||||
--echo # NOTE: current code will not show "Using join buffer":
|
||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -374,6 +377,7 @@ send SELECT * FROM v1, t2;
|
||||
|
||||
connection default;
|
||||
--source include/wait_condition.inc
|
||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -403,6 +407,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_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -418,6 +423,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_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -513,6 +519,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_ERROR_WHEN_EXECUTING_COMMAND
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
@ -601,6 +608,32 @@ set debug_dbug='';
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-324: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN for a query with TEMPTABLE view
|
||||
--echo # loses 'DERIVED' line on the way without saying that the plan was already deleted
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
|
||||
EXPLAIN SELECT a + 1 FROM v1;
|
||||
|
||||
set debug_dbug='d,show_explain_probe_join_tab_preread';
|
||||
set @show_explain_probe_select_id=1;
|
||||
|
||||
send
|
||||
SELECT a + 1 FROM v1;
|
||||
connection default;
|
||||
--source include/wait_condition.inc
|
||||
evalp show explain for $thr2;
|
||||
connection con1;
|
||||
reap;
|
||||
set debug_dbug='';
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
|
||||
## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a
|
||||
## thread and served together.
|
||||
|
@ -2356,13 +2356,14 @@ int select_result_explain_buffer::send_data(List<Item> &items)
|
||||
}
|
||||
|
||||
|
||||
/* Write all strings out to the output, and free them. */
|
||||
|
||||
void select_result_explain_buffer::flush_data()
|
||||
{
|
||||
List_iterator<String> it(data_rows);
|
||||
String *str;
|
||||
while ((str= it++))
|
||||
{
|
||||
/* TODO: write out the lines. */
|
||||
protocol->set_packet(str->ptr(), str->length());
|
||||
protocol->write();
|
||||
delete str;
|
||||
@ -2370,6 +2371,20 @@ void select_result_explain_buffer::flush_data()
|
||||
data_rows.empty();
|
||||
}
|
||||
|
||||
|
||||
/* Just free all of the accumulated strings */
|
||||
|
||||
void select_result_explain_buffer::discard_data()
|
||||
{
|
||||
List_iterator<String> it(data_rows);
|
||||
String *str;
|
||||
while ((str= it++))
|
||||
{
|
||||
delete str;
|
||||
}
|
||||
data_rows.empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -3288,6 +3303,7 @@ void Show_explain_request::get_explain_data(void *arg)
|
||||
// Actually, change the ARENA, because we're going to allocate items!
|
||||
Query_arena backup_arena;
|
||||
THD *target_thd= req->target_thd;
|
||||
bool printed_anything= FALSE;
|
||||
|
||||
target_thd->set_n_backup_active_arena((Query_arena*)req->request_thd,
|
||||
&backup_arena);
|
||||
@ -3296,7 +3312,11 @@ void Show_explain_request::get_explain_data(void *arg)
|
||||
target_thd->query_length(),
|
||||
&my_charset_bin);
|
||||
|
||||
if (target_thd->lex->unit.print_explain(req->explain_buf, 0 /* explain flags */))
|
||||
if (target_thd->lex->unit.print_explain(req->explain_buf, 0 /* explain flags*/,
|
||||
&printed_anything))
|
||||
req->failed_to_produce= TRUE;
|
||||
|
||||
if (!printed_anything)
|
||||
req->failed_to_produce= TRUE;
|
||||
|
||||
target_thd->restore_active_arena((Query_arena*)req->request_thd,
|
||||
|
@ -3328,6 +3328,8 @@ public:
|
||||
/* this will be called in the parent thread: */
|
||||
void flush_data();
|
||||
|
||||
void discard_data();
|
||||
|
||||
List<String> data_rows;
|
||||
};
|
||||
|
||||
|
@ -4074,7 +4074,8 @@ int print_explain_message_line(select_result_sink *result,
|
||||
|
||||
|
||||
int st_select_lex::print_explain(select_result_sink *output,
|
||||
uint8 explain_flags)
|
||||
uint8 explain_flags,
|
||||
bool *printed_anything)
|
||||
{
|
||||
int res;
|
||||
if (join && join->have_query_plan == JOIN::QEP_AVAILABLE)
|
||||
@ -4083,6 +4084,7 @@ int st_select_lex::print_explain(select_result_sink *output,
|
||||
There is a number of reasons join can be marked as degenerate, so all
|
||||
three conditions below can happen simultaneously, or individually:
|
||||
*/
|
||||
*printed_anything= TRUE;
|
||||
if (!join->table_count || !join->tables_list || join->zero_result_cause)
|
||||
{
|
||||
/* It's a degenerate join */
|
||||
@ -4112,7 +4114,8 @@ int st_select_lex::print_explain(select_result_sink *output,
|
||||
*/
|
||||
if (!(unit->item && unit->item->eliminated))
|
||||
{
|
||||
unit->print_explain(output, explain_flags);
|
||||
if ((res= unit->print_explain(output, explain_flags, printed_anything)))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4120,7 +4123,9 @@ int st_select_lex::print_explain(select_result_sink *output,
|
||||
{
|
||||
const char *msg;
|
||||
if (!join)
|
||||
DBUG_ASSERT(0); // psergey: TODO: can this happen or not?
|
||||
DBUG_ASSERT(0); /* Seems not to be possible */
|
||||
|
||||
/* Not printing anything useful, don't touch *printed_anything here */
|
||||
if (join->have_query_plan == JOIN::QEP_NOT_PRESENT_YET)
|
||||
msg= "Not yet optimized";
|
||||
else
|
||||
@ -4132,12 +4137,12 @@ int st_select_lex::print_explain(select_result_sink *output,
|
||||
0, msg);
|
||||
}
|
||||
err:
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int st_select_lex_unit::print_explain(select_result_sink *output,
|
||||
uint8 explain_flags)
|
||||
uint8 explain_flags, bool *printed_anything)
|
||||
{
|
||||
int res= 0;
|
||||
SELECT_LEX *first= first_select();
|
||||
@ -4148,12 +4153,15 @@ int st_select_lex_unit::print_explain(select_result_sink *output,
|
||||
If there is only one child, 'first', and it has join==NULL, emit "not in
|
||||
EXPLAIN state" error.
|
||||
*/
|
||||
return 1;
|
||||
const char *msg="Query plan already deleted";
|
||||
res= print_explain_message_line(output, first, TRUE /* on_the_fly */,
|
||||
0, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
|
||||
{
|
||||
if ((res= sl->print_explain(output, explain_flags)))
|
||||
if ((res= sl->print_explain(output, explain_flags, printed_anything)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,8 @@ public:
|
||||
friend int subselect_union_engine::exec();
|
||||
|
||||
List<Item> *get_unit_column_types();
|
||||
int print_explain(select_result_sink *output, uint8 explain_flags);
|
||||
int print_explain(select_result_sink *output, uint8 explain_flags,
|
||||
bool *printed_anything);
|
||||
};
|
||||
|
||||
typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
||||
@ -1039,7 +1040,8 @@ public:
|
||||
bool save_prep_leaf_tables(THD *thd);
|
||||
|
||||
bool is_merged_child_of(st_select_lex *ancestor);
|
||||
int print_explain(select_result_sink *output, uint8 explain_flags);
|
||||
int print_explain(select_result_sink *output, uint8 explain_flags,
|
||||
bool *printed_anything);
|
||||
/*
|
||||
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
|
||||
- Non-aggregated fields are used in this select.
|
||||
|
@ -10365,9 +10365,18 @@ bool JOIN_TAB::preread_init()
|
||||
mysql_handle_single_derived(join->thd->lex,
|
||||
derived, DT_CREATE | DT_FILL))
|
||||
return TRUE;
|
||||
|
||||
preread_init_done= TRUE;
|
||||
if (select && select->quick)
|
||||
select->quick->replace_handler(table->file);
|
||||
|
||||
DBUG_EXECUTE_IF("show_explain_probe_join_tab_preread",
|
||||
if (dbug_user_var_equals_int(join->thd,
|
||||
"show_explain_probe_select_id",
|
||||
join->select_lex->select_number))
|
||||
dbug_serve_apcs(join->thd, 1);
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -2085,6 +2085,7 @@ void mysqld_show_explain(THD *thd, ulong thread_id)
|
||||
"Target is not running EXPLAINable command");
|
||||
}
|
||||
bres= TRUE;
|
||||
explain_buf->discard_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user