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;
|
||||
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 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;
|
||||
# ###################################################################
|
||||
# ## EXPLAIN UPDATE tests
|
||||
|
@ -313,14 +313,26 @@ sp_get_flags_for_command(LEX *lex)
|
||||
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
|
||||
break;
|
||||
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;
|
||||
else
|
||||
flags= sp_head::MULTI_RESULTS;
|
||||
break;
|
||||
}
|
||||
case SQLCOM_UPDATE:
|
||||
case SQLCOM_UPDATE_MULTI:
|
||||
{
|
||||
if (!lex->describe)
|
||||
flags= 0;
|
||||
else
|
||||
{
|
||||
/* This is DELETE ... RETURNING ... */
|
||||
flags= sp_head::MULTI_RESULTS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -2988,7 +3000,6 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
||||
}
|
||||
|
||||
reinit_stmt_before_use(thd, m_lex);
|
||||
// not here, but inside every instr: create_qpf_query(m_lex);
|
||||
|
||||
if (open_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;
|
||||
ha_rows deleted= 0;
|
||||
bool reverse= FALSE;
|
||||
bool err= true;
|
||||
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
|
||||
order_list->first : NULL);
|
||||
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 */
|
||||
result2->prepare(dummy, &thd->lex->unit);
|
||||
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)
|
||||
result2->abort_result_set();
|
||||
@ -669,7 +668,7 @@ exit_without_my_ok:
|
||||
delete select;
|
||||
free_underlaid_joins(thd, select_lex);
|
||||
//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 (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)
|
||||
{
|
||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||
@ -3362,20 +3351,22 @@ end_with_restore_list:
|
||||
if (!explain)
|
||||
{
|
||||
MYSQL_MULTI_DELETE_DONE(res, del_result->num_deleted());
|
||||
if (res)
|
||||
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
|
||||
}
|
||||
else
|
||||
{
|
||||
result->reset_offset_limit();
|
||||
thd->lex->query_plan_footprint->print_explain(result,
|
||||
thd->lex->describe);
|
||||
}
|
||||
|
||||
if (res)
|
||||
result->abort_result_set(); /* for both DELETE and EXPLAIN DELETE */
|
||||
else
|
||||
{
|
||||
if (explain)
|
||||
result->send_eof();
|
||||
if (!res)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -22990,10 +22990,13 @@ int JOIN::save_qpf(QPF_query *output, bool need_tmp_table, bool need_order,
|
||||
unit= unit->next_unit())
|
||||
{
|
||||
/*
|
||||
Display subqueries only if they are not parts of eliminated WHERE/ON
|
||||
clauses.
|
||||
Display subqueries only if
|
||||
(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);
|
||||
}
|
||||
|
@ -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 */
|
||||
result->prepare(dummy, &thd->lex->unit);
|
||||
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)
|
||||
result->abort_result_set();
|
||||
else
|
||||
@ -1048,7 +1048,7 @@ exit_without_my_ok:
|
||||
|
||||
delete select;
|
||||
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)
|
||||
{
|
||||
thd->lex->query_plan_footprint->print_explain(output, 0);
|
||||
thd->lex->query_plan_footprint->print_explain(output, thd->lex->describe);
|
||||
output->send_eof();
|
||||
delete output;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user