diff options
-rw-r--r-- | mysql-test/r/explain_non_select.result | 2 | ||||
-rw-r--r-- | sql/sp_head.cc | 21 | ||||
-rw-r--r-- | sql/sql_delete.cc | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 37 | ||||
-rw-r--r-- | sql/sql_select.cc | 9 | ||||
-rw-r--r-- | sql/sql_update.cc | 8 |
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; } |