diff options
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r-- | sql/sql_delete.cc | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ddb6af97865..5564d628594 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -33,7 +33,7 @@ */ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - SQL_LIST *order, ha_rows limit, ulonglong options, + SQL_I_List<ORDER> *order, ha_rows limit, ulonglong options, bool reset_auto_increment) { bool will_batch; @@ -84,7 +84,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (select_lex->setup_ref_array(thd, order->elements) || setup_order(thd, select_lex->ref_pointer_array, &tables, - fields, all_fields, (ORDER*) order->first)) + fields, all_fields, order->first)) { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); @@ -130,7 +130,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, - there should be no delete triggers associated with the table. */ if (!using_limit && const_cond_result && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && (thd->lex->sql_command == SQLCOM_TRUNCATE || (!thd->current_stmt_binlog_row_based && !(table->triggers && table->triggers->has_delete_triggers())))) @@ -230,14 +229,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ha_rows examined_rows; if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR) - usable_index= get_index_for_order(table, (ORDER*)(order->first), limit); + usable_index= get_index_for_order(table, order->first, limit); if (usable_index == MAX_KEY) { table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (!(sortorder= make_unireg_sortorder((ORDER*) order->first, + if (!(sortorder= make_unireg_sortorder(order->first, &length, NULL)) || (table->sort.found_records = filesort(thd, table, sortorder, length, select, HA_POS_ERROR, 1, @@ -248,6 +247,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(TRUE); } + thd->examined_row_count+= examined_rows; /* Filesort has already found and selected the rows we want to delete, so we don't need the where clause @@ -265,8 +265,15 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); DBUG_RETURN(TRUE); } - if (usable_index==MAX_KEY) - init_read_record(&info, thd, table, select, 1, 1, FALSE); + if (usable_index == MAX_KEY || (select && select->quick)) + { + if (init_read_record(&info, thd, table, select, 1, 1, FALSE)) + { + delete select; + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); + } + } else init_read_record_idx(&info, thd, table, 1, usable_index); @@ -304,6 +311,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, while (!(error=info.read_record(&info)) && !thd->killed && ! thd->is_error()) { + update_virtual_fields(thd, table); + thd->examined_row_count++; // thd->is_error() is tested to disallow delete row on error if (!select || select->skip_record(thd) > 0) { @@ -547,7 +556,7 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b) int mysql_multi_delete_prepare(THD *thd) { LEX *lex= thd->lex; - TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first; + TABLE_LIST *aux_tables= lex->auxiliary_table_list.first; TABLE_LIST *target_tbl; DBUG_ENTER("mysql_multi_delete_prepare"); @@ -943,7 +952,10 @@ int multi_delete::do_table_deletes(TABLE *table, bool ignore) READ_RECORD info; ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - init_read_record(&info, thd, table, NULL, 0, 1, FALSE); + + if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE)) + DBUG_RETURN(1); + /* Ignore any rows not found in reference tables as they may already have been deleted by foreign key handling |