1/*
2 Copyright (c) 2000, 2010, Oracle and/or its affiliates.
3 Copyright (c) 2010, 2015, MariaDB
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
18/*
19 Delete of records tables.
20
21 Multi-table deletes were introduced by Monty and Sinisa
22*/
23
24#include "mariadb.h"
25#include "sql_priv.h"
26#include "unireg.h"
27#include "sql_delete.h"
28#include "sql_cache.h" // query_cache_*
29#include "sql_base.h" // open_temprary_table
30#include "lock.h" // unlock_table_name
31#include "sql_view.h" // check_key_in_view, mysql_frm_type
32#include "sql_parse.h" // mysql_init_select
33#include "sql_acl.h" // *_ACL
34#include "filesort.h" // filesort
35#include "sql_handler.h" // mysql_ha_rm_tables
36#include "sql_select.h"
37#include "sp_head.h"
38#include "sql_trigger.h"
39#include "sql_statistics.h"
40#include "transaction.h"
41#include "records.h" // init_read_record,
42#include "filesort.h"
43#include "uniques.h"
44#include "sql_derived.h" // mysql_handle_list_of_derived
45 // end_read_record
46#include "sql_partition.h" // make_used_partitions_str
47
48#define MEM_STRIP_BUF_SIZE ((size_t) thd->variables.sortbuff_size)
49
50/*
51 @brief
52 Print query plan of a single-table DELETE command
53
54 @detail
55 This function is used by EXPLAIN DELETE and by SHOW EXPLAIN when it is
56 invoked on a running DELETE statement.
57*/
58
59Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *thd)
60{
61 Explain_query *query= thd->lex->explain;
62 Explain_delete *explain=
63 new (mem_root) Explain_delete(mem_root, thd->lex->analyze_stmt);
64 if (!explain)
65 return 0;
66
67 if (deleting_all_rows)
68 {
69 explain->deleting_all_rows= true;
70 explain->select_type= "SIMPLE";
71 explain->rows= scanned_rows;
72 }
73 else
74 {
75 explain->deleting_all_rows= false;
76 if (Update_plan::save_explain_data_intern(mem_root, explain,
77 thd->lex->analyze_stmt))
78 return 0;
79 }
80
81 query->add_upd_del_plan(explain);
82 return explain;
83}
84
85
86Explain_update*
87Update_plan::save_explain_update_data(MEM_ROOT *mem_root, THD *thd)
88{
89 Explain_query *query= thd->lex->explain;
90 Explain_update* explain=
91 new (mem_root) Explain_update(mem_root, thd->lex->analyze_stmt);
92 if (!explain)
93 return 0;
94 if (save_explain_data_intern(mem_root, explain, thd->lex->analyze_stmt))
95 return 0;
96 query->add_upd_del_plan(explain);
97 return explain;
98}
99
100
101bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
102 Explain_update *explain,
103 bool is_analyze)
104{
105 explain->select_type= "SIMPLE";
106 explain->table_name.append(&table->pos_in_table_list->alias);
107
108 explain->impossible_where= false;
109 explain->no_partitions= false;
110
111 if (impossible_where)
112 {
113 explain->impossible_where= true;
114 return 0;
115 }
116
117 if (no_partitions)
118 {
119 explain->no_partitions= true;
120 return 0;
121 }
122
123 if (is_analyze)
124 table->file->set_time_tracker(&explain->table_tracker);
125
126 select_lex->set_explain_type(TRUE);
127 explain->select_type= select_lex->type;
128 /* Partitions */
129 {
130#ifdef WITH_PARTITION_STORAGE_ENGINE
131 partition_info *part_info;
132 if ((part_info= table->part_info))
133 {
134 make_used_partitions_str(mem_root, part_info, &explain->used_partitions,
135 explain->used_partitions_list);
136 explain->used_partitions_set= true;
137 }
138 else
139 explain->used_partitions_set= false;
140#else
141 /* just produce empty column if partitioning is not compiled in */
142 explain->used_partitions_set= false;
143#endif
144 }
145
146
147 /* Set jtype */
148 if (select && select->quick)
149 {
150 int quick_type= select->quick->get_type();
151 if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
152 (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) ||
153 (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
154 (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
155 explain->jtype= JT_INDEX_MERGE;
156 else
157 explain->jtype= JT_RANGE;
158 }
159 else
160 {
161 if (index == MAX_KEY)
162 explain->jtype= JT_ALL;
163 else
164 explain->jtype= JT_NEXT;
165 }
166
167 explain->using_where= MY_TEST(select && select->cond);
168 explain->where_cond= select? select->cond: NULL;
169
170 if (using_filesort)
171 if (!(explain->filesort_tracker= new (mem_root) Filesort_tracker(is_analyze)))
172 return 1;
173 explain->using_io_buffer= using_io_buffer;
174
175 append_possible_keys(mem_root, explain->possible_keys, table,
176 possible_keys);
177
178 explain->quick_info= NULL;
179
180 /* Calculate key_len */
181 if (select && select->quick)
182 {
183 explain->quick_info= select->quick->get_explain(mem_root);
184 }
185 else
186 {
187 if (index != MAX_KEY)
188 {
189 explain->key.set(mem_root, &table->key_info[index],
190 table->key_info[index].key_length);
191 }
192 }
193 explain->rows= scanned_rows;
194
195 if (select && select->quick &&
196 select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
197 {
198 explain_append_mrr_info((QUICK_RANGE_SELECT*)select->quick,
199 &explain->mrr_type);
200 }
201
202 bool skip= updating_a_view;
203
204 /* Save subquery children */
205 for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit();
206 unit;
207 unit= unit->next_unit())
208 {
209 if (skip)
210 {
211 skip= false;
212 continue;
213 }
214 /*
215 Display subqueries only if they are not parts of eliminated WHERE/ON
216 clauses.
217 */
218 if (!(unit->item && unit->item->eliminated))
219 explain->add_child(unit->first_select()->select_number);
220 }
221 return 0;
222}
223
224
225static bool record_should_be_deleted(THD *thd, TABLE *table, SQL_SELECT *sel,
226 Explain_delete *explain, bool truncate_history)
227{
228 bool check_delete= true;
229
230 if (table->versioned())
231 {
232 bool historical= !table->vers_end_field()->is_max();
233 check_delete= truncate_history ? historical : !historical;
234 }
235
236 explain->tracker.on_record_read();
237 thd->inc_examined_row_count(1);
238 if (table->vfield)
239 (void) table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_DELETE);
240 if (check_delete && (!sel || sel->skip_record(thd) > 0))
241 {
242 explain->tracker.on_record_after_where();
243 return true;
244 }
245 return false;
246}
247
248
249inline
250int TABLE::delete_row()
251{
252 if (!versioned(VERS_TIMESTAMP) || !vers_end_field()->is_max())
253 return file->ha_delete_row(record[0]);
254
255 store_record(this, record[1]);
256 vers_update_end();
257 return file->ha_update_row(record[1], record[0]);
258}
259
260
261/**
262 Implement DELETE SQL word.
263
264 @note Like implementations of other DDL/DML in MySQL, this function
265 relies on the caller to close the thread tables. This is done in the
266 end of dispatch_command().
267*/
268
269bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
270 SQL_I_List<ORDER> *order_list, ha_rows limit,
271 ulonglong options, select_result *result)
272{
273 bool will_batch= FALSE;
274 int error, loc_error;
275 TABLE *table;
276 SQL_SELECT *select=0;
277 SORT_INFO *file_sort= 0;
278 READ_RECORD info;
279 bool using_limit=limit != HA_POS_ERROR;
280 bool transactional_table, safe_update, const_cond;
281 bool const_cond_result;
282 bool return_error= 0;
283 ha_rows deleted= 0;
284 bool reverse= FALSE;
285 bool has_triggers;
286 ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
287 order_list->first : NULL);
288 SELECT_LEX *select_lex= &thd->lex->select_lex;
289 killed_state killed_status= NOT_KILLED;
290 THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
291 bool binlog_is_row;
292 bool with_select= !select_lex->item_list.is_empty();
293 Explain_delete *explain;
294 Delete_plan query_plan(thd->mem_root);
295 Unique * deltempfile= NULL;
296 bool delete_record, delete_while_scanning;
297 DBUG_ENTER("mysql_delete");
298
299 query_plan.index= MAX_KEY;
300 query_plan.using_filesort= FALSE;
301
302 create_explain_query(thd->lex, thd->mem_root);
303 if (open_and_lock_tables(thd, table_list, TRUE, 0))
304 DBUG_RETURN(TRUE);
305
306 THD_STAGE_INFO(thd, stage_init_update);
307
308 bool truncate_history= table_list->vers_conditions.is_set();
309 if (truncate_history)
310 {
311 if (table_list->is_view_or_derived())
312 {
313 my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
314 DBUG_RETURN(true);
315 }
316
317 TABLE *table= table_list->table;
318 DBUG_ASSERT(table);
319
320 DBUG_ASSERT(!conds || thd->stmt_arena->is_stmt_execute());
321 if (select_lex->vers_setup_conds(thd, table_list))
322 DBUG_RETURN(TRUE);
323
324 DBUG_ASSERT(!conds);
325 conds= table_list->on_expr;
326 table_list->on_expr= NULL;
327 }
328
329 if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
330 DBUG_RETURN(TRUE);
331 if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
332 DBUG_RETURN(TRUE);
333
334 if (!table_list->single_table_updatable())
335 {
336 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
337 DBUG_RETURN(TRUE);
338 }
339 if (!(table= table_list->table) || !table->is_created())
340 {
341 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
342 table_list->view_db.str, table_list->view_name.str);
343 DBUG_RETURN(TRUE);
344 }
345 table->map=1;
346 query_plan.select_lex= &thd->lex->select_lex;
347 query_plan.table= table;
348 query_plan.updating_a_view= MY_TEST(table_list->view);
349
350 if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
351 select_lex->item_list, &conds,
352 &delete_while_scanning))
353 DBUG_RETURN(TRUE);
354
355 if (with_select)
356 (void) result->prepare(select_lex->item_list, NULL);
357
358 if (thd->lex->current_select->first_cond_optimization)
359 {
360 thd->lex->current_select->save_leaf_tables(thd);
361 thd->lex->current_select->first_cond_optimization= 0;
362 }
363 /* check ORDER BY even if it can be ignored */
364 if (order)
365 {
366 TABLE_LIST tables;
367 List<Item> fields;
368 List<Item> all_fields;
369
370 bzero((char*) &tables,sizeof(tables));
371 tables.table = table;
372 tables.alias = table_list->alias;
373
374 if (select_lex->setup_ref_array(thd, order_list->elements) ||
375 setup_order(thd, select_lex->ref_pointer_array, &tables,
376 fields, all_fields, order))
377 {
378 free_underlaid_joins(thd, &thd->lex->select_lex);
379 DBUG_RETURN(TRUE);
380 }
381 }
382
383 /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
384 if (select_lex->optimize_unflattened_subqueries(false))
385 DBUG_RETURN(TRUE);
386
387 const_cond= (!conds || conds->const_item());
388 safe_update= MY_TEST(thd->variables.option_bits & OPTION_SAFE_UPDATES);
389 if (safe_update && const_cond)
390 {
391 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
392 ER_THD(thd, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
393 DBUG_RETURN(TRUE);
394 }
395
396 const_cond_result= const_cond && (!conds || conds->val_int());
397 if (unlikely(thd->is_error()))
398 {
399 /* Error evaluating val_int(). */
400 DBUG_RETURN(TRUE);
401 }
402
403 /*
404 Test if the user wants to delete all rows and deletion doesn't have
405 any side-effects (because of triggers), so we can use optimized
406 handler::delete_all_rows() method.
407
408 We can use delete_all_rows() if and only if:
409 - We allow new functions (not using option --skip-new), and are
410 not in safe mode (not using option --safe-mode)
411 - There is no limit clause
412 - The condition is constant
413 - If there is a condition, then it it produces a non-zero value
414 - If the current command is DELETE FROM with no where clause, then:
415 - We should not be binlogging this statement in row-based, and
416 - there should be no delete triggers associated with the table.
417 */
418
419 has_triggers= (table->triggers &&
420 table->triggers->has_delete_triggers());
421 if (!with_select && !using_limit && const_cond_result &&
422 (!thd->is_current_stmt_binlog_format_row() &&
423 !has_triggers)
424 && !table->versioned(VERS_TIMESTAMP))
425 {
426 /* Update the table->file->stats.records number */
427 table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
428 ha_rows const maybe_deleted= table->file->stats.records;
429 DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
430
431 query_plan.set_delete_all_rows(maybe_deleted);
432 if (thd->lex->describe)
433 goto produce_explain_and_leave;
434
435 if (likely(!(error=table->file->ha_delete_all_rows())))
436 {
437 /*
438 If delete_all_rows() is used, it is not possible to log the
439 query in row format, so we have to log it in statement format.
440 */
441 query_type= THD::STMT_QUERY_TYPE;
442 error= -1;
443 deleted= maybe_deleted;
444 if (!query_plan.save_explain_delete_data(thd->mem_root, thd))
445 error= 1;
446 goto cleanup;
447 }
448 if (error != HA_ERR_WRONG_COMMAND)
449 {
450 table->file->print_error(error,MYF(0));
451 error=0;
452 goto cleanup;
453 }
454 /* Handler didn't support fast delete; Delete rows one by one */
455 query_plan.cancel_delete_all_rows();
456 }
457 if (conds)
458 {
459 Item::cond_result result;
460 conds= conds->remove_eq_conds(thd, &result, true);
461 if (result == Item::COND_FALSE) // Impossible where
462 {
463 limit= 0;
464 query_plan.set_impossible_where();
465 if (thd->lex->describe || thd->lex->analyze_stmt)
466 goto produce_explain_and_leave;
467 }
468 }
469
470#ifdef WITH_PARTITION_STORAGE_ENGINE
471 if (prune_partitions(thd, table, conds))
472 {
473 free_underlaid_joins(thd, select_lex);
474
475 query_plan.set_no_partitions();
476 if (thd->lex->describe || thd->lex->analyze_stmt)
477 goto produce_explain_and_leave;
478
479 my_ok(thd, 0);
480 DBUG_RETURN(0);
481 }
482#endif
483 /* Update the table->file->stats.records number */
484 table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
485 set_statistics_for_table(thd, table);
486
487 table->covering_keys.clear_all();
488 table->quick_keys.clear_all(); // Can't use 'only index'
489
490 select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error);
491 if (unlikely(error))
492 DBUG_RETURN(TRUE);
493 if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
494 {
495 query_plan.set_impossible_where();
496 if (thd->lex->describe || thd->lex->analyze_stmt)
497 goto produce_explain_and_leave;
498
499 delete select;
500 free_underlaid_joins(thd, select_lex);
501 /*
502 Error was already created by quick select evaluation (check_quick()).
503 TODO: Add error code output parameter to Item::val_xxx() methods.
504 Currently they rely on the user checking DA for
505 errors when unwinding the stack after calling Item::val_xxx().
506 */
507 if (unlikely(thd->is_error()))
508 DBUG_RETURN(TRUE);
509 my_ok(thd, 0);
510 DBUG_RETURN(0); // Nothing to delete
511 }
512
513 /* If running in safe sql mode, don't allow updates without keys */
514 if (table->quick_keys.is_clear_all())
515 {
516 thd->set_status_no_index_used();
517 if (safe_update && !using_limit)
518 {
519 delete select;
520 free_underlaid_joins(thd, select_lex);
521 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
522 ER_THD(thd, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
523 DBUG_RETURN(TRUE);
524 }
525 }
526 if (options & OPTION_QUICK)
527 (void) table->file->extra(HA_EXTRA_QUICK);
528
529 query_plan.scanned_rows= select? select->records: table->file->stats.records;
530 if (order)
531 {
532 table->update_const_key_parts(conds);
533 order= simple_remove_const(order, conds);
534
535 if (select && select->quick && select->quick->unique_key_range())
536 { // Single row select (always "ordered")
537 query_plan.using_filesort= FALSE;
538 query_plan.index= MAX_KEY;
539 }
540 else
541 {
542 ha_rows scanned_limit= query_plan.scanned_rows;
543 query_plan.index= get_index_for_order(order, table, select, limit,
544 &scanned_limit,
545 &query_plan.using_filesort,
546 &reverse);
547 if (!query_plan.using_filesort)
548 query_plan.scanned_rows= scanned_limit;
549 }
550 }
551
552 query_plan.select= select;
553 query_plan.possible_keys= select? select->possible_keys: key_map(0);
554
555 /*
556 Ok, we have generated a query plan for the DELETE.
557 - if we're running EXPLAIN DELETE, goto produce explain output
558 - otherwise, execute the query plan
559 */
560 if (thd->lex->describe)
561 goto produce_explain_and_leave;
562
563 if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd)))
564 goto got_error;
565 ANALYZE_START_TRACKING(&explain->command_tracker);
566
567 DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
568 dbug_serve_apcs(thd, 1););
569
570 if (!(select && select->quick))
571 status_var_increment(thd->status_var.delete_scan_count);
572
573 binlog_is_row= thd->is_current_stmt_binlog_format_row();
574 DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE"));
575
576 /*
577 We can use direct delete (delete that is done silently in the handler)
578 if none of the following conditions are true:
579 - There are triggers
580 - There is binary logging
581 - There is a virtual not stored column in the WHERE clause
582 - ORDER BY or LIMIT
583 - As this requires the rows to be deleted in a specific order
584 - Note that Spider can handle ORDER BY and LIMIT in a cluster with
585 one data node. These conditions are therefore checked in
586 direct_delete_rows_init().
587
588 Direct delete does not require a WHERE clause
589
590 Later we also ensure that we are only using one table (no sub queries)
591 */
592
593 if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) &&
594 !has_triggers && !binlog_is_row && !with_select)
595 {
596 table->mark_columns_needed_for_delete();
597 if (!table->check_virtual_columns_marked_for_read())
598 {
599 DBUG_PRINT("info", ("Trying direct delete"));
600 if (select && select->cond &&
601 (select->cond->used_tables() == table->map))
602 {
603 DBUG_ASSERT(!table->file->pushed_cond);
604 if (!table->file->cond_push(select->cond))
605 table->file->pushed_cond= select->cond;
606 }
607 if (!table->file->direct_delete_rows_init())
608 {
609 /* Direct deleting is supported */
610 DBUG_PRINT("info", ("Using direct delete"));
611 THD_STAGE_INFO(thd, stage_updating);
612 if (!(error= table->file->ha_direct_delete_rows(&deleted)))
613 error= -1;
614 goto terminate_delete;
615 }
616 }
617 }
618
619 if (query_plan.using_filesort)
620 {
621 {
622 Filesort fsort(order, HA_POS_ERROR, true, select);
623 DBUG_ASSERT(query_plan.index == MAX_KEY);
624
625 Filesort_tracker *fs_tracker=
626 thd->lex->explain->get_upd_del_plan()->filesort_tracker;
627
628 if (!(file_sort= filesort(thd, table, &fsort, fs_tracker)))
629 goto got_error;
630
631 thd->inc_examined_row_count(file_sort->examined_rows);
632 /*
633 Filesort has already found and selected the rows we want to delete,
634 so we don't need the where clause
635 */
636 delete select;
637
638 /*
639 If we are not in DELETE ... RETURNING, we can free subqueries. (in
640 DELETE ... RETURNING we can't, because the RETURNING part may have
641 a subquery in it)
642 */
643 if (!with_select)
644 free_underlaid_joins(thd, select_lex);
645 select= 0;
646 }
647 }
648
649 /* If quick select is used, initialize it before retrieving rows. */
650 if (select && select->quick && select->quick->reset())
651 goto got_error;
652
653 if (query_plan.index == MAX_KEY || (select && select->quick))
654 error= init_read_record(&info, thd, table, select, file_sort, 1, 1, FALSE);
655 else
656 error= init_read_record_idx(&info, thd, table, 1, query_plan.index,
657 reverse);
658 if (unlikely(error))
659 goto got_error;
660
661 if (unlikely(init_ftfuncs(thd, select_lex, 1)))
662 goto got_error;
663
664 table->mark_columns_needed_for_delete();
665
666 if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) &&
667 !table->prepare_triggers_for_delete_stmt_or_event())
668 will_batch= !table->file->start_bulk_delete();
669
670 if (with_select)
671 {
672 if (unlikely(result->send_result_set_metadata(select_lex->item_list,
673 Protocol::SEND_NUM_ROWS |
674 Protocol::SEND_EOF)))
675 goto cleanup;
676 }
677
678 explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan();
679 explain->tracker.on_scan_init();
680
681 if (!delete_while_scanning)
682 {
683 /*
684 The table we are going to delete appears in subqueries in the where
685 clause. Instead of deleting the rows, first mark them deleted.
686 */
687 ha_rows tmplimit=limit;
688 deltempfile= new (thd->mem_root) Unique (refpos_order_cmp, table->file,
689 table->file->ref_length,
690 MEM_STRIP_BUF_SIZE);
691
692 THD_STAGE_INFO(thd, stage_searching_rows_for_update);
693 while (!(error=info.read_record()) && !thd->killed &&
694 ! thd->is_error())
695 {
696 if (record_should_be_deleted(thd, table, select, explain, truncate_history))
697 {
698 table->file->position(table->record[0]);
699 if (unlikely((error=
700 deltempfile->unique_add((char*) table->file->ref))))
701 {
702 error= 1;
703 goto terminate_delete;
704 }
705 if (!--tmplimit && using_limit)
706 break;
707 }
708 }
709 end_read_record(&info);
710 if (unlikely(deltempfile->get(table)) ||
711 unlikely(table->file->ha_index_or_rnd_end()) ||
712 unlikely(init_read_record(&info, thd, table, 0, &deltempfile->sort, 0,
713 1, false)))
714 {
715 error= 1;
716 goto terminate_delete;
717 }
718 delete_record= true;
719 }
720
721 THD_STAGE_INFO(thd, stage_updating);
722 while (likely(!(error=info.read_record())) && likely(!thd->killed) &&
723 likely(!thd->is_error()))
724 {
725 if (delete_while_scanning)
726 delete_record= record_should_be_deleted(thd, table, select, explain,
727 truncate_history);
728 if (delete_record)
729 {
730 if (!truncate_history && table->triggers &&
731 table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
732 TRG_ACTION_BEFORE, FALSE))
733 {
734 error= 1;
735 break;
736 }
737
738 if (with_select && result->send_data(select_lex->item_list) < 0)
739 {
740 error=1;
741 break;
742 }
743
744 error= table->delete_row();
745 if (likely(!error))
746 {
747 deleted++;
748 if (!truncate_history && table->triggers &&
749 table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
750 TRG_ACTION_AFTER, FALSE))
751 {
752 error= 1;
753 break;
754 }
755 if (!--limit && using_limit)
756 {
757 error= -1;
758 break;
759 }
760 }
761 else
762 {
763 table->file->print_error(error,
764 MYF(thd->lex->ignore ? ME_JUST_WARNING : 0));
765 if (thd->is_error())
766 {
767 error= 1;
768 break;
769 }
770 }
771 }
772 /*
773 Don't try unlocking the row if skip_record reported an error since in
774 this case the transaction might have been rolled back already.
775 */
776 else if (likely(!thd->is_error()))
777 table->file->unlock_row(); // Row failed selection, release lock on it
778 else
779 break;
780 }
781
782terminate_delete:
783 killed_status= thd->killed;
784 if (unlikely(killed_status != NOT_KILLED || thd->is_error()))
785 error= 1; // Aborted
786 if (will_batch && unlikely((loc_error= table->file->end_bulk_delete())))
787 {
788 if (error != 1)
789 table->file->print_error(loc_error,MYF(0));
790 error=1;
791 }
792 THD_STAGE_INFO(thd, stage_end);
793 end_read_record(&info);
794 if (options & OPTION_QUICK)
795 (void) table->file->extra(HA_EXTRA_NORMAL);
796 ANALYZE_STOP_TRACKING(&explain->command_tracker);
797
798cleanup:
799 /*
800 Invalidate the table in the query cache if something changed. This must
801 be before binlog writing and ha_autocommit_...
802 */
803 if (deleted)
804 {
805 query_cache_invalidate3(thd, table_list, 1);
806 }
807
808 if (thd->lex->current_select->first_cond_optimization)
809 {
810 thd->lex->current_select->save_leaf_tables(thd);
811 thd->lex->current_select->first_cond_optimization= 0;
812 }
813
814 delete deltempfile;
815 deltempfile=NULL;
816 delete select;
817 select= NULL;
818 transactional_table= table->file->has_transactions();
819
820 if (!transactional_table && deleted > 0)
821 thd->transaction.stmt.modified_non_trans_table=
822 thd->transaction.all.modified_non_trans_table= TRUE;
823
824 /* See similar binlogging code in sql_update.cc, for comments */
825 if (likely((error < 0) || thd->transaction.stmt.modified_non_trans_table))
826 {
827 if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
828 {
829 int errcode= 0;
830 if (error < 0)
831 thd->clear_error();
832 else
833 errcode= query_error_code(thd, killed_status == NOT_KILLED);
834
835 ScopedStatementReplication scoped_stmt_rpl(
836 table->versioned(VERS_TRX_ID) ? thd : NULL);
837 /*
838 [binlog]: If 'handler::delete_all_rows()' was called and the
839 storage engine does not inject the rows itself, we replicate
840 statement-based; otherwise, 'ha_delete_row()' was used to
841 delete specific rows which we might log row-based.
842 */
843 int log_result= thd->binlog_query(query_type,
844 thd->query(), thd->query_length(),
845 transactional_table, FALSE, FALSE,
846 errcode);
847
848 if (log_result)
849 {
850 error=1;
851 }
852 }
853 }
854 DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
855
856 if (likely(error < 0) ||
857 (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
858 {
859 if (thd->lex->analyze_stmt)
860 goto send_nothing_and_leave;
861
862 if (with_select)
863 result->send_eof();
864 else
865 my_ok(thd, deleted);
866 DBUG_PRINT("info",("%ld records deleted",(long) deleted));
867 }
868 delete file_sort;
869 free_underlaid_joins(thd, select_lex);
870 if (table->file->pushed_cond)
871 table->file->cond_pop();
872 DBUG_RETURN(error >= 0 || thd->is_error());
873
874 /* Special exits */
875produce_explain_and_leave:
876 /*
877 We come here for various "degenerate" query plans: impossible WHERE,
878 no-partitions-used, impossible-range, etc.
879 */
880 if (!(query_plan.save_explain_delete_data(thd->mem_root, thd)))
881 goto got_error;
882
883send_nothing_and_leave:
884 /*
885 ANALYZE DELETE jumps here. We can't send explain right here, because
886 we might be using ANALYZE DELETE ...RETURNING, in which case we have
887 Protocol_discard active.
888 */
889
890 delete select;
891 delete file_sort;
892 free_underlaid_joins(thd, select_lex);
893 if (table->file->pushed_cond)
894 table->file->cond_pop();
895
896 DBUG_ASSERT(!return_error || thd->is_error() || thd->killed);
897 DBUG_RETURN((return_error || thd->is_error() || thd->killed) ? 1 : 0);
898
899got_error:
900 return_error= 1;
901 goto send_nothing_and_leave;
902}
903
904
905/*
906 Prepare items in DELETE statement
907
908 SYNOPSIS
909 mysql_prepare_delete()
910 thd - thread handler
911 table_list - global/local table list
912 wild_num - number of wildcards used in optional SELECT clause
913 field_list - list of items in optional SELECT clause
914 conds - conditions
915
916 RETURN VALUE
917 FALSE OK
918 TRUE error
919*/
920int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
921 uint wild_num, List<Item> &field_list, Item **conds,
922 bool *delete_while_scanning)
923{
924 Item *fake_conds= 0;
925 SELECT_LEX *select_lex= &thd->lex->select_lex;
926 DBUG_ENTER("mysql_prepare_delete");
927 List<Item> all_fields;
928
929 *delete_while_scanning= true;
930 thd->lex->allow_sum_func= 0;
931 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
932 &thd->lex->select_lex.top_join_list,
933 table_list,
934 select_lex->leaf_tables, FALSE,
935 DELETE_ACL, SELECT_ACL, TRUE))
936 DBUG_RETURN(TRUE);
937 if (table_list->vers_conditions.is_set())
938 {
939 if (table_list->is_view())
940 {
941 my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
942 DBUG_RETURN(true);
943 }
944 if (select_lex->vers_setup_conds(thd, table_list))
945 DBUG_RETURN(true);
946 }
947 if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num,
948 &select_lex->hidden_bit_fields)) ||
949 setup_fields(thd, Ref_ptr_array(),
950 field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
951 setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
952 setup_ftfuncs(select_lex))
953 DBUG_RETURN(TRUE);
954 if (!table_list->single_table_updatable() ||
955 check_key_in_view(thd, table_list))
956 {
957 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
958 DBUG_RETURN(TRUE);
959 }
960
961 if (unique_table(thd, table_list, table_list->next_global, 0))
962 *delete_while_scanning= false;
963
964 if (select_lex->inner_refs_list.elements &&
965 fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
966 DBUG_RETURN(TRUE);
967
968 select_lex->fix_prepare_information(thd, conds, &fake_conds);
969 DBUG_RETURN(FALSE);
970}
971
972
973/***************************************************************************
974 Delete multiple tables from join
975***************************************************************************/
976
977
978extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
979{
980 handler *file= (handler*)arg;
981 return file->cmp_ref((const uchar*)a, (const uchar*)b);
982}
983
984/*
985 make delete specific preparation and checks after opening tables
986
987 SYNOPSIS
988 mysql_multi_delete_prepare()
989 thd thread handler
990
991 RETURN
992 FALSE OK
993 TRUE Error
994*/
995
996int mysql_multi_delete_prepare(THD *thd)
997{
998 LEX *lex= thd->lex;
999 TABLE_LIST *aux_tables= lex->auxiliary_table_list.first;
1000 TABLE_LIST *target_tbl;
1001 DBUG_ENTER("mysql_multi_delete_prepare");
1002
1003 if (mysql_handle_derived(lex, DT_INIT))
1004 DBUG_RETURN(TRUE);
1005 if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
1006 DBUG_RETURN(TRUE);
1007 if (mysql_handle_derived(lex, DT_PREPARE))
1008 DBUG_RETURN(TRUE);
1009 /*
1010 setup_tables() need for VIEWs. JOIN::prepare() will not do it second
1011 time.
1012
1013 lex->query_tables also point on local list of DELETE SELECT_LEX
1014 */
1015 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
1016 &thd->lex->select_lex.top_join_list,
1017 lex->query_tables,
1018 lex->select_lex.leaf_tables, FALSE,
1019 DELETE_ACL, SELECT_ACL, FALSE))
1020 DBUG_RETURN(TRUE);
1021
1022 if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
1023 DBUG_RETURN(TRUE);
1024
1025 /*
1026 Multi-delete can't be constructed over-union => we always have
1027 single SELECT on top and have to check underlying SELECTs of it
1028 */
1029 lex->select_lex.exclude_from_table_unique_test= TRUE;
1030 /* Fix tables-to-be-deleted-from list to point at opened tables */
1031 for (target_tbl= (TABLE_LIST*) aux_tables;
1032 target_tbl;
1033 target_tbl= target_tbl->next_local)
1034 {
1035
1036 target_tbl->table= target_tbl->correspondent_table->table;
1037 if (target_tbl->correspondent_table->is_multitable())
1038 {
1039 my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
1040 target_tbl->correspondent_table->view_db.str,
1041 target_tbl->correspondent_table->view_name.str);
1042 DBUG_RETURN(TRUE);
1043 }
1044
1045 if (!target_tbl->correspondent_table->single_table_updatable() ||
1046 check_key_in_view(thd, target_tbl->correspondent_table))
1047 {
1048 my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
1049 target_tbl->table_name.str, "DELETE");
1050 DBUG_RETURN(TRUE);
1051 }
1052 /*
1053 Check that table from which we delete is not used somewhere
1054 inside subqueries/view.
1055 */
1056 {
1057 TABLE_LIST *duplicate;
1058 if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
1059 lex->query_tables, 0)))
1060 {
1061 update_non_unique_table_error(target_tbl->correspondent_table,
1062 "DELETE", duplicate);
1063 DBUG_RETURN(TRUE);
1064 }
1065 }
1066 }
1067 /*
1068 Reset the exclude flag to false so it doesn't interfare
1069 with further calls to unique_table
1070 */
1071 lex->select_lex.exclude_from_table_unique_test= FALSE;
1072
1073 if (lex->save_prep_leaf_tables())
1074 DBUG_RETURN(TRUE);
1075
1076 DBUG_RETURN(FALSE);
1077}
1078
1079
1080multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg):
1081 select_result_interceptor(thd_arg), delete_tables(dt), deleted(0), found(0),
1082 num_of_tables(num_of_tables_arg), error(0),
1083 do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
1084{
1085 tempfiles= (Unique **) thd_arg->calloc(sizeof(Unique *) * num_of_tables);
1086}
1087
1088
1089int
1090multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
1091{
1092 DBUG_ENTER("multi_delete::prepare");
1093 unit= u;
1094 do_delete= 1;
1095 THD_STAGE_INFO(thd, stage_deleting_from_main_table);
1096 SELECT_LEX *select_lex= u->first_select();
1097 if (select_lex->first_cond_optimization)
1098 {
1099 if (select_lex->handle_derived(thd->lex, DT_MERGE))
1100 DBUG_RETURN(TRUE);
1101 }
1102 DBUG_RETURN(0);
1103}
1104
1105void multi_delete::prepare_to_read_rows()
1106{
1107 /* see multi_update::prepare_to_read_rows() */
1108 for (TABLE_LIST *walk= delete_tables; walk; walk= walk->next_local)
1109 {
1110 TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
1111 tbl->table->mark_columns_needed_for_delete();
1112 }
1113}
1114
1115bool
1116multi_delete::initialize_tables(JOIN *join)
1117{
1118 TABLE_LIST *walk;
1119 Unique **tempfiles_ptr;
1120 DBUG_ENTER("initialize_tables");
1121
1122 if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
1123 error_if_full_join(join)))
1124 DBUG_RETURN(1);
1125
1126 table_map tables_to_delete_from=0;
1127 delete_while_scanning= true;
1128 for (walk= delete_tables; walk; walk= walk->next_local)
1129 {
1130 TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
1131 tables_to_delete_from|= tbl->table->map;
1132 if (delete_while_scanning &&
1133 unique_table(thd, tbl, join->tables_list, 0))
1134 {
1135 /*
1136 If the table we are going to delete from appears
1137 in join, we need to defer delete. So the delete
1138 doesn't interfers with the scaning of results.
1139 */
1140 delete_while_scanning= false;
1141 }
1142 }
1143
1144 walk= delete_tables;
1145
1146 for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS,
1147 WITH_CONST_TABLES);
1148 tab;
1149 tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
1150 {
1151 if (!tab->bush_children && tab->table->map & tables_to_delete_from)
1152 {
1153 /* We are going to delete from this table */
1154 TABLE *tbl=walk->table=tab->table;
1155 walk= walk->next_local;
1156 /* Don't use KEYREAD optimization on this table */
1157 tbl->no_keyread=1;
1158 /* Don't use record cache */
1159 tbl->no_cache= 1;
1160 tbl->covering_keys.clear_all();
1161 if (tbl->file->has_transactions())
1162 transactional_tables= 1;
1163 else
1164 normal_tables= 1;
1165 tbl->prepare_triggers_for_delete_stmt_or_event();
1166 tbl->prepare_for_position();
1167 }
1168 else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
1169 walk == delete_tables)
1170 {
1171 /*
1172 We are not deleting from the table we are scanning. In this
1173 case send_data() shouldn't delete any rows a we may touch
1174 the rows in the deleted table many times
1175 */
1176 delete_while_scanning= false;
1177 }
1178 }
1179 walk= delete_tables;
1180 tempfiles_ptr= tempfiles;
1181 if (delete_while_scanning)
1182 {
1183 table_being_deleted= delete_tables;
1184 walk= walk->next_local;
1185 }
1186 for (;walk ;walk= walk->next_local)
1187 {
1188 TABLE *table=walk->table;
1189 *tempfiles_ptr++= new (thd->mem_root) Unique (refpos_order_cmp, table->file,
1190 table->file->ref_length,
1191 MEM_STRIP_BUF_SIZE);
1192 }
1193 init_ftfuncs(thd, thd->lex->current_select, 1);
1194 DBUG_RETURN(thd->is_fatal_error);
1195}
1196
1197
1198multi_delete::~multi_delete()
1199{
1200 for (table_being_deleted= delete_tables;
1201 table_being_deleted;
1202 table_being_deleted= table_being_deleted->next_local)
1203 {
1204 TABLE *table= table_being_deleted->table;
1205 table->no_keyread=0;
1206 }
1207
1208 for (uint counter= 0; counter < num_of_tables; counter++)
1209 {
1210 if (tempfiles[counter])
1211 delete tempfiles[counter];
1212 }
1213}
1214
1215
1216int multi_delete::send_data(List<Item> &values)
1217{
1218 int secure_counter= delete_while_scanning ? -1 : 0;
1219 TABLE_LIST *del_table;
1220 DBUG_ENTER("multi_delete::send_data");
1221
1222 bool ignore= thd->lex->ignore;
1223
1224 for (del_table= delete_tables;
1225 del_table;
1226 del_table= del_table->next_local, secure_counter++)
1227 {
1228 TABLE *table= del_table->table;
1229
1230 /* Check if we are using outer join and we didn't find the row */
1231 if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
1232 continue;
1233
1234 if (table->versioned() && !table->vers_end_field()->is_max())
1235 {
1236 continue;
1237 }
1238
1239 table->file->position(table->record[0]);
1240 found++;
1241
1242 if (secure_counter < 0)
1243 {
1244 /* We are scanning the current table */
1245 DBUG_ASSERT(del_table == table_being_deleted);
1246 if (table->triggers &&
1247 table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1248 TRG_ACTION_BEFORE, FALSE))
1249 DBUG_RETURN(1);
1250 table->status|= STATUS_DELETED;
1251
1252 error= table->delete_row();
1253 if (likely(!error))
1254 {
1255 deleted++;
1256 if (!table->file->has_transactions())
1257 thd->transaction.stmt.modified_non_trans_table= TRUE;
1258 if (table->triggers &&
1259 table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1260 TRG_ACTION_AFTER, FALSE))
1261 DBUG_RETURN(1);
1262 }
1263 else if (!ignore)
1264 {
1265 /*
1266 If the IGNORE option is used errors caused by ha_delete_row don't
1267 have to stop the iteration.
1268 */
1269 table->file->print_error(error,MYF(0));
1270 DBUG_RETURN(1);
1271 }
1272 }
1273 else
1274 {
1275 error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
1276 if (unlikely(error))
1277 {
1278 error= 1; // Fatal error
1279 DBUG_RETURN(1);
1280 }
1281 }
1282 }
1283 DBUG_RETURN(0);
1284}
1285
1286
1287void multi_delete::abort_result_set()
1288{
1289 DBUG_ENTER("multi_delete::abort_result_set");
1290
1291 /* the error was handled or nothing deleted and no side effects return */
1292 if (error_handled ||
1293 (!thd->transaction.stmt.modified_non_trans_table && !deleted))
1294 DBUG_VOID_RETURN;
1295
1296 /* Something already deleted so we have to invalidate cache */
1297 if (deleted)
1298 query_cache_invalidate3(thd, delete_tables, 1);
1299
1300 if (thd->transaction.stmt.modified_non_trans_table)
1301 thd->transaction.all.modified_non_trans_table= TRUE;
1302 thd->transaction.all.m_unsafe_rollback_flags|=
1303 (thd->transaction.stmt.m_unsafe_rollback_flags & THD_TRANS::DID_WAIT);
1304
1305 /*
1306 If rows from the first table only has been deleted and it is
1307 transactional, just do rollback.
1308 The same if all tables are transactional, regardless of where we are.
1309 In all other cases do attempt deletes ...
1310 */
1311 if (do_delete && normal_tables &&
1312 (table_being_deleted != delete_tables ||
1313 !table_being_deleted->table->file->has_transactions()))
1314 {
1315 /*
1316 We have to execute the recorded do_deletes() and write info into the
1317 error log
1318 */
1319 error= 1;
1320 send_eof();
1321 DBUG_ASSERT(error_handled);
1322 DBUG_VOID_RETURN;
1323 }
1324
1325 if (thd->transaction.stmt.modified_non_trans_table)
1326 {
1327 /*
1328 there is only side effects; to binlog with the error
1329 */
1330 if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
1331 {
1332 int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
1333 /* possible error of writing binary log is ignored deliberately */
1334 (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
1335 thd->query(), thd->query_length(),
1336 transactional_tables, FALSE, FALSE, errcode);
1337 }
1338 }
1339 DBUG_VOID_RETURN;
1340}
1341
1342
1343
1344/**
1345 Do delete from other tables.
1346
1347 @retval 0 ok
1348 @retval 1 error
1349
1350 @todo Is there any reason not use the normal nested-loops join? If not, and
1351 there is no documentation supporting it, this method and callee should be
1352 removed and there should be hooks within normal execution.
1353*/
1354
1355int multi_delete::do_deletes()
1356{
1357 DBUG_ENTER("do_deletes");
1358 DBUG_ASSERT(do_delete);
1359
1360 do_delete= 0; // Mark called
1361 if (!found)
1362 DBUG_RETURN(0);
1363
1364 table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
1365 delete_tables);
1366
1367 for (uint counter= 0; table_being_deleted;
1368 table_being_deleted= table_being_deleted->next_local, counter++)
1369 {
1370 TABLE *table = table_being_deleted->table;
1371 int local_error;
1372 if (unlikely(tempfiles[counter]->get(table)))
1373 DBUG_RETURN(1);
1374
1375 local_error= do_table_deletes(table, &tempfiles[counter]->sort,
1376 thd->lex->ignore);
1377
1378 if (unlikely(thd->killed) && likely(!local_error))
1379 DBUG_RETURN(1);
1380
1381 if (unlikely(local_error == -1)) // End of file
1382 local_error= 0;
1383
1384 if (unlikely(local_error))
1385 DBUG_RETURN(local_error);
1386 }
1387 DBUG_RETURN(0);
1388}
1389
1390
1391/**
1392 Implements the inner loop of nested-loops join within multi-DELETE
1393 execution.
1394
1395 @param table The table from which to delete.
1396
1397 @param ignore If used, all non fatal errors will be translated
1398 to warnings and we should not break the row-by-row iteration.
1399
1400 @return Status code
1401
1402 @retval 0 All ok.
1403 @retval 1 Triggers or handler reported error.
1404 @retval -1 End of file from handler.
1405*/
1406int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info,
1407 bool ignore)
1408{
1409 int local_error= 0;
1410 READ_RECORD info;
1411 ha_rows last_deleted= deleted;
1412 DBUG_ENTER("do_deletes_for_table");
1413
1414 if (unlikely(init_read_record(&info, thd, table, NULL, sort_info, 0, 1,
1415 FALSE)))
1416 DBUG_RETURN(1);
1417
1418 bool will_batch= !table->file->start_bulk_delete();
1419 while (likely(!(local_error= info.read_record())) && likely(!thd->killed))
1420 {
1421 if (table->triggers &&
1422 unlikely(table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1423 TRG_ACTION_BEFORE, FALSE)))
1424 {
1425 local_error= 1;
1426 break;
1427 }
1428
1429 local_error= table->delete_row();
1430 if (unlikely(local_error) && !ignore)
1431 {
1432 table->file->print_error(local_error, MYF(0));
1433 break;
1434 }
1435
1436 /*
1437 Increase the reported number of deleted rows only if no error occurred
1438 during ha_delete_row.
1439 Also, don't execute the AFTER trigger if the row operation failed.
1440 */
1441 if (unlikely(!local_error))
1442 {
1443 deleted++;
1444 if (table->triggers &&
1445 table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1446 TRG_ACTION_AFTER, FALSE))
1447 {
1448 local_error= 1;
1449 break;
1450 }
1451 }
1452 }
1453 if (will_batch)
1454 {
1455 int tmp_error= table->file->end_bulk_delete();
1456 if (unlikely(tmp_error) && !local_error)
1457 {
1458 local_error= tmp_error;
1459 table->file->print_error(local_error, MYF(0));
1460 }
1461 }
1462 if (last_deleted != deleted && !table->file->has_transactions())
1463 thd->transaction.stmt.modified_non_trans_table= TRUE;
1464
1465 end_read_record(&info);
1466
1467 DBUG_RETURN(local_error);
1468}
1469
1470/*
1471 Send ok to the client
1472
1473 return: 0 sucess
1474 1 error
1475*/
1476
1477bool multi_delete::send_eof()
1478{
1479 killed_state killed_status= NOT_KILLED;
1480 THD_STAGE_INFO(thd, stage_deleting_from_reference_tables);
1481
1482 /* Does deletes for the last n - 1 tables, returns 0 if ok */
1483 int local_error= do_deletes(); // returns 0 if success
1484
1485 /* compute a total error to know if something failed */
1486 local_error= local_error || error;
1487 killed_status= (local_error == 0)? NOT_KILLED : thd->killed;
1488 /* reset used flags */
1489 THD_STAGE_INFO(thd, stage_end);
1490
1491 if (thd->transaction.stmt.modified_non_trans_table)
1492 thd->transaction.all.modified_non_trans_table= TRUE;
1493 thd->transaction.all.m_unsafe_rollback_flags|=
1494 (thd->transaction.stmt.m_unsafe_rollback_flags & THD_TRANS::DID_WAIT);
1495
1496 /*
1497 We must invalidate the query cache before binlog writing and
1498 ha_autocommit_...
1499 */
1500 if (deleted)
1501 {
1502 query_cache_invalidate3(thd, delete_tables, 1);
1503 }
1504 if (likely((local_error == 0) ||
1505 thd->transaction.stmt.modified_non_trans_table))
1506 {
1507 if(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
1508 {
1509 int errcode= 0;
1510 if (likely(local_error == 0))
1511 thd->clear_error();
1512 else
1513 errcode= query_error_code(thd, killed_status == NOT_KILLED);
1514 if (unlikely(thd->binlog_query(THD::ROW_QUERY_TYPE,
1515 thd->query(), thd->query_length(),
1516 transactional_tables, FALSE, FALSE,
1517 errcode)) &&
1518 !normal_tables)
1519 {
1520 local_error=1; // Log write failed: roll back the SQL statement
1521 }
1522 }
1523 }
1524 if (unlikely(local_error != 0))
1525 error_handled= TRUE; // to force early leave from ::abort_result_set()
1526
1527 if (likely(!local_error && !thd->lex->analyze_stmt))
1528 {
1529 ::my_ok(thd, deleted);
1530 }
1531 return 0;
1532}
1533