mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MWL#182: Explain running statements
- Implement new approach to testing (the DBUG_EXECUTE_IF variant) - add an 'evalp' mysqltest command that is like 'eval' except that it prints the original query. - Fix select_describe() not to change join_tab[i]->type - More tests
This commit is contained in:
@ -75,6 +75,8 @@
|
|||||||
#define QUERY_SEND_FLAG 1
|
#define QUERY_SEND_FLAG 1
|
||||||
#define QUERY_REAP_FLAG 2
|
#define QUERY_REAP_FLAG 2
|
||||||
|
|
||||||
|
#define QUERY_PRINT_ORIGINAL_FLAG 4
|
||||||
|
|
||||||
#ifndef HAVE_SETENV
|
#ifndef HAVE_SETENV
|
||||||
static int setenv(const char *name, const char *value, int overwrite);
|
static int setenv(const char *name, const char *value, int overwrite);
|
||||||
#endif
|
#endif
|
||||||
@ -289,6 +291,7 @@ enum enum_commands {
|
|||||||
Q_SEND, Q_REAP,
|
Q_SEND, Q_REAP,
|
||||||
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
|
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
|
||||||
Q_PING, Q_EVAL,
|
Q_PING, Q_EVAL,
|
||||||
|
Q_EVALP,
|
||||||
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
||||||
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
||||||
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
||||||
@ -353,6 +356,7 @@ const char *command_names[]=
|
|||||||
"replace_column",
|
"replace_column",
|
||||||
"ping",
|
"ping",
|
||||||
"eval",
|
"eval",
|
||||||
|
"evalp",
|
||||||
"rpl_probe",
|
"rpl_probe",
|
||||||
"enable_rpl_parse",
|
"enable_rpl_parse",
|
||||||
"disable_rpl_parse",
|
"disable_rpl_parse",
|
||||||
@ -7532,7 +7536,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
|
|||||||
/*
|
/*
|
||||||
Evaluate query if this is an eval command
|
Evaluate query if this is an eval command
|
||||||
*/
|
*/
|
||||||
if (command->type == Q_EVAL || command->type == Q_SEND_EVAL)
|
if (command->type == Q_EVAL || command->type == Q_SEND_EVAL ||
|
||||||
|
command->type == Q_EVALP)
|
||||||
{
|
{
|
||||||
init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
|
init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
|
||||||
do_eval(&eval_query, command->query, command->end, FALSE);
|
do_eval(&eval_query, command->query, command->end, FALSE);
|
||||||
@ -7564,11 +7569,21 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
|
|||||||
*/
|
*/
|
||||||
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
|
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
|
||||||
{
|
{
|
||||||
replace_dynstr_append_mem(ds, query, query_len);
|
char *print_query= query;
|
||||||
|
int print_len= query_len;
|
||||||
|
if (flags & QUERY_PRINT_ORIGINAL_FLAG)
|
||||||
|
{
|
||||||
|
print_query= command->query;
|
||||||
|
print_len= command->end - command->query;
|
||||||
|
}
|
||||||
|
replace_dynstr_append_mem(ds, print_query, print_len);
|
||||||
dynstr_append_mem(ds, delimiter, delimiter_length);
|
dynstr_append_mem(ds, delimiter, delimiter_length);
|
||||||
dynstr_append_mem(ds, "\n", 1);
|
dynstr_append_mem(ds, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We're done with this flag */
|
||||||
|
flags &= ~QUERY_PRINT_ORIGINAL_FLAG;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Write the command to the result file before we execute the query
|
Write the command to the result file before we execute the query
|
||||||
This is needed to be able to analyse the log if something goes
|
This is needed to be able to analyse the log if something goes
|
||||||
@ -8420,6 +8435,7 @@ int main(int argc, char **argv)
|
|||||||
case Q_EVAL_RESULT:
|
case Q_EVAL_RESULT:
|
||||||
die("'eval_result' command is deprecated");
|
die("'eval_result' command is deprecated");
|
||||||
case Q_EVAL:
|
case Q_EVAL:
|
||||||
|
case Q_EVALP:
|
||||||
case Q_QUERY_VERTICAL:
|
case Q_QUERY_VERTICAL:
|
||||||
case Q_QUERY_HORIZONTAL:
|
case Q_QUERY_HORIZONTAL:
|
||||||
if (command->query == command->query_buf)
|
if (command->query == command->query_buf)
|
||||||
@ -8447,6 +8463,9 @@ int main(int argc, char **argv)
|
|||||||
flags= QUERY_REAP_FLAG;
|
flags= QUERY_REAP_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command->type == Q_EVALP)
|
||||||
|
flags |= QUERY_PRINT_ORIGINAL_FLAG;
|
||||||
|
|
||||||
/* Check for special property for this query */
|
/* Check for special property for this query */
|
||||||
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
|
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
|
||||||
|
|
||||||
|
@ -3,24 +3,37 @@ create table t0 (a int);
|
|||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
|
insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
|
||||||
|
alter table t1 add b int, add c int, add filler char(32);
|
||||||
|
update t1 set b=a, c=a, filler='fooo';
|
||||||
|
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 thr2
|
show explain for (select max(a) from t0);
|
||||||
|
ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
|
||||||
|
show explain for $thr2;
|
||||||
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
ERROR HY000: Error when executing command SHOW EXPLAIN: Target is not running 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: Error when executing command SHOW EXPLAIN: Target is not running EXPLAINable command
|
||||||
select get_lock('optimizer_done', 10);
|
set debug='d,show_explain_probe_1';
|
||||||
get_lock('optimizer_done', 10)
|
select count(*) from t1 where a < 100000;
|
||||||
1
|
show explain for $thr2;
|
||||||
select count(*) from t1 where a < 100000 and sleep(a*0 + release_lock('optimizer_done') +1);
|
|
||||||
select get_lock('optimizer_done', 100);
|
|
||||||
get_lock('optimizer_done', 100)
|
|
||||||
1
|
|
||||||
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 t1 ALL NULL NULL NULL NULL 1000 Using where
|
1 SIMPLE t1 index a a 5 NULL 1000 Using where; Using index
|
||||||
select release_lock('optimizer_done');
|
count(*)
|
||||||
release_lock('optimizer_done')
|
1000
|
||||||
1
|
set debug='d,show_explain_probe_1';
|
||||||
kill query thr2
|
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
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 10 Using where
|
||||||
|
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
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range a a 5 NULL 10 Using index condition; Rowid-ordered scan
|
||||||
drop table t0,t1;
|
drop table t0,t1;
|
||||||
|
@ -9,6 +9,9 @@ create table t0 (a int);
|
|||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
|
insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
|
||||||
|
alter table t1 add b int, add c int, add filler char(32);
|
||||||
|
update t1 set b=a, c=a, filler='fooo';
|
||||||
|
alter table t1 add key(a), add key(b);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Try killing a non-existent thread
|
# Try killing a non-existent thread
|
||||||
@ -16,7 +19,12 @@ insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
|
|||||||
--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
|
||||||
|
show explain for (select max(a) from t0);
|
||||||
|
|
||||||
|
#
|
||||||
# Setup two threads and their ids
|
# Setup two threads and their ids
|
||||||
|
#
|
||||||
let $thr1=`select connection_id()`;
|
let $thr1=`select connection_id()`;
|
||||||
connect (con1, localhost, root,,);
|
connect (con1, localhost, root,,);
|
||||||
connection con1;
|
connection con1;
|
||||||
@ -24,36 +32,47 @@ let $thr2=`select connection_id()`;
|
|||||||
connection default;
|
connection default;
|
||||||
|
|
||||||
# SHOW EXPLAIN FOR <idle thread>
|
# SHOW EXPLAIN FOR <idle thread>
|
||||||
echo SHOW explain for thr2;
|
|
||||||
--disable_query_log
|
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
||||||
eval show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
--enable_query_log
|
|
||||||
|
|
||||||
# SHOW EXPLAIN FOR <ourselves>
|
# SHOW EXPLAIN FOR <ourselves>
|
||||||
echo SHOW explain for thr1;
|
|
||||||
--disable_query_log
|
|
||||||
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
--error ER_ERROR_WHEN_EXECUTING_COMMAND
|
||||||
eval show explain for $thr1;
|
evalp show explain for $thr1;
|
||||||
--enable_query_log
|
|
||||||
|
|
||||||
# SHOW EXPLAIN FOR <running thread>
|
let $wait_condition= select State='show_explain_trap' from information_schema.processlist where id=$thr2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test SHOW EXPLAIN for simple queries
|
||||||
|
#
|
||||||
connection con1;
|
connection con1;
|
||||||
select get_lock('optimizer_done', 10);
|
set debug='d,show_explain_probe_1';
|
||||||
send select count(*) from t1 where a < 100000 and sleep(a*0 + release_lock('optimizer_done') +1);
|
send select count(*) from t1 where a < 100000;
|
||||||
connection default;
|
|
||||||
select get_lock('optimizer_done', 100);
|
connection default;
|
||||||
echo SHOW explain for thr2;
|
--source include/wait_condition.inc
|
||||||
--disable_query_log
|
evalp show explain for $thr2;
|
||||||
eval show explain for $thr2;
|
connection con1;
|
||||||
--enable_query_log
|
reap;
|
||||||
select release_lock('optimizer_done');
|
|
||||||
--disable_query_log
|
|
||||||
eval kill query $thr2;
|
set debug='d,show_explain_probe_1';
|
||||||
--enable_query_log
|
send select max(c) from t1 where a < 10;
|
||||||
echo kill query thr2;
|
connection default;
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
evalp show explain for $thr2;
|
||||||
|
connection con1;
|
||||||
|
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
|
||||||
|
evalp show explain for $thr2;
|
||||||
|
connection con1;
|
||||||
|
reap;
|
||||||
|
|
||||||
#insert into t1 values ('one'),('two'),('three');
|
|
||||||
|
|
||||||
## TODO: Test this: multiple SHOW EXPLAIN calls in course of running of one select
|
## TODO: Test this: multiple SHOW EXPLAIN calls in course of running of one select
|
||||||
##
|
##
|
||||||
|
@ -29,6 +29,10 @@ void Apc_target::init()
|
|||||||
// todo: should use my_pthread_... functions instead?
|
// todo: should use my_pthread_... functions instead?
|
||||||
DBUG_ASSERT(!enabled);
|
DBUG_ASSERT(!enabled);
|
||||||
(void)pthread_mutex_init(&LOCK_apc_queue, MY_MUTEX_INIT_SLOW);
|
(void)pthread_mutex_init(&LOCK_apc_queue, MY_MUTEX_INIT_SLOW);
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
n_calls_processed= 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,6 +221,10 @@ void Apc_target::process_apc_requests()
|
|||||||
request->func(request->func_arg);
|
request->func(request->func_arg);
|
||||||
request->what="func called by process_apc_requests";
|
request->what="func called by process_apc_requests";
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
n_calls_processed++;
|
||||||
|
#endif
|
||||||
|
|
||||||
pthread_cond_signal(&request->COND_request);
|
pthread_cond_signal(&request->COND_request);
|
||||||
|
|
||||||
pthread_mutex_unlock(&request->LOCK_request);
|
pthread_mutex_unlock(&request->LOCK_request);
|
||||||
|
@ -62,13 +62,17 @@ public:
|
|||||||
bool make_apc_call(apc_func_t func, void *func_arg,
|
bool make_apc_call(apc_func_t func, void *func_arg,
|
||||||
int timeout_sec, bool *timed_out);
|
int timeout_sec, bool *timed_out);
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
int n_calls_processed;
|
||||||
|
//int call_queue_size;
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
class Call_request;
|
class Call_request;
|
||||||
int enabled;
|
int enabled;
|
||||||
|
|
||||||
Call_request *apc_calls;
|
Call_request *apc_calls;
|
||||||
pthread_mutex_t LOCK_apc_queue;
|
pthread_mutex_t LOCK_apc_queue;
|
||||||
//int call_queue_size;
|
|
||||||
|
|
||||||
class Call_request
|
class Call_request
|
||||||
{
|
{
|
||||||
|
@ -2404,6 +2404,10 @@ int rea_create_table(THD *thd, const char *path,
|
|||||||
int format_number(uint inputflag,uint max_length,char * pos,uint length,
|
int format_number(uint inputflag,uint max_length,char * pos,uint length,
|
||||||
char * *errpos);
|
char * *errpos);
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
void dbug_serve_apcs(THD *thd, int n_calls);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* table.cc */
|
/* table.cc */
|
||||||
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
|
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
|
||||||
uint key_length);
|
uint key_length);
|
||||||
|
@ -245,6 +245,25 @@ Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
|
|||||||
JOIN_TAB *first_depth_first_tab(JOIN* join);
|
JOIN_TAB *first_depth_first_tab(JOIN* join);
|
||||||
JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab);
|
JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab);
|
||||||
|
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
// psergey:
|
||||||
|
void dbug_serve_apcs(THD *thd, int n_calls)
|
||||||
|
{
|
||||||
|
// TODO how do we signal that we're SHOW-EXPLAIN-READY?
|
||||||
|
const char *save_proc_info= thd->proc_info;
|
||||||
|
thd_proc_info(thd, "show_explain_trap");
|
||||||
|
|
||||||
|
int n_apcs= thd->apc_target.n_calls_processed + n_calls;
|
||||||
|
while (thd->apc_target.n_calls_processed < n_apcs)
|
||||||
|
{
|
||||||
|
my_sleep(300);
|
||||||
|
if (thd->check_killed())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thd_proc_info(thd, save_proc_info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This handles SELECT with and without UNION.
|
This handles SELECT with and without UNION.
|
||||||
*/
|
*/
|
||||||
@ -2048,6 +2067,8 @@ void JOIN::exec_inner()
|
|||||||
int tmp_error;
|
int tmp_error;
|
||||||
DBUG_ENTER("JOIN::exec");
|
DBUG_ENTER("JOIN::exec");
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("show_explain_probe_1", dbug_serve_apcs(thd, 1););
|
||||||
|
|
||||||
thd_proc_info(thd, "executing");
|
thd_proc_info(thd, "executing");
|
||||||
error= 0;
|
error= 0;
|
||||||
if (procedure)
|
if (procedure)
|
||||||
@ -20430,7 +20451,6 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
}
|
}
|
||||||
else if (join->select_lex == join->unit->fake_select_lex)
|
else if (join->select_lex == join->unit->fake_select_lex)
|
||||||
{
|
{
|
||||||
//if (!join->select_lex->type)
|
|
||||||
if (on_the_fly)
|
if (on_the_fly)
|
||||||
join->select_lex->set_explain_type(on_the_fly); //psergey
|
join->select_lex->set_explain_type(on_the_fly); //psergey
|
||||||
/*
|
/*
|
||||||
@ -20561,6 +20581,7 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
join->select_lex->type;
|
join->select_lex->type;
|
||||||
item_list.push_back(new Item_string(stype, strlen(stype), cs));
|
item_list.push_back(new Item_string(stype, strlen(stype), cs));
|
||||||
|
|
||||||
|
enum join_type tab_type= tab->type;
|
||||||
if ((tab->type == JT_ALL || tab->type == JT_HASH) &&
|
if ((tab->type == JT_ALL || tab->type == JT_HASH) &&
|
||||||
tab->select && tab->select->quick)
|
tab->select && tab->select->quick)
|
||||||
{
|
{
|
||||||
@ -20569,9 +20590,9 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
(quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) ||
|
(quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) ||
|
||||||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
|
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
|
||||||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
|
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
|
||||||
tab->type= tab->type == JT_ALL ? JT_INDEX_MERGE : JT_HASH_INDEX_MERGE;
|
tab_type= tab->type == JT_ALL ? JT_INDEX_MERGE : JT_HASH_INDEX_MERGE;
|
||||||
else
|
else
|
||||||
tab->type= tab->type == JT_ALL ? JT_RANGE : JT_HASH_RANGE;
|
tab_type= tab->type == JT_ALL ? JT_RANGE : JT_HASH_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* table */
|
/* table */
|
||||||
@ -20620,8 +20641,8 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* "type" column */
|
/* "type" column */
|
||||||
item_list.push_back(new Item_string(join_type_str[tab->type],
|
item_list.push_back(new Item_string(join_type_str[tab_type],
|
||||||
strlen(join_type_str[tab->type]),
|
strlen(join_type_str[tab_type]),
|
||||||
cs));
|
cs));
|
||||||
/* Build "possible_keys" value and add it to item_list */
|
/* Build "possible_keys" value and add it to item_list */
|
||||||
if (!tab->keys.is_clear_all())
|
if (!tab->keys.is_clear_all())
|
||||||
@ -20645,7 +20666,7 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
item_list.push_back(item_null);
|
item_list.push_back(item_null);
|
||||||
|
|
||||||
/* Build "key", "key_len", and "ref" values and add them to item_list */
|
/* Build "key", "key_len", and "ref" values and add them to item_list */
|
||||||
if (tab->type == JT_NEXT)
|
if (tab_type == JT_NEXT)
|
||||||
{
|
{
|
||||||
key_info= table->key_info+tab->index;
|
key_info= table->key_info+tab->index;
|
||||||
key_len= key_info->key_length;
|
key_len= key_info->key_length;
|
||||||
@ -20674,12 +20695,12 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_hj && tab->type != JT_HASH)
|
if (is_hj && tab_type != JT_HASH)
|
||||||
{
|
{
|
||||||
tmp2.append(':');
|
tmp2.append(':');
|
||||||
tmp3.append(':');
|
tmp3.append(':');
|
||||||
}
|
}
|
||||||
if (tab->type == JT_HASH_NEXT)
|
if (tab_type == JT_HASH_NEXT)
|
||||||
{
|
{
|
||||||
register uint length;
|
register uint length;
|
||||||
key_info= table->key_info+tab->index;
|
key_info= table->key_info+tab->index;
|
||||||
@ -20701,7 +20722,7 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
|
item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
|
||||||
else
|
else
|
||||||
item_list.push_back(item_null);
|
item_list.push_back(item_null);
|
||||||
if (key_info && tab->type != JT_NEXT)
|
if (key_info && tab_type != JT_NEXT)
|
||||||
item_list.push_back(new Item_string(tmp4.ptr(),tmp4.length(),cs));
|
item_list.push_back(new Item_string(tmp4.ptr(),tmp4.length(),cs));
|
||||||
else
|
else
|
||||||
item_list.push_back(item_null);
|
item_list.push_back(item_null);
|
||||||
@ -20754,7 +20775,7 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
ha_rows examined_rows;
|
ha_rows examined_rows;
|
||||||
if (tab->select && tab->select->quick)
|
if (tab->select && tab->select->quick)
|
||||||
examined_rows= tab->select->quick->records;
|
examined_rows= tab->select->quick->records;
|
||||||
else if (tab->type == JT_NEXT || tab->type == JT_ALL || is_hj)
|
else if (tab_type == JT_NEXT || tab_type == JT_ALL || is_hj)
|
||||||
{
|
{
|
||||||
if (tab->limit)
|
if (tab->limit)
|
||||||
examined_rows= tab->limit;
|
examined_rows= tab->limit;
|
||||||
@ -20793,7 +20814,7 @@ int JOIN::print_explain(select_result_sink *result, bool on_the_fly,
|
|||||||
|
|
||||||
/* Build "Extra" field and add it to item_list. */
|
/* Build "Extra" field and add it to item_list. */
|
||||||
key_read=table->key_read;
|
key_read=table->key_read;
|
||||||
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
|
if ((tab_type == JT_NEXT || tab_type == JT_CONST) &&
|
||||||
table->covering_keys.is_set(tab->index))
|
table->covering_keys.is_set(tab->index))
|
||||||
key_read=1;
|
key_read=1;
|
||||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
|
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
|
||||||
|
Reference in New Issue
Block a user