summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc30
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