Commit 5eecea8c authored by Sergey Petrunya's avatar Sergey Petrunya

MDEV-324: SHOW EXPLAIN: Plan produced by SHOW EXPLAIN for a query with...

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.
parent 2c1e737c
......@@ -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 @@ class select_result_explain_buffer : public select_result_sink
/* 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 @@ class st_select_lex_unit: public st_select_lex_node {
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 @@ class st_select_lex: public st_select_lex_node
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
{
......
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