mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MWL#182: Explain running statements
- Address feedback from the second code review.
This commit is contained in:
@ -10,11 +10,11 @@ alter table t1 add key(a), add key(b);
|
|||||||
show explain for 2*1000*1000*1000;
|
show explain for 2*1000*1000*1000;
|
||||||
ERROR HY000: Unknown thread id: 2000000000
|
ERROR HY000: Unknown thread id: 2000000000
|
||||||
show explain for (select max(a) from t0);
|
show explain for (select max(a) from t0);
|
||||||
ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
|
ERROR HY000: You may only use constant expressions in this statement
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
show explain for $thr1;
|
show explain for $thr1;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
set @show_explain_probe_select_id=1;
|
set @show_explain_probe_select_id=1;
|
||||||
set debug_dbug='d,show_explain_probe_join_exec_start';
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
select count(*) from t1 where a < 100000;
|
select count(*) from t1 where a < 100000;
|
||||||
@ -153,7 +153,7 @@ 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
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
|
||||||
# Try to do SHOW EXPLAIN for a query that runs a SET command:
|
# Try to do SHOW EXPLAIN for a query that runs a SET command:
|
||||||
@ -163,7 +163,7 @@ set @show_explain_probe_select_id=2;
|
|||||||
set debug_dbug='d,show_explain_probe_join_exec_start';
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
set @foo= (select max(a) from t0 where sin(a) >0);
|
set @foo= (select max(a) from t0 where sin(a) >0);
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
#
|
#
|
||||||
# Attempt SHOW EXPLAIN for an UPDATE
|
# Attempt SHOW EXPLAIN for an UPDATE
|
||||||
#
|
#
|
||||||
@ -172,9 +172,9 @@ set @show_explain_probe_select_id=2;
|
|||||||
set debug_dbug='d,show_explain_probe_join_exec_start';
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
drop table t2;
|
drop table t2;
|
||||||
#
|
#
|
||||||
# Attempt SHOW EXPLAIN for a DELETE
|
# Attempt SHOW EXPLAIN for a DELETE
|
||||||
@ -184,9 +184,9 @@ set @show_explain_probe_select_id=2;
|
|||||||
set debug_dbug='d,show_explain_probe_join_exec_start';
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
drop table t2;
|
drop table t2;
|
||||||
#
|
#
|
||||||
# Multiple SHOW EXPLAIN calls for one select
|
# Multiple SHOW EXPLAIN calls for one select
|
||||||
@ -308,7 +308,7 @@ 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
@ -361,7 +361,7 @@ set @show_explain_probe_select_id=2;
|
|||||||
set debug_dbug='d,show_explain_probe_join_exec_end';
|
set debug_dbug='d,show_explain_probe_join_exec_end';
|
||||||
SELECT * FROM v1, t2;
|
SELECT * FROM v1, t2;
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
a b
|
a b
|
||||||
8 4
|
8 4
|
||||||
8 5
|
8 5
|
||||||
@ -393,7 +393,7 @@ 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
a
|
a
|
||||||
set debug_dbug='';
|
set debug_dbug='';
|
||||||
#
|
#
|
||||||
@ -405,7 +405,7 @@ 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
a a
|
a a
|
||||||
set debug_dbug='';
|
set debug_dbug='';
|
||||||
drop table t3;
|
drop table t3;
|
||||||
@ -510,7 +510,7 @@ 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
pk a1
|
pk a1
|
||||||
set debug_dbug='';
|
set debug_dbug='';
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
@ -732,6 +732,7 @@ drop table t1,t3,t4;
|
|||||||
# ---------- SHOW EXPLAIN and permissions -----------------
|
# ---------- SHOW EXPLAIN and permissions -----------------
|
||||||
#
|
#
|
||||||
grant ALL on test.* to test2@localhost;
|
grant ALL on test.* to test2@localhost;
|
||||||
|
grant super on *.* to test2@localhost;
|
||||||
#
|
#
|
||||||
# First, make sure that user 'test2' cannot do SHOW EXPLAIN on us
|
# First, make sure that user 'test2' cannot do SHOW EXPLAIN on us
|
||||||
#
|
#
|
||||||
@ -739,7 +740,7 @@ set @show_explain_probe_select_id=1;
|
|||||||
set debug_dbug='d,show_explain_probe_join_exec_start';
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
select * from t0 where a < 3;
|
select * from t0 where a < 3;
|
||||||
show explain for $thr2;
|
show explain for $thr2;
|
||||||
ERROR 42000: Access denied; you need (at least one of) the PROCESSLIST privilege(s) for this operation
|
ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
|
||||||
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 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
|
||||||
@ -751,11 +752,20 @@ a
|
|||||||
2
|
2
|
||||||
set debug_dbug='';
|
set debug_dbug='';
|
||||||
#
|
#
|
||||||
# Unfortunately, our test setup doesn't allow to check that test2
|
# Check that user test2 can do SHOW EXPLAIN on its own queries
|
||||||
# can do SHOW EXPLAIN on his own queries. This is because SET debug_dbug
|
|
||||||
# requires SUPER privilege. Giving SUPER to test2 will make the test
|
|
||||||
# meaningless
|
|
||||||
#
|
#
|
||||||
|
set @show_explain_probe_select_id=1;
|
||||||
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
|
select * from t0 where a < 3;
|
||||||
|
show explain for $thr_con2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select * from t0 where a < 3
|
||||||
|
a
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
#
|
#
|
||||||
# Now, grant test2 a PROCESSLIST permission, and see that he's able to observe us
|
# Now, grant test2 a PROCESSLIST permission, and see that he's able to observe us
|
||||||
#
|
#
|
||||||
|
@ -45,7 +45,7 @@ alter table t1 add key(a), add key(b);
|
|||||||
--error ER_NO_SUCH_THREAD
|
--error ER_NO_SUCH_THREAD
|
||||||
show explain for 2*1000*1000*1000;
|
show explain for 2*1000*1000*1000;
|
||||||
|
|
||||||
--error ER_NOT_SUPPORTED_YET
|
--error ER_SET_CONSTANTS_ONLY
|
||||||
show explain for (select max(a) from t0);
|
show explain for (select max(a) from t0);
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -58,11 +58,11 @@ let $thr2=`select connection_id()`;
|
|||||||
connection default;
|
connection default;
|
||||||
|
|
||||||
# SHOW EXPLAIN FOR <idle thread>
|
# SHOW EXPLAIN FOR <idle thread>
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
|
|
||||||
# SHOW EXPLAIN FOR <ourselves>
|
# SHOW EXPLAIN FOR <ourselves>
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr1;
|
evalp show explain for $thr1;
|
||||||
|
|
||||||
let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr2;
|
let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr2;
|
||||||
@ -192,7 +192,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;
|
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_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -212,7 +212,7 @@ set debug_dbug='d,show_explain_probe_join_exec_start';
|
|||||||
send set @foo= (select max(a) from t0 where sin(a) >0);
|
send set @foo= (select max(a) from t0 where sin(a) >0);
|
||||||
connection default;
|
connection default;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -226,9 +226,9 @@ set debug_dbug='d,show_explain_probe_join_exec_start';
|
|||||||
send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
send update t2 set dummy=0 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
||||||
connection default;
|
connection default;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -243,9 +243,9 @@ set debug_dbug='d,show_explain_probe_join_exec_start';
|
|||||||
send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
send delete from t2 where (select max(a) from t0 where t2.a + t0.a <3) >3 ;
|
||||||
connection default;
|
connection default;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -329,7 +329,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_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -378,7 +378,7 @@ send SELECT * FROM v1, t2;
|
|||||||
|
|
||||||
connection default;
|
connection default;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -408,7 +408,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_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -424,7 +424,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_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -520,7 +520,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_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
@ -734,6 +734,8 @@ drop table t1,t3,t4;
|
|||||||
--echo #
|
--echo #
|
||||||
grant ALL on test.* to test2@localhost;
|
grant ALL on test.* to test2@localhost;
|
||||||
|
|
||||||
|
# Give the user SUPER privilege so it can set debug_dbug variable.
|
||||||
|
grant super on *.* to test2@localhost;
|
||||||
connect (con2, localhost, test2,,);
|
connect (con2, localhost, test2,,);
|
||||||
connection con1;
|
connection con1;
|
||||||
|
|
||||||
@ -760,12 +762,32 @@ reap;
|
|||||||
set debug_dbug='';
|
set debug_dbug='';
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Unfortunately, our test setup doesn't allow to check that test2
|
--echo # Check that user test2 can do SHOW EXPLAIN on its own queries
|
||||||
--echo # can do SHOW EXPLAIN on his own queries. This is because SET debug_dbug
|
|
||||||
--echo # requires SUPER privilege. Giving SUPER to test2 will make the test
|
|
||||||
--echo # meaningless
|
|
||||||
--echo #
|
--echo #
|
||||||
|
connect (con3, localhost, test2,,);
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
let $thr_con2=`select connection_id()`;
|
||||||
|
set @show_explain_probe_select_id=1;
|
||||||
|
set debug_dbug='d,show_explain_probe_join_exec_start';
|
||||||
|
send
|
||||||
|
select * from t0 where a < 3;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
let $save_wait_condition= $wait_condition;
|
||||||
|
let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr_con2;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
connection con3;
|
||||||
|
evalp show explain for $thr_con2;
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
reap;
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
|
||||||
|
disconnect con3;
|
||||||
|
let $wait_condition= $save_wait_condition;
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Now, grant test2 a PROCESSLIST permission, and see that he's able to observe us
|
--echo # Now, grant test2 a PROCESSLIST permission, and see that he's able to observe us
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -24,35 +24,6 @@
|
|||||||
|
|
||||||
/* For standalone testing of APC system, see unittest/sql/my_apc-t.cc */
|
/* For standalone testing of APC system, see unittest/sql/my_apc-t.cc */
|
||||||
|
|
||||||
#ifndef MY_APC_STANDALONE
|
|
||||||
|
|
||||||
ST_FIELD_INFO show_explain_fields_info[]=
|
|
||||||
{
|
|
||||||
/* field_name, length, type, value, field_flags, old_name*/
|
|
||||||
{"id", 3, MYSQL_TYPE_LONGLONG, 0 /*value*/, MY_I_S_MAYBE_NULL, "id",
|
|
||||||
SKIP_OPEN_TABLE},
|
|
||||||
{"select_type", 19, MYSQL_TYPE_STRING, 0 /*value*/, 0, "select_type",
|
|
||||||
SKIP_OPEN_TABLE},
|
|
||||||
{"table", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0 /*value*/, MY_I_S_MAYBE_NULL,
|
|
||||||
"table", SKIP_OPEN_TABLE},
|
|
||||||
{"type", 10, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "type", SKIP_OPEN_TABLE},
|
|
||||||
{"possible_keys", NAME_CHAR_LEN*MAX_KEY, MYSQL_TYPE_STRING, 0/*value*/,
|
|
||||||
MY_I_S_MAYBE_NULL, "possible_keys", SKIP_OPEN_TABLE},
|
|
||||||
{"key", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0/*value*/, MY_I_S_MAYBE_NULL,
|
|
||||||
"key", SKIP_OPEN_TABLE},
|
|
||||||
{"key_len", NAME_CHAR_LEN*MAX_KEY, MYSQL_TYPE_STRING, 0/*value*/,
|
|
||||||
MY_I_S_MAYBE_NULL, "key_len", SKIP_OPEN_TABLE},
|
|
||||||
{"ref", NAME_CHAR_LEN*MAX_REF_PARTS, MYSQL_TYPE_STRING, 0/*value*/,
|
|
||||||
MY_I_S_MAYBE_NULL, "ref", SKIP_OPEN_TABLE},
|
|
||||||
{"rows", 10, MYSQL_TYPE_LONGLONG, 0/*value*/, MY_I_S_MAYBE_NULL, "rows",
|
|
||||||
SKIP_OPEN_TABLE},
|
|
||||||
{"Extra", 255, MYSQL_TYPE_STRING, 0/*value*/, 0 /*flags*/, "Extra",
|
|
||||||
SKIP_OPEN_TABLE},
|
|
||||||
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
Initialize the target.
|
Initialize the target.
|
||||||
|
|
||||||
@ -266,9 +237,6 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
|
|||||||
|
|
||||||
void Apc_target::process_apc_requests()
|
void Apc_target::process_apc_requests()
|
||||||
{
|
{
|
||||||
if (!get_first_in_queue())
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
Call_request *request;
|
Call_request *request;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#ifndef INCLUDES_MY_APC_H
|
||||||
|
#define INCLUDES_MY_APC_H
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011 - 2012, Monty Program Ab
|
Copyright (c) 2011 - 2012, Monty Program Ab
|
||||||
|
|
||||||
@ -93,7 +95,7 @@ private:
|
|||||||
We use this structure, because we
|
We use this structure, because we
|
||||||
- process requests sequentially: requests are added at the end of the
|
- process requests sequentially: requests are added at the end of the
|
||||||
list and removed from the front. With circular list, we can keep one
|
list and removed from the front. With circular list, we can keep one
|
||||||
pointer.
|
pointer, and access both front an back of the list with it.
|
||||||
- a thread that has posted a request may time out (or be KILLed) and
|
- a thread that has posted a request may time out (or be KILLed) and
|
||||||
cancel the request, which means we need a fast request-removal
|
cancel the request, which means we need a fast request-removal
|
||||||
operation.
|
operation.
|
||||||
@ -132,3 +134,5 @@ private:
|
|||||||
void init_show_explain_psi_keys(void);
|
void init_show_explain_psi_keys(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif //INCLUDES_MY_APC_H
|
||||||
|
|
||||||
|
@ -3909,8 +3909,8 @@ static int init_thread_environment()
|
|||||||
sp_cache_init();
|
sp_cache_init();
|
||||||
#ifdef HAVE_EVENT_SCHEDULER
|
#ifdef HAVE_EVENT_SCHEDULER
|
||||||
Events::init_mutexes();
|
Events::init_mutexes();
|
||||||
init_show_explain_psi_keys();
|
|
||||||
#endif
|
#endif
|
||||||
|
init_show_explain_psi_keys();
|
||||||
/* Parameter for threads created for connections */
|
/* Parameter for threads created for connections */
|
||||||
(void) pthread_attr_init(&connection_attrib);
|
(void) pthread_attr_init(&connection_attrib);
|
||||||
(void) pthread_attr_setdetachstate(&connection_attrib,
|
(void) pthread_attr_setdetachstate(&connection_attrib,
|
||||||
|
@ -4345,13 +4345,13 @@ ER_TOO_MANY_USER_CONNECTIONS 42000
|
|||||||
ER_SET_CONSTANTS_ONLY
|
ER_SET_CONSTANTS_ONLY
|
||||||
dan "Du må kun bruge konstantudtryk med SET"
|
dan "Du må kun bruge konstantudtryk med SET"
|
||||||
nla "U mag alleen constante expressies gebruiken bij SET"
|
nla "U mag alleen constante expressies gebruiken bij SET"
|
||||||
eng "You may only use constant expressions with SET"
|
eng "You may only use constant expressions in this statement"
|
||||||
est "Ainult konstantsed suurused on lubatud SET klauslis"
|
est "Ainult konstantsed suurused on lubatud SET klauslis"
|
||||||
fre "Seules les expressions constantes sont autorisées avec SET"
|
fre "Seules les expressions constantes sont autorisées avec SET"
|
||||||
ger "Bei SET dürfen nur konstante Ausdrücke verwendet werden"
|
ger "Bei diesem Befehl dürfen nur konstante Ausdrücke verwendet werden"
|
||||||
ita "Si possono usare solo espressioni costanti con SET"
|
ita "Si possono usare solo espressioni costanti con SET"
|
||||||
por "Você pode usar apenas expressões constantes com SET"
|
por "Você pode usar apenas expressões constantes com SET"
|
||||||
rus "Вы можете использовать в SET только константные выражения"
|
rus "С этой командой вы можете использовать только константные выражения"
|
||||||
serbian "Možete upotrebiti samo konstantan iskaz sa komandom 'SET'"
|
serbian "Možete upotrebiti samo konstantan iskaz sa komandom 'SET'"
|
||||||
spa "Tu solo debes usar expresiones constantes con SET"
|
spa "Tu solo debes usar expresiones constantes con SET"
|
||||||
swe "Man kan endast använda konstantuttryck med SET"
|
swe "Man kan endast använda konstantuttryck med SET"
|
||||||
@ -6582,3 +6582,5 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION
|
|||||||
eng "Cannot modify @@session.skip_replication inside a stored function or trigger"
|
eng "Cannot modify @@session.skip_replication inside a stored function or trigger"
|
||||||
ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
|
ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
|
||||||
eng "Query execution was interrupted. The query examined at least %llu rows, which exceeds LIMIT ROWS EXAMINED (%llu). The query result may be incomplete."
|
eng "Query execution was interrupted. The query examined at least %llu rows, which exceeds LIMIT ROWS EXAMINED (%llu). The query result may be incomplete."
|
||||||
|
ER_TARGET_NOT_EXPLAINABLE
|
||||||
|
eng "Target is not running an EXPLAINable command"
|
||||||
|
@ -2295,15 +2295,6 @@ int select_send::send_data(List<Item> &items)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int select_result_explain_buffer::send_data(List<Item> &items)
|
|
||||||
{
|
|
||||||
fill_record(thd, dst_table->field, items, TRUE, FALSE);
|
|
||||||
if ((dst_table->file->ha_write_tmp_row(dst_table->record[0])))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool select_send::send_eof()
|
bool select_send::send_eof()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -3233,43 +3224,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Produce EXPLAIN data.
|
|
||||||
|
|
||||||
This function is APC-scheduled to be run in the context of the thread that
|
|
||||||
we're producing EXPLAIN for.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Show_explain_request::call_in_target_thread()
|
|
||||||
{
|
|
||||||
Query_arena backup_arena;
|
|
||||||
bool printed_anything= FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Change the arena because JOIN::print_explain and co. are going to allocate
|
|
||||||
items. Let them allocate them on our arena.
|
|
||||||
*/
|
|
||||||
target_thd->set_n_backup_active_arena((Query_arena*)request_thd,
|
|
||||||
&backup_arena);
|
|
||||||
|
|
||||||
query_str.copy(target_thd->query(),
|
|
||||||
target_thd->query_length(),
|
|
||||||
&my_charset_bin);
|
|
||||||
|
|
||||||
if (target_thd->lex->unit.print_explain(explain_buf, 0 /* explain flags*/,
|
|
||||||
&printed_anything))
|
|
||||||
{
|
|
||||||
failed_to_produce= TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!printed_anything)
|
|
||||||
failed_to_produce= TRUE;
|
|
||||||
|
|
||||||
target_thd->restore_active_arena((Query_arena*)request_thd, &backup_arena);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Statement::~Statement()
|
Statement::~Statement()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -3832,6 +3786,7 @@ void THD::restore_backup_open_tables_state(Open_tables_backup *backup)
|
|||||||
@retval 1 the user thread has been killed
|
@retval 1 the user thread has been killed
|
||||||
|
|
||||||
This is used to signal a storage engine if it should be killed.
|
This is used to signal a storage engine if it should be killed.
|
||||||
|
See also THD::check_killed().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" int thd_killed(const MYSQL_THD thd)
|
extern "C" int thd_killed(const MYSQL_THD thd)
|
||||||
@ -3839,6 +3794,10 @@ extern "C" int thd_killed(const MYSQL_THD thd)
|
|||||||
if (!thd)
|
if (!thd)
|
||||||
thd= current_thd;
|
thd= current_thd;
|
||||||
|
|
||||||
|
Apc_target *apc_target= (Apc_target*)&thd->apc_target;
|
||||||
|
if (apc_target->have_apc_requests())
|
||||||
|
apc_target->process_apc_requests();
|
||||||
|
|
||||||
if (!(thd->killed & KILL_HARD_BIT))
|
if (!(thd->killed & KILL_HARD_BIT))
|
||||||
return 0;
|
return 0;
|
||||||
return thd->killed;
|
return thd->killed;
|
||||||
|
@ -1520,39 +1520,7 @@ private:
|
|||||||
|
|
||||||
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
||||||
|
|
||||||
class select_result_explain_buffer;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
SHOW EXPLAIN request object.
|
|
||||||
|
|
||||||
The thread that runs SHOW EXPLAIN statement creates a Show_explain_request
|
|
||||||
object R, and then schedules APC call of
|
|
||||||
Show_explain_request::call((void*)&R).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Show_explain_request : public Apc_target::Apc_call
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
THD *target_thd; /* thd that we're running SHOW EXPLAIN for */
|
|
||||||
THD *request_thd; /* thd that run SHOW EXPLAIN command */
|
|
||||||
|
|
||||||
/* If true, there was some error when producing EXPLAIN output. */
|
|
||||||
bool failed_to_produce;
|
|
||||||
|
|
||||||
/* SHOW EXPLAIN will be stored here */
|
|
||||||
select_result_explain_buffer *explain_buf;
|
|
||||||
|
|
||||||
/* Query that we've got SHOW EXPLAIN for */
|
|
||||||
String query_str;
|
|
||||||
|
|
||||||
/* Overloaded virtual function */
|
|
||||||
void call_in_target_thread();
|
|
||||||
};
|
|
||||||
|
|
||||||
class THD;
|
class THD;
|
||||||
void mysqld_show_explain(THD *thd, const char *calling_user, ulong thread_id);
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
void dbug_serve_apcs(THD *thd, int n_calls);
|
void dbug_serve_apcs(THD *thd, int n_calls);
|
||||||
#endif
|
#endif
|
||||||
@ -2222,6 +2190,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
killed_state volatile killed;
|
killed_state volatile killed;
|
||||||
|
|
||||||
|
/* See also thd_killed() */
|
||||||
inline bool check_killed()
|
inline bool check_killed()
|
||||||
{
|
{
|
||||||
if (killed)
|
if (killed)
|
||||||
@ -2438,7 +2407,8 @@ public:
|
|||||||
Allows this thread to serve as a target for others to schedule Async
|
Allows this thread to serve as a target for others to schedule Async
|
||||||
Procedure Calls on.
|
Procedure Calls on.
|
||||||
|
|
||||||
It's possible to schedule arbitrary C++ function calls. Currently, only
|
It's possible to schedule any code to be executed this way, by
|
||||||
|
inheriting from the Apc_call object. Currently, only
|
||||||
Show_explain_request uses this.
|
Show_explain_request uses this.
|
||||||
*/
|
*/
|
||||||
Apc_target apc_target;
|
Apc_target apc_target;
|
||||||
|
@ -2155,9 +2155,9 @@ mysql_execute_command(THD *thd)
|
|||||||
*/
|
*/
|
||||||
if (lex->sroutines.records || lex->query_tables->next_global)
|
if (lex->sroutines.records || lex->query_tables->next_global)
|
||||||
{
|
{
|
||||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
|
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
|
||||||
"function calls as part of this statement");
|
MYF(0));
|
||||||
break;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item **it= &(lex->show_explain_for_thread);
|
Item **it= &(lex->show_explain_for_thread);
|
||||||
|
@ -1999,8 +1999,50 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
/*
|
||||||
const char *target_not_explainable_cmd="Target is not running EXPLAINable command";
|
Produce EXPLAIN data.
|
||||||
|
|
||||||
|
This function is APC-scheduled to be run in the context of the thread that
|
||||||
|
we're producing EXPLAIN for.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Show_explain_request::call_in_target_thread()
|
||||||
|
{
|
||||||
|
Query_arena backup_arena;
|
||||||
|
bool printed_anything= FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Change the arena because JOIN::print_explain and co. are going to allocate
|
||||||
|
items. Let them allocate them on our arena.
|
||||||
|
*/
|
||||||
|
target_thd->set_n_backup_active_arena((Query_arena*)request_thd,
|
||||||
|
&backup_arena);
|
||||||
|
|
||||||
|
query_str.copy(target_thd->query(),
|
||||||
|
target_thd->query_length(),
|
||||||
|
&my_charset_bin);
|
||||||
|
|
||||||
|
if (target_thd->lex->unit.print_explain(explain_buf, 0 /* explain flags*/,
|
||||||
|
&printed_anything))
|
||||||
|
{
|
||||||
|
failed_to_produce= TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!printed_anything)
|
||||||
|
failed_to_produce= TRUE;
|
||||||
|
|
||||||
|
target_thd->restore_active_arena((Query_arena*)request_thd, &backup_arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int select_result_explain_buffer::send_data(List<Item> &items)
|
||||||
|
{
|
||||||
|
fill_record(thd, dst_table->field, items, TRUE, FALSE);
|
||||||
|
if ((dst_table->file->ha_write_tmp_row(dst_table->record[0])))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Store the SHOW EXPLAIN output in the temporary table.
|
Store the SHOW EXPLAIN output in the temporary table.
|
||||||
@ -2048,7 +2090,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
|
|||||||
if (calling_user && (!tmp_sctx->user || strcmp(calling_user,
|
if (calling_user && (!tmp_sctx->user || strcmp(calling_user,
|
||||||
tmp_sctx->user)))
|
tmp_sctx->user)))
|
||||||
{
|
{
|
||||||
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "PROCESSLIST");
|
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "PROCESS");
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
@ -2056,8 +2098,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
|
|||||||
if (tmp == thd)
|
if (tmp == thd)
|
||||||
{
|
{
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), "SHOW EXPLAIN",
|
my_error(ER_TARGET_NOT_EXPLAINABLE, MYF(0));
|
||||||
target_not_explainable_cmd);
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,21 +2125,12 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
|
|||||||
if (bres || explain_req.failed_to_produce)
|
if (bres || explain_req.failed_to_produce)
|
||||||
{
|
{
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
{
|
|
||||||
thd->send_kill_message();
|
thd->send_kill_message();
|
||||||
}
|
else if (timed_out)
|
||||||
else
|
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
|
||||||
if (timed_out)
|
|
||||||
{
|
|
||||||
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
|
|
||||||
"SHOW EXPLAIN",
|
|
||||||
"Timeout");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
my_error(ER_TARGET_NOT_EXPLAINABLE, MYF(0));
|
||||||
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
|
|
||||||
"SHOW EXPLAIN", target_not_explainable_cmd);
|
|
||||||
}
|
|
||||||
bres= TRUE;
|
bres= TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -8427,7 +8459,32 @@ ST_FIELD_INFO keycache_fields_info[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern ST_FIELD_INFO show_explain_fields_info[];
|
ST_FIELD_INFO show_explain_fields_info[]=
|
||||||
|
{
|
||||||
|
/* field_name, length, type, value, field_flags, old_name*/
|
||||||
|
{"id", 3, MYSQL_TYPE_LONGLONG, 0 /*value*/, MY_I_S_MAYBE_NULL, "id",
|
||||||
|
SKIP_OPEN_TABLE},
|
||||||
|
{"select_type", 19, MYSQL_TYPE_STRING, 0 /*value*/, 0, "select_type",
|
||||||
|
SKIP_OPEN_TABLE},
|
||||||
|
{"table", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0 /*value*/, MY_I_S_MAYBE_NULL,
|
||||||
|
"table", SKIP_OPEN_TABLE},
|
||||||
|
{"type", 10, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "type", SKIP_OPEN_TABLE},
|
||||||
|
{"possible_keys", NAME_CHAR_LEN*MAX_KEY, MYSQL_TYPE_STRING, 0/*value*/,
|
||||||
|
MY_I_S_MAYBE_NULL, "possible_keys", SKIP_OPEN_TABLE},
|
||||||
|
{"key", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0/*value*/, MY_I_S_MAYBE_NULL,
|
||||||
|
"key", SKIP_OPEN_TABLE},
|
||||||
|
{"key_len", NAME_CHAR_LEN*MAX_KEY, MYSQL_TYPE_STRING, 0/*value*/,
|
||||||
|
MY_I_S_MAYBE_NULL, "key_len", SKIP_OPEN_TABLE},
|
||||||
|
{"ref", NAME_CHAR_LEN*MAX_REF_PARTS, MYSQL_TYPE_STRING, 0/*value*/,
|
||||||
|
MY_I_S_MAYBE_NULL, "ref", SKIP_OPEN_TABLE},
|
||||||
|
{"rows", 10, MYSQL_TYPE_LONGLONG, 0/*value*/, MY_I_S_MAYBE_NULL, "rows",
|
||||||
|
SKIP_OPEN_TABLE},
|
||||||
|
{"Extra", 255, MYSQL_TYPE_STRING, 0/*value*/, 0 /*flags*/, "Extra",
|
||||||
|
SKIP_OPEN_TABLE},
|
||||||
|
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Description of ST_FIELD_INFO in table.h
|
Description of ST_FIELD_INFO in table.h
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "sql_list.h" /* List */
|
#include "sql_list.h" /* List */
|
||||||
#include "handler.h" /* enum_schema_tables */
|
#include "handler.h" /* enum_schema_tables */
|
||||||
#include "table.h" /* enum_schema_table_state */
|
#include "table.h" /* enum_schema_table_state */
|
||||||
|
#include "my_apc.h"
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
class JOIN;
|
class JOIN;
|
||||||
@ -132,4 +133,28 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
|
|||||||
/* These functions were under INNODB_COMPATIBILITY_HOOKS */
|
/* These functions were under INNODB_COMPATIBILITY_HOOKS */
|
||||||
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
|
int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
|
||||||
|
|
||||||
|
class select_result_explain_buffer;
|
||||||
|
/*
|
||||||
|
SHOW EXPLAIN request object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Show_explain_request : public Apc_target::Apc_call
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
THD *target_thd; /* thd that we're running SHOW EXPLAIN for */
|
||||||
|
THD *request_thd; /* thd that run SHOW EXPLAIN command */
|
||||||
|
|
||||||
|
/* If true, there was some error when producing EXPLAIN output. */
|
||||||
|
bool failed_to_produce;
|
||||||
|
|
||||||
|
/* SHOW EXPLAIN will be stored here */
|
||||||
|
select_result_explain_buffer *explain_buf;
|
||||||
|
|
||||||
|
/* Query that we've got SHOW EXPLAIN for */
|
||||||
|
String query_str;
|
||||||
|
|
||||||
|
/* Overloaded virtual function */
|
||||||
|
void call_in_target_thread();
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SQL_SHOW_H */
|
#endif /* SQL_SHOW_H */
|
||||||
|
@ -90,7 +90,7 @@ void *test_apc_service_thread(void *ptr)
|
|||||||
apc_target.init(&target_mutex);
|
apc_target.init(&target_mutex);
|
||||||
apc_target.enable();
|
apc_target.enable();
|
||||||
started= TRUE;
|
started= TRUE;
|
||||||
fprintf(stderr, "# test_apc_service_thread started\n");
|
diag("test_apc_service_thread started");
|
||||||
while (!service_should_exit)
|
while (!service_should_exit)
|
||||||
{
|
{
|
||||||
//apc_target.disable();
|
//apc_target.disable();
|
||||||
@ -137,7 +137,7 @@ public:
|
|||||||
void *test_apc_requestor_thread(void *ptr)
|
void *test_apc_requestor_thread(void *ptr)
|
||||||
{
|
{
|
||||||
my_thread_init();
|
my_thread_init();
|
||||||
fprintf(stderr, "# test_apc_requestor_thread started\n");
|
diag("test_apc_requestor_thread started");
|
||||||
THD my_thd;
|
THD my_thd;
|
||||||
|
|
||||||
while (!requestors_should_exit)
|
while (!requestors_should_exit)
|
||||||
@ -159,7 +159,7 @@ void *test_apc_requestor_thread(void *ptr)
|
|||||||
|
|
||||||
if (dst_value != 0)
|
if (dst_value != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "APC was done even though return value says it wasnt!\n");
|
diag("APC was done even though return value says it wasnt!");
|
||||||
have_errors= true;
|
have_errors= true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,13 +167,13 @@ void *test_apc_requestor_thread(void *ptr)
|
|||||||
{
|
{
|
||||||
if (dst_value != src_value)
|
if (dst_value != src_value)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "APC was not done even though return value says it was!\n");
|
diag("APC was not done even though return value says it was!");
|
||||||
have_errors= true;
|
have_errors= true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//my_sleep(300);
|
//my_sleep(300);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "# test_apc_requestor_thread exiting\n");
|
diag("test_apc_requestor_thread exiting");
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -204,20 +204,20 @@ int main(int args, char **argv)
|
|||||||
for (i = 0; i < 15; i++)
|
for (i = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
my_sleep(500*1000);
|
my_sleep(500*1000);
|
||||||
fprintf(stderr, "# %d APCs served %d missed\n", apcs_served, apcs_missed);
|
diag("%d APCs served %d missed", apcs_served, apcs_missed);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "# Shutting down requestors\n");
|
diag("Shutting down requestors");
|
||||||
requestors_should_exit= TRUE;
|
requestors_should_exit= TRUE;
|
||||||
for (i = 0; i < N_THREADS; i++)
|
for (i = 0; i < N_THREADS; i++)
|
||||||
pthread_join(request_thr[i], NULL);
|
pthread_join(request_thr[i], NULL);
|
||||||
|
|
||||||
fprintf(stderr, "# Shutting down service\n");
|
diag("Shutting down service");
|
||||||
service_should_exit= TRUE;
|
service_should_exit= TRUE;
|
||||||
pthread_join(service_thr, NULL);
|
pthread_join(service_thr, NULL);
|
||||||
|
|
||||||
mysql_mutex_destroy(&apc_counters_mutex);
|
mysql_mutex_destroy(&apc_counters_mutex);
|
||||||
|
|
||||||
fprintf(stderr, "# Done.\n");
|
diag("Done");
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
my_thread_global_end();
|
my_thread_global_end();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user