diff options
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r-- | sql/sql_delete.cc | 70 |
1 files changed, 23 insertions, 47 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f4cad88124f..6a4ce266af2 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -199,23 +199,12 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root, &explain->mrr_type); } - bool skip= updating_a_view; - /* Save subquery children */ for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); unit; unit= unit->next_unit()) { - if (skip) - { - skip= false; - continue; - } - /* - Display subqueries only if they are not parts of eliminated WHERE/ON - clauses. - */ - if (!(unit->item && unit->item->eliminated)) + if (unit->explainable()) explain->add_child(unit->first_select()->select_number); } return 0; @@ -322,10 +311,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order= (ORDER *) ((order_list && order_list->elements) ? order_list->first : NULL); SELECT_LEX *select_lex= thd->lex->first_select_lex(); + SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0; killed_state killed_status= NOT_KILLED; THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE; bool binlog_is_row; - bool with_select= !select_lex->item_list.is_empty(); Explain_delete *explain; Delete_plan query_plan(thd->mem_root); Unique * deltempfile= NULL; @@ -365,18 +354,15 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->map=1; query_plan.select_lex= thd->lex->first_select_lex(); query_plan.table= table; - query_plan.updating_a_view= MY_TEST(table_list->view); - if (mysql_prepare_delete(thd, table_list, select_lex->with_wild, - select_lex->item_list, &conds, - &delete_while_scanning)) + if (mysql_prepare_delete(thd, table_list, &conds, &delete_while_scanning)) DBUG_RETURN(TRUE); if (delete_history) table->vers_write= false; - if (with_select) - (void) result->prepare(select_lex->item_list, NULL); + if (returning) + (void) result->prepare(returning->item_list, NULL); if (thd->lex->current_select->first_cond_optimization) { @@ -441,9 +427,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, has_triggers= table->triggers && table->triggers->has_delete_triggers(); - if (!with_select && !using_limit && const_cond_result && - (!thd->is_current_stmt_binlog_format_row() && - !has_triggers) + if (!returning && !using_limit && const_cond_result && + (!thd->is_current_stmt_binlog_format_row() && !has_triggers) && !table->versioned(VERS_TIMESTAMP) && !table_list->has_period()) { /* Update the table->file->stats.records number */ @@ -585,7 +570,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd))) goto got_error; - ANALYZE_START_TRACKING(&explain->command_tracker); + ANALYZE_START_TRACKING(thd, &explain->command_tracker); DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start", dbug_serve_apcs(thd, 1);); @@ -614,7 +599,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, */ if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) && - !has_triggers && !binlog_is_row && !with_select && + !has_triggers && !binlog_is_row && !returning && !table_list->has_period()) { table->mark_columns_needed_for_delete(); @@ -664,7 +649,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DELETE ... RETURNING we can't, because the RETURNING part may have a subquery in it) */ - if (!with_select) + if (!returning) free_underlaid_joins(thd, select_lex); select= 0; } @@ -699,11 +684,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, !table->prepare_triggers_for_delete_stmt_or_event()) will_batch= !table->file->start_bulk_delete(); - if (with_select) + if (returning) { - if (unlikely(result->send_result_set_metadata(select_lex->item_list, - Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF))) + if (result->send_result_set_metadata(returning->item_list, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) goto cleanup; } @@ -785,7 +769,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, break; } - if (with_select && result->send_data(select_lex->item_list) < 0) + // no LIMIT / OFFSET + if (returning && result->send_data(returning->item_list) < 0) { error=1; break; @@ -863,7 +848,7 @@ terminate_delete: table->file->ha_release_auto_increment(); if (options & OPTION_QUICK) (void) table->file->extra(HA_EXTRA_NORMAL); - ANALYZE_STOP_TRACKING(&explain->command_tracker); + ANALYZE_STOP_TRACKING(thd, &explain->command_tracker); cleanup: /* @@ -929,7 +914,7 @@ cleanup: if (thd->lex->analyze_stmt) goto send_nothing_and_leave; - if (with_select) + if (returning) result->send_eof(); else my_ok(thd, deleted); @@ -979,16 +964,13 @@ got_error: mysql_prepare_delete() thd - thread handler table_list - global/local table list - wild_num - number of wildcards used in optional SELECT clause - field_list - list of items in optional SELECT clause conds - conditions RETURN VALUE FALSE OK TRUE error */ -int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, - uint wild_num, List<Item> &field_list, Item **conds, +int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds, bool *delete_while_scanning) { Item *fake_conds= 0; @@ -998,12 +980,9 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, *delete_while_scanning= true; thd->lex->allow_sum_func.clear_all(); - if (setup_tables_and_check_access(thd, - &thd->lex->first_select_lex()->context, - &thd->lex->first_select_lex()-> - top_join_list, - table_list, - select_lex->leaf_tables, FALSE, + if (setup_tables_and_check_access(thd, &select_lex->context, + &select_lex->top_join_list, table_list, + select_lex->leaf_tables, FALSE, DELETE_ACL, SELECT_ACL, TRUE)) DBUG_RETURN(TRUE); @@ -1034,10 +1013,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, *conds= select_lex->where; - if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num, - &select_lex->hidden_bit_fields)) || - setup_fields(thd, Ref_ptr_array(), - field_list, MARK_COLUMNS_READ, NULL, NULL, 0) || + if (setup_returning_fields(thd, table_list) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); @@ -1061,7 +1037,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) DBUG_RETURN(TRUE); - select_lex->fix_prepare_information(thd, conds, &fake_conds); + select_lex->fix_prepare_information(thd, conds, &fake_conds); DBUG_RETURN(FALSE); } |