EXPLAIN UPDATE/DELETE
- Make EXPLAIN UPDATE/DELETE work inside SPs - Return correct error code from mysql_delete() - EXPLAIN <multi-DELETE> will create a multi_delete object (as it affects the optimization). select_result will be only used for producing EXPLAIN output.
This commit is contained in:
parent
e8eeb2e7f9
commit
6519ca51dd
@ -49,7 +49,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
explain delete t1 from t0, t1 where t0.a = t1.a;
|
explain delete t1 from t0, t1 where t0.a = t1.a;
|
||||||
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 8 Using where
|
1 SIMPLE t0 ALL NULL NULL NULL NULL 8 Using where
|
||||||
1 SIMPLE t1 ref a a 5 test.t0.a 4 Using index
|
1 SIMPLE t1 ref a a 5 test.t0.a 4
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
# ###################################################################
|
# ###################################################################
|
||||||
# ## EXPLAIN UPDATE tests
|
# ## EXPLAIN UPDATE tests
|
||||||
|
@ -313,14 +313,26 @@ sp_get_flags_for_command(LEX *lex)
|
|||||||
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
|
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
|
||||||
break;
|
break;
|
||||||
case SQLCOM_DELETE:
|
case SQLCOM_DELETE:
|
||||||
|
case SQLCOM_DELETE_MULTI:
|
||||||
{
|
{
|
||||||
if (lex->select_lex.item_list.is_empty())
|
/*
|
||||||
|
DELETE normally doesn't return resultset, but there are two exceptions:
|
||||||
|
- DELETE ... RETURNING
|
||||||
|
- EXPLAIN DELETE ...
|
||||||
|
*/
|
||||||
|
if (lex->select_lex.item_list.is_empty() && !lex->describe)
|
||||||
flags= 0;
|
flags= 0;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* This is DELETE ... RETURNING ... */
|
|
||||||
flags= sp_head::MULTI_RESULTS;
|
flags= sp_head::MULTI_RESULTS;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case SQLCOM_UPDATE:
|
||||||
|
case SQLCOM_UPDATE_MULTI:
|
||||||
|
{
|
||||||
|
if (!lex->describe)
|
||||||
|
flags= 0;
|
||||||
|
else
|
||||||
|
flags= sp_head::MULTI_RESULTS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2988,7 +3000,6 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
reinit_stmt_before_use(thd, m_lex);
|
reinit_stmt_before_use(thd, m_lex);
|
||||||
// not here, but inside every instr: create_qpf_query(m_lex);
|
|
||||||
|
|
||||||
if (open_tables)
|
if (open_tables)
|
||||||
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
|
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
|
||||||
|
@ -183,7 +183,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
bool const_cond_result;
|
bool const_cond_result;
|
||||||
ha_rows deleted= 0;
|
ha_rows deleted= 0;
|
||||||
bool reverse= FALSE;
|
bool reverse= FALSE;
|
||||||
bool err= true;
|
|
||||||
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
|
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
|
||||||
order_list->first : NULL);
|
order_list->first : NULL);
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
@ -659,7 +658,7 @@ exit_without_my_ok:
|
|||||||
List<Item> dummy; /* note: looked in 5.6 and they too use a dummy list like this */
|
List<Item> dummy; /* note: looked in 5.6 and they too use a dummy list like this */
|
||||||
result2->prepare(dummy, &thd->lex->unit);
|
result2->prepare(dummy, &thd->lex->unit);
|
||||||
thd->send_explain_fields(result2);
|
thd->send_explain_fields(result2);
|
||||||
int err2= thd->lex->query_plan_footprint->print_explain(result2, 0 /* explain flags*/);
|
int err2= thd->lex->query_plan_footprint->print_explain(result2, thd->lex->describe);
|
||||||
|
|
||||||
if (err2)
|
if (err2)
|
||||||
result2->abort_result_set();
|
result2->abort_result_set();
|
||||||
@ -669,7 +668,7 @@ exit_without_my_ok:
|
|||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
//table->set_keyread(false);
|
//table->set_keyread(false);
|
||||||
DBUG_RETURN((err || thd->is_error() || thd->killed) ? 1 : 0);
|
DBUG_RETURN((err2 || thd->is_error() || thd->killed) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3332,18 +3332,7 @@ end_with_restore_list:
|
|||||||
|
|
||||||
if (!thd->is_fatal_error)
|
if (!thd->is_fatal_error)
|
||||||
{
|
{
|
||||||
if (explain)
|
|
||||||
{
|
|
||||||
result= new select_send();
|
|
||||||
if (thd->send_explain_fields(result))
|
|
||||||
{
|
|
||||||
delete result;
|
|
||||||
result= NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result= new multi_delete(aux_tables, lex->table_count);
|
result= new multi_delete(aux_tables, lex->table_count);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||||
@ -3362,20 +3351,22 @@ end_with_restore_list:
|
|||||||
if (!explain)
|
if (!explain)
|
||||||
{
|
{
|
||||||
MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
|
MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result->reset_offset_limit();
|
|
||||||
thd->lex->query_plan_footprint->print_explain(result,
|
|
||||||
thd->lex->describe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
|
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (explain)
|
if (!res)
|
||||||
result->send_eof();
|
{
|
||||||
|
select_result *result= new select_send();
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
if (thd->send_explain_fields(result) ||
|
||||||
|
lex->query_plan_footprint->print_explain(result, lex->describe) ||
|
||||||
|
result->send_eof())
|
||||||
|
res= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
|
||||||
}
|
}
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
@ -22990,10 +22990,13 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
|
|||||||
unit= unit->next_unit())
|
unit= unit->next_unit())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Display subqueries only if they are not parts of eliminated WHERE/ON
|
Display subqueries only if
|
||||||
clauses.
|
(1) they are not parts of ON clauses that were eliminated by table
|
||||||
|
elimination.
|
||||||
|
(2) they are not merged derived tables
|
||||||
*/
|
*/
|
||||||
if (!(unit->item && unit->item->eliminated))
|
if (!(unit->item && unit->item->eliminated) && // (1)
|
||||||
|
(!unit->derived || unit->derived->is_materialized_derived())) // (2)
|
||||||
{
|
{
|
||||||
qp_node->add_child(unit->first_select()->select_number);
|
qp_node->add_child(unit->first_select()->select_number);
|
||||||
}
|
}
|
||||||
|
@ -1039,8 +1039,8 @@ exit_without_my_ok:
|
|||||||
List<Item> dummy; /* note: looked in 5.6 and they too use a dummy list like this */
|
List<Item> dummy; /* note: looked in 5.6 and they too use a dummy list like this */
|
||||||
result->prepare(dummy, &thd->lex->unit);
|
result->prepare(dummy, &thd->lex->unit);
|
||||||
thd->send_explain_fields(result);
|
thd->send_explain_fields(result);
|
||||||
int err2= thd->lex->query_plan_footprint->print_explain(result, 0 /* explain flags*/);
|
int err2= thd->lex->query_plan_footprint->print_explain(result,
|
||||||
|
thd->lex->describe);
|
||||||
if (err2)
|
if (err2)
|
||||||
result->abort_result_set();
|
result->abort_result_set();
|
||||||
else
|
else
|
||||||
@ -1048,7 +1048,7 @@ exit_without_my_ok:
|
|||||||
|
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
|
DBUG_RETURN((err2 || thd->is_error()) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1518,7 +1518,7 @@ bool mysql_multi_update(THD *thd,
|
|||||||
{
|
{
|
||||||
if (explain)
|
if (explain)
|
||||||
{
|
{
|
||||||
thd->lex->query_plan_footprint->print_explain(output, 0);
|
thd->lex->query_plan_footprint->print_explain(output, thd->lex->describe);
|
||||||
output->send_eof();
|
output->send_eof();
|
||||||
delete output;
|
delete output;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user