summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/explain_non_select.result2
-rw-r--r--sql/sp_head.cc21
-rw-r--r--sql/sql_delete.cc5
-rw-r--r--sql/sql_parse.cc37
-rw-r--r--sql/sql_select.cc9
-rw-r--r--sql/sql_update.cc8
6 files changed, 43 insertions, 39 deletions
diff --git a/mysql-test/r/explain_non_select.result b/mysql-test/r/explain_non_select.result
index 7705ed29386..5597e6a876e 100644
--- a/mysql-test/r/explain_non_select.result
+++ b/mysql-test/r/explain_non_select.result
@@ -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
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0e69956e951..a3027763b8a 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -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);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 93de4fccf5e..25fe56d2e71 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 133485c3a68..71d68c6730d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f9f96321bf1..afa99a5cd24 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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);
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 15b3b9ad7e7..2881f6a7a1d 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -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;
}