mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-3798: EXPLAIN UPDATE/DELETE
Update the SHOW EXPLAIN code to work with the new architecture (part#1): Before, SHOW EXPLAIN operated on real query plan structures, which meant it had to check when SELECTs are created/deleted. SELECTs would call apc_target->enable() when they got a query plan and disable() when their query plan was deleted. Now, Explain data structure becomes available at once (and we call apc_target->enable()) and then it stays until it is deleted (when that happens, we call apc_target->disable()).
This commit is contained in:
@ -181,6 +181,8 @@ 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: Target is not running an EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
|
kill query $thr2;
|
||||||
|
ERROR 70100: Query execution was interrupted
|
||||||
set debug_dbug=@old_debug;
|
set debug_dbug=@old_debug;
|
||||||
#
|
#
|
||||||
# Attempt SHOW EXPLAIN for an UPDATE
|
# Attempt SHOW EXPLAIN for an UPDATE
|
||||||
@ -405,13 +407,8 @@ 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: Target is not running an EXPLAINable command
|
ERROR HY000: Target is not running an EXPLAINable command
|
||||||
a b
|
kill query $thr2;
|
||||||
8 4
|
ERROR 70100: Query execution was interrupted
|
||||||
8 5
|
|
||||||
8 6
|
|
||||||
8 7
|
|
||||||
8 8
|
|
||||||
8 9
|
|
||||||
set debug_dbug=@old_debug;
|
set debug_dbug=@old_debug;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t2, t3;
|
DROP TABLE t2, t3;
|
||||||
|
@ -224,7 +224,9 @@ connection default;
|
|||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_TARGET_NOT_EXPLAINABLE
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
|
evalp kill query $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
|
--error ER_QUERY_INTERRUPTED
|
||||||
reap;
|
reap;
|
||||||
set debug_dbug=@old_debug;
|
set debug_dbug=@old_debug;
|
||||||
|
|
||||||
@ -399,7 +401,9 @@ connection default;
|
|||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--error ER_TARGET_NOT_EXPLAINABLE
|
--error ER_TARGET_NOT_EXPLAINABLE
|
||||||
evalp show explain for $thr2;
|
evalp show explain for $thr2;
|
||||||
|
evalp kill query $thr2;
|
||||||
connection con1;
|
connection con1;
|
||||||
|
--error ER_QUERY_INTERRUPTED
|
||||||
reap;
|
reap;
|
||||||
set debug_dbug=@old_debug;
|
set debug_dbug=@old_debug;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
|
@ -3037,7 +3037,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
else if (! thd->in_sub_stmt)
|
else if (! thd->in_sub_stmt)
|
||||||
thd->mdl_context.release_statement_locks();
|
thd->mdl_context.release_statement_locks();
|
||||||
}
|
}
|
||||||
|
//TODO: why is this here if log_slow_query is in sp_instr_stmt_execute?
|
||||||
delete_explain_query(m_lex);
|
delete_explain_query(m_lex);
|
||||||
|
|
||||||
if (m_lex->query_tables_own_last)
|
if (m_lex->query_tables_own_last)
|
||||||
|
@ -67,7 +67,7 @@ void Delete_plan::save_explain_data(Explain_query *query)
|
|||||||
Update_plan::save_explain_data_intern(query, explain);
|
Update_plan::save_explain_data_intern(query, explain);
|
||||||
}
|
}
|
||||||
|
|
||||||
query->upd_del_plan= explain;
|
query->add_upd_del_plan(explain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ void Update_plan::save_explain_data(Explain_query *query)
|
|||||||
{
|
{
|
||||||
Explain_update* explain= new Explain_update;
|
Explain_update* explain= new Explain_update;
|
||||||
save_explain_data_intern(query, explain);
|
save_explain_data_intern(query, explain);
|
||||||
query->upd_del_plan= explain;
|
query->add_upd_del_plan(explain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -459,7 +459,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
goto exit_without_my_ok;
|
goto exit_without_my_ok;
|
||||||
|
|
||||||
query_plan.save_explain_data(thd->lex->explain);
|
query_plan.save_explain_data(thd->lex->explain);
|
||||||
thd->apc_target.enable();
|
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
|
DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
|
||||||
dbug_serve_apcs(thd, 1););
|
dbug_serve_apcs(thd, 1););
|
||||||
@ -486,7 +485,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
{
|
{
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||||
thd->apc_target.disable();
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
thd->examined_row_count+= examined_rows;
|
thd->examined_row_count+= examined_rows;
|
||||||
@ -505,7 +503,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
{
|
{
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
thd->apc_target.disable();
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
if (query_plan.index == MAX_KEY || (select && select->quick))
|
if (query_plan.index == MAX_KEY || (select && select->quick))
|
||||||
@ -514,7 +511,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
{
|
{
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
thd->apc_target.disable();
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -624,7 +620,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
if (options & OPTION_QUICK)
|
if (options & OPTION_QUICK)
|
||||||
(void) table->file->extra(HA_EXTRA_NORMAL);
|
(void) table->file->extra(HA_EXTRA_NORMAL);
|
||||||
|
|
||||||
thd->apc_target.disable();
|
|
||||||
cleanup:
|
cleanup:
|
||||||
/*
|
/*
|
||||||
Invalidate the table in the query cache if something changed. This must
|
Invalidate the table in the query cache if something changed. This must
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
|
|
||||||
|
|
||||||
Explain_query::Explain_query() : upd_del_plan(NULL), insert_plan(NULL)
|
Explain_query::Explain_query(THD *thd_arg) :
|
||||||
|
upd_del_plan(NULL), insert_plan(NULL), thd(thd_arg), apc_enabled(false)
|
||||||
{
|
{
|
||||||
operations= 0;
|
operations= 0;
|
||||||
}
|
}
|
||||||
@ -30,6 +31,9 @@ Explain_query::Explain_query() : upd_del_plan(NULL), insert_plan(NULL)
|
|||||||
|
|
||||||
Explain_query::~Explain_query()
|
Explain_query::~Explain_query()
|
||||||
{
|
{
|
||||||
|
if (apc_enabled)
|
||||||
|
thd->apc_target.disable();
|
||||||
|
|
||||||
delete upd_del_plan;
|
delete upd_del_plan;
|
||||||
delete insert_plan;
|
delete insert_plan;
|
||||||
uint i;
|
uint i;
|
||||||
@ -62,11 +66,12 @@ Explain_select *Explain_query::get_select(uint select_id)
|
|||||||
|
|
||||||
void Explain_query::add_node(Explain_node *node)
|
void Explain_query::add_node(Explain_node *node)
|
||||||
{
|
{
|
||||||
|
uint select_id;
|
||||||
operations++;
|
operations++;
|
||||||
if (node->get_type() == Explain_node::EXPLAIN_UNION)
|
if (node->get_type() == Explain_node::EXPLAIN_UNION)
|
||||||
{
|
{
|
||||||
Explain_union *u= (Explain_union*)node;
|
Explain_union *u= (Explain_union*)node;
|
||||||
uint select_id= u->get_select_id();
|
select_id= u->get_select_id();
|
||||||
if (unions.elements() <= select_id)
|
if (unions.elements() <= select_id)
|
||||||
unions.resize(max(select_id+1, unions.elements()*2), NULL);
|
unions.resize(max(select_id+1, unions.elements()*2), NULL);
|
||||||
|
|
||||||
@ -85,7 +90,7 @@ void Explain_query::add_node(Explain_node *node)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint select_id= sel->select_id;
|
select_id= sel->select_id;
|
||||||
Explain_select *old_node;
|
Explain_select *old_node;
|
||||||
|
|
||||||
if (selects.elements() <= select_id)
|
if (selects.elements() <= select_id)
|
||||||
@ -100,6 +105,27 @@ void Explain_query::add_node(Explain_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Explain_query::add_insert_plan(Explain_insert *insert_plan_arg)
|
||||||
|
{
|
||||||
|
insert_plan= insert_plan_arg;
|
||||||
|
query_plan_ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Explain_query::add_upd_del_plan(Explain_update *upd_del_plan_arg)
|
||||||
|
{
|
||||||
|
upd_del_plan= upd_del_plan_arg;
|
||||||
|
query_plan_ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Explain_query::query_plan_ready()
|
||||||
|
{
|
||||||
|
if (!apc_enabled)
|
||||||
|
thd->apc_target.enable();
|
||||||
|
apc_enabled= true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Send EXPLAIN output to the client.
|
Send EXPLAIN output to the client.
|
||||||
*/
|
*/
|
||||||
@ -915,7 +941,7 @@ void delete_explain_query(LEX *lex)
|
|||||||
void create_explain_query(LEX *lex, MEM_ROOT *mem_root)
|
void create_explain_query(LEX *lex, MEM_ROOT *mem_root)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!lex->explain);
|
DBUG_ASSERT(!lex->explain);
|
||||||
lex->explain= new Explain_query;
|
lex->explain= new Explain_query(lex->thd);
|
||||||
DBUG_ASSERT(mem_root == current_thd->mem_root);
|
DBUG_ASSERT(mem_root == current_thd->mem_root);
|
||||||
lex->explain->mem_root= mem_root;
|
lex->explain->mem_root= mem_root;
|
||||||
}
|
}
|
||||||
|
@ -221,10 +221,13 @@ class Explain_insert;
|
|||||||
class Explain_query : public Sql_alloc
|
class Explain_query : public Sql_alloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Explain_query();
|
Explain_query(THD *thd);
|
||||||
~Explain_query();
|
~Explain_query();
|
||||||
|
|
||||||
/* Add a new node */
|
/* Add a new node */
|
||||||
void add_node(Explain_node *node);
|
void add_node(Explain_node *node);
|
||||||
|
void add_insert_plan(Explain_insert *insert_plan_arg);
|
||||||
|
void add_upd_del_plan(Explain_update *upd_del_plan_arg);
|
||||||
|
|
||||||
/* This will return a select, or a union */
|
/* This will return a select, or a union */
|
||||||
Explain_node *get_node(uint select_id);
|
Explain_node *get_node(uint select_id);
|
||||||
@ -234,12 +237,6 @@ public:
|
|||||||
|
|
||||||
Explain_union *get_union(uint select_id);
|
Explain_union *get_union(uint select_id);
|
||||||
|
|
||||||
/* Explain_delete inherits from Explain_update */
|
|
||||||
Explain_update *upd_del_plan;
|
|
||||||
|
|
||||||
/* Query "plan" for INSERTs */
|
|
||||||
Explain_insert *insert_plan;
|
|
||||||
|
|
||||||
/* Produce a tabular EXPLAIN output */
|
/* Produce a tabular EXPLAIN output */
|
||||||
int print_explain(select_result_sink *output, uint8 explain_flags);
|
int print_explain(select_result_sink *output, uint8 explain_flags);
|
||||||
|
|
||||||
@ -251,11 +248,22 @@ public:
|
|||||||
|
|
||||||
/* If true, at least part of EXPLAIN can be printed */
|
/* If true, at least part of EXPLAIN can be printed */
|
||||||
bool have_query_plan() { return insert_plan || upd_del_plan|| get_node(1) != NULL; }
|
bool have_query_plan() { return insert_plan || upd_del_plan|| get_node(1) != NULL; }
|
||||||
|
|
||||||
|
void query_plan_ready();
|
||||||
|
|
||||||
MEM_ROOT *mem_root;
|
MEM_ROOT *mem_root;
|
||||||
private:
|
private:
|
||||||
|
/* Explain_delete inherits from Explain_update */
|
||||||
|
Explain_update *upd_del_plan;
|
||||||
|
|
||||||
|
/* Query "plan" for INSERTs */
|
||||||
|
Explain_insert *insert_plan;
|
||||||
|
|
||||||
Dynamic_array<Explain_union*> unions;
|
Dynamic_array<Explain_union*> unions;
|
||||||
Dynamic_array<Explain_select*> selects;
|
Dynamic_array<Explain_select*> selects;
|
||||||
|
|
||||||
|
THD *thd; // for APC start/stop
|
||||||
|
bool apc_enabled;
|
||||||
/*
|
/*
|
||||||
Debugging aid: count how many times add_node() was called. Ideally, it
|
Debugging aid: count how many times add_node() was called. Ideally, it
|
||||||
should be one, we currently allow O(1) query plan saves for each
|
should be one, we currently allow O(1) query plan saves for each
|
||||||
|
@ -461,7 +461,8 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
|
|||||||
if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) ||
|
if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) ||
|
||||||
thd->variables.max_insert_delayed_threads == 0 ||
|
thd->variables.max_insert_delayed_threads == 0 ||
|
||||||
thd->locked_tables_mode > LTM_LOCK_TABLES ||
|
thd->locked_tables_mode > LTM_LOCK_TABLES ||
|
||||||
thd->lex->uses_stored_routines())
|
thd->lex->uses_stored_routines() /*||
|
||||||
|
thd->lex->describe*/)
|
||||||
{
|
{
|
||||||
*lock_type= TL_WRITE;
|
*lock_type= TL_WRITE;
|
||||||
return;
|
return;
|
||||||
@ -649,7 +650,7 @@ static void save_insert_query_plan(THD* thd, TABLE_LIST *table_list)
|
|||||||
Explain_insert* explain= new Explain_insert;
|
Explain_insert* explain= new Explain_insert;
|
||||||
explain->table_name.append(table_list->table->alias);
|
explain->table_name.append(table_list->table->alias);
|
||||||
|
|
||||||
thd->lex->explain->insert_plan= explain;
|
thd->lex->explain->add_insert_plan(explain);
|
||||||
|
|
||||||
/* See Update_plan::updating_a_view for details */
|
/* See Update_plan::updating_a_view for details */
|
||||||
bool skip= test(table_list->view);
|
bool skip= test(table_list->view);
|
||||||
|
@ -4276,11 +4276,15 @@ int st_select_lex_unit::save_union_explain(Explain_query *output)
|
|||||||
for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
|
for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
|
||||||
eu->add_select(sl->select_number);
|
eu->add_select(sl->select_number);
|
||||||
|
|
||||||
|
eu->fake_select_type= "UNION RESULT";
|
||||||
|
eu->using_filesort= test(global_parameters->order_list.first);
|
||||||
|
|
||||||
// Save the UNION node
|
// Save the UNION node
|
||||||
output->add_node(eu);
|
output->add_node(eu);
|
||||||
|
|
||||||
eu->fake_select_type= "UNION RESULT";
|
if (eu->get_select_id() == 1)
|
||||||
eu->using_filesort= test(global_parameters->order_list.first);
|
output->query_plan_ready();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,6 +1031,10 @@ public:
|
|||||||
|
|
||||||
void clear_index_hints(void) { index_hints= NULL; }
|
void clear_index_hints(void) { index_hints= NULL; }
|
||||||
bool is_part_of_union() { return master_unit()->is_union(); }
|
bool is_part_of_union() { return master_unit()->is_union(); }
|
||||||
|
bool is_top_level_node()
|
||||||
|
{
|
||||||
|
return (select_number == 1) && !is_part_of_union();
|
||||||
|
}
|
||||||
bool optimize_unflattened_subqueries(bool const_only);
|
bool optimize_unflattened_subqueries(bool const_only);
|
||||||
/* Set the EXPLAIN type for this subquery. */
|
/* Set the EXPLAIN type for this subquery. */
|
||||||
void set_explain_type(bool on_the_fly);
|
void set_explain_type(bool on_the_fly);
|
||||||
|
@ -2298,8 +2298,6 @@ JOIN::save_join_tab()
|
|||||||
void join_save_qpf(JOIN *join)
|
void join_save_qpf(JOIN *join)
|
||||||
{
|
{
|
||||||
THD *thd= join->thd;
|
THD *thd= join->thd;
|
||||||
//TODO: why not call st_select_lex::save_qpf here?
|
|
||||||
|
|
||||||
if (join->select_lex->select_number != UINT_MAX &&
|
if (join->select_lex->select_number != UINT_MAX &&
|
||||||
join->select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
|
join->select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ &&
|
||||||
join->have_query_plan != JOIN::QEP_NOT_PRESENT_YET &&
|
join->have_query_plan != JOIN::QEP_NOT_PRESENT_YET &&
|
||||||
@ -2328,7 +2326,6 @@ void join_save_qpf(JOIN *join)
|
|||||||
|
|
||||||
void JOIN::exec()
|
void JOIN::exec()
|
||||||
{
|
{
|
||||||
thd->apc_target.enable();
|
|
||||||
DBUG_EXECUTE_IF("show_explain_probe_join_exec_start",
|
DBUG_EXECUTE_IF("show_explain_probe_join_exec_start",
|
||||||
if (dbug_user_var_equals_int(thd,
|
if (dbug_user_var_equals_int(thd,
|
||||||
"show_explain_probe_select_id",
|
"show_explain_probe_select_id",
|
||||||
@ -2368,7 +2365,6 @@ void JOIN::exec()
|
|||||||
select_lex->select_number))
|
select_lex->select_number))
|
||||||
dbug_serve_apcs(thd, 1);
|
dbug_serve_apcs(thd, 1);
|
||||||
);
|
);
|
||||||
thd->apc_target.disable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -22997,6 +22993,10 @@ int JOIN::save_explain_data(Explain_query *output, bool need_tmp_table,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!error && select_lex->is_top_level_node())
|
||||||
|
output->query_plan_ready();
|
||||||
|
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,6 @@ int mysql_update(THD *thd,
|
|||||||
Update_plan query_plan(thd->mem_root);
|
Update_plan query_plan(thd->mem_root);
|
||||||
query_plan.index= MAX_KEY;
|
query_plan.index= MAX_KEY;
|
||||||
query_plan.using_filesort= FALSE;
|
query_plan.using_filesort= FALSE;
|
||||||
bool apc_target_enabled= false; // means was enabled *by code this function*
|
|
||||||
DBUG_ENTER("mysql_update");
|
DBUG_ENTER("mysql_update");
|
||||||
|
|
||||||
if (open_tables(thd, &table_list, &table_count, 0))
|
if (open_tables(thd, &table_list, &table_count, 0))
|
||||||
@ -518,8 +517,6 @@ int mysql_update(THD *thd,
|
|||||||
goto exit_without_my_ok;
|
goto exit_without_my_ok;
|
||||||
query_plan.save_explain_data(thd->lex->explain);
|
query_plan.save_explain_data(thd->lex->explain);
|
||||||
|
|
||||||
thd->apc_target.enable();
|
|
||||||
apc_target_enabled= true;
|
|
||||||
DBUG_EXECUTE_IF("show_explain_probe_update_exec_start",
|
DBUG_EXECUTE_IF("show_explain_probe_update_exec_start",
|
||||||
dbug_serve_apcs(thd, 1););
|
dbug_serve_apcs(thd, 1););
|
||||||
|
|
||||||
@ -960,8 +957,6 @@ int mysql_update(THD *thd,
|
|||||||
if (!transactional_table && updated > 0)
|
if (!transactional_table && updated > 0)
|
||||||
thd->transaction.stmt.modified_non_trans_table= TRUE;
|
thd->transaction.stmt.modified_non_trans_table= TRUE;
|
||||||
|
|
||||||
thd->apc_target.disable();
|
|
||||||
apc_target_enabled= false;
|
|
||||||
end_read_record(&info);
|
end_read_record(&info);
|
||||||
delete select;
|
delete select;
|
||||||
thd_proc_info(thd, "end");
|
thd_proc_info(thd, "end");
|
||||||
@ -1035,8 +1030,6 @@ int mysql_update(THD *thd,
|
|||||||
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
|
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (apc_target_enabled)
|
|
||||||
thd->apc_target.disable();
|
|
||||||
|
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
@ -1045,7 +1038,6 @@ err:
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
exit_without_my_ok:
|
exit_without_my_ok:
|
||||||
DBUG_ASSERT(!apc_target_enabled);
|
|
||||||
query_plan.save_explain_data(thd->lex->explain);
|
query_plan.save_explain_data(thd->lex->explain);
|
||||||
|
|
||||||
int err2= thd->lex->explain->send_explain(thd);
|
int err2= thd->lex->explain->send_explain(thd);
|
||||||
|
Reference in New Issue
Block a user