1 /*
2    Copyright (c) 2000, 2019, Oracle and/or its affiliates.
3    Copyright (c) 2010, 2021, 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-1335  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_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 
save_explain_delete_data(MEM_ROOT * mem_root,THD * thd)59 Explain_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 
86 Explain_update*
save_explain_update_data(MEM_ROOT * mem_root,THD * thd)87 Update_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 
save_explain_data_intern(MEM_ROOT * mem_root,Explain_update * explain,bool is_analyze)101 bool 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 
record_should_be_deleted(THD * thd,TABLE * table,SQL_SELECT * sel,Explain_delete * explain,bool truncate_history)225 static bool record_should_be_deleted(THD *thd, TABLE *table, SQL_SELECT *sel,
226                                      Explain_delete *explain, bool truncate_history)
227 {
228   explain->tracker.on_record_read();
229   thd->inc_examined_row_count(1);
230   if (table->vfield)
231     (void) table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_DELETE);
232   if (!sel || sel->skip_record(thd) > 0)
233   {
234     explain->tracker.on_record_after_where();
235     return true;
236   }
237   return false;
238 }
239 
240 static
update_portion_of_time(THD * thd,TABLE * table,const vers_select_conds_t & period_conds,bool * inside_period)241 int update_portion_of_time(THD *thd, TABLE *table,
242                            const vers_select_conds_t &period_conds,
243                            bool *inside_period)
244 {
245   bool lcond= period_conds.field_start->val_datetime_packed(thd)
246               < period_conds.start.item->val_datetime_packed(thd);
247   bool rcond= period_conds.field_end->val_datetime_packed(thd)
248               > period_conds.end.item->val_datetime_packed(thd);
249 
250   *inside_period= !lcond && !rcond;
251   if (*inside_period)
252     return 0;
253 
254   DBUG_ASSERT(!table->triggers
255               || !table->triggers->has_triggers(TRG_EVENT_INSERT,
256                                                 TRG_ACTION_BEFORE));
257 
258   int res= 0;
259   Item *src= lcond ? period_conds.start.item : period_conds.end.item;
260   uint dst_fieldno= lcond ? table->s->period.end_fieldno
261                           : table->s->period.start_fieldno;
262 
263   ulonglong prev_insert_id= table->file->next_insert_id;
264   store_record(table, record[1]);
265   if (likely(!res))
266     res= src->save_in_field(table->field[dst_fieldno], true);
267 
268   if (likely(!res))
269     res= table->update_generated_fields();
270 
271   if(likely(!res))
272     res= table->file->ha_update_row(table->record[1], table->record[0]);
273 
274   if (likely(!res) && table->triggers)
275     res= table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
276                                            TRG_ACTION_AFTER, true);
277   restore_record(table, record[1]);
278   if (res)
279     table->file->restore_auto_increment(prev_insert_id);
280 
281   if (likely(!res) && lcond && rcond)
282     res= table->period_make_insert(period_conds.end.item,
283                                    table->field[table->s->period.start_fieldno]);
284 
285   return res;
286 }
287 
288 inline
delete_row()289 int TABLE::delete_row()
290 {
291   if (!versioned(VERS_TIMESTAMP) || !vers_end_field()->is_max())
292     return file->ha_delete_row(record[0]);
293 
294   store_record(this, record[1]);
295   vers_update_end();
296   int err= file->ha_update_row(record[1], record[0]);
297   /*
298      MDEV-23644: we get HA_ERR_FOREIGN_DUPLICATE_KEY iff we already got history
299      row with same trx_id which is the result of foreign key action, so we
300      don't need one more history row.
301   */
302   if (err == HA_ERR_FOREIGN_DUPLICATE_KEY)
303     return file->ha_delete_row(record[0]);
304   return err;
305 }
306 
307 
308 /**
309   Implement DELETE SQL word.
310 
311   @note Like implementations of other DDL/DML in MySQL, this function
312   relies on the caller to close the thread tables. This is done in the
313   end of dispatch_command().
314 */
315 
mysql_delete(THD * thd,TABLE_LIST * table_list,COND * conds,SQL_I_List<ORDER> * order_list,ha_rows limit,ulonglong options,select_result * result)316 bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
317                   SQL_I_List<ORDER> *order_list, ha_rows limit,
318                   ulonglong options, select_result *result)
319 {
320   bool          will_batch= FALSE;
321   int		error, loc_error;
322   TABLE		*table;
323   SQL_SELECT	*select=0;
324   SORT_INFO	*file_sort= 0;
325   READ_RECORD	info;
326   bool          using_limit=limit != HA_POS_ERROR;
327   bool		transactional_table, safe_update, const_cond;
328   bool          const_cond_result;
329   bool		return_error= 0;
330   ha_rows	deleted= 0;
331   bool          reverse= FALSE;
332   bool          has_triggers= false;
333   ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
334                            order_list->first : NULL);
335   SELECT_LEX   *select_lex= thd->lex->first_select_lex();
336   killed_state killed_status= NOT_KILLED;
337   THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
338   bool binlog_is_row;
339   bool with_select= !select_lex->item_list.is_empty();
340   Explain_delete *explain;
341   Delete_plan query_plan(thd->mem_root);
342   Unique * deltempfile= NULL;
343   bool delete_record= false;
344   bool delete_while_scanning;
345   bool portion_of_time_through_update;
346   DBUG_ENTER("mysql_delete");
347 
348   query_plan.index= MAX_KEY;
349   query_plan.using_filesort= FALSE;
350 
351   create_explain_query(thd->lex, thd->mem_root);
352   if (open_and_lock_tables(thd, table_list, TRUE, 0))
353     DBUG_RETURN(TRUE);
354 
355   THD_STAGE_INFO(thd, stage_init_update);
356 
357   const bool delete_history= table_list->vers_conditions.delete_history;
358   DBUG_ASSERT(!(delete_history && table_list->period_conditions.is_set()));
359 
360   if (thd->lex->handle_list_of_derived(table_list, DT_MERGE_FOR_INSERT))
361     DBUG_RETURN(TRUE);
362   if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
363     DBUG_RETURN(TRUE);
364 
365   if (!table_list->single_table_updatable())
366   {
367      my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
368      DBUG_RETURN(TRUE);
369   }
370   if (!(table= table_list->table) || !table->is_created())
371   {
372       my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
373 	       table_list->view_db.str, table_list->view_name.str);
374     DBUG_RETURN(TRUE);
375   }
376   table->map=1;
377   query_plan.select_lex= thd->lex->first_select_lex();
378   query_plan.table= table;
379   query_plan.updating_a_view= MY_TEST(table_list->view);
380 
381   promote_select_describe_flag_if_needed(thd->lex);
382 
383   if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
384                            select_lex->item_list, &conds,
385                            &delete_while_scanning))
386     DBUG_RETURN(TRUE);
387 
388   if (delete_history)
389     table->vers_write= false;
390 
391   if (with_select)
392     (void) result->prepare(select_lex->item_list, NULL);
393 
394   if (thd->lex->current_select->first_cond_optimization)
395   {
396     thd->lex->current_select->save_leaf_tables(thd);
397     thd->lex->current_select->first_cond_optimization= 0;
398   }
399   /* check ORDER BY even if it can be ignored */
400   if (order)
401   {
402     TABLE_LIST   tables;
403     List<Item>   fields;
404     List<Item>   all_fields;
405 
406     bzero((char*) &tables,sizeof(tables));
407     tables.table = table;
408     tables.alias = table_list->alias;
409 
410       if (select_lex->setup_ref_array(thd, order_list->elements) ||
411 	  setup_order(thd, select_lex->ref_pointer_array, &tables,
412                     fields, all_fields, order))
413     {
414       free_underlaid_joins(thd, thd->lex->first_select_lex());
415       DBUG_RETURN(TRUE);
416     }
417   }
418 
419   /* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
420   if (select_lex->optimize_unflattened_subqueries(false))
421     DBUG_RETURN(TRUE);
422 
423   const_cond= (!conds || conds->const_item());
424   safe_update= MY_TEST(thd->variables.option_bits & OPTION_SAFE_UPDATES);
425   if (safe_update && const_cond)
426   {
427     my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
428                ER_THD(thd, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
429     DBUG_RETURN(TRUE);
430   }
431 
432   const_cond_result= const_cond && (!conds || conds->val_int());
433   if (unlikely(thd->is_error()))
434   {
435     /* Error evaluating val_int(). */
436     DBUG_RETURN(TRUE);
437   }
438 
439   /*
440     Test if the user wants to delete all rows and deletion doesn't have
441     any side-effects (because of triggers), so we can use optimized
442     handler::delete_all_rows() method.
443 
444     We can use delete_all_rows() if and only if:
445     - We allow new functions (not using option --skip-new), and are
446       not in safe mode (not using option --safe-mode)
447     - There is no limit clause
448     - The condition is constant
449     - If there is a condition, then it it produces a non-zero value
450     - If the current command is DELETE FROM with no where clause, then:
451       - We should not be binlogging this statement in row-based, and
452       - there should be no delete triggers associated with the table.
453   */
454 
455   has_triggers= table->triggers && table->triggers->has_delete_triggers();
456 
457   if (!with_select && !using_limit && const_cond_result &&
458       (!thd->is_current_stmt_binlog_format_row() &&
459        !has_triggers)
460       && !table->versioned(VERS_TIMESTAMP) && !table_list->has_period())
461   {
462     /* Update the table->file->stats.records number */
463     table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
464     ha_rows const maybe_deleted= table->file->stats.records;
465     DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
466 
467     query_plan.set_delete_all_rows(maybe_deleted);
468     if (thd->lex->describe)
469       goto produce_explain_and_leave;
470 
471     if (likely(!(error=table->file->ha_delete_all_rows())))
472     {
473       /*
474         If delete_all_rows() is used, it is not possible to log the
475         query in row format, so we have to log it in statement format.
476       */
477       query_type= THD::STMT_QUERY_TYPE;
478       error= -1;
479       deleted= maybe_deleted;
480       if (!query_plan.save_explain_delete_data(thd->mem_root, thd))
481         error= 1;
482       goto cleanup;
483     }
484     if (error != HA_ERR_WRONG_COMMAND)
485     {
486       table->file->print_error(error,MYF(0));
487       error=0;
488       goto cleanup;
489     }
490     /* Handler didn't support fast delete; Delete rows one by one */
491     query_plan.cancel_delete_all_rows();
492   }
493   if (conds)
494   {
495     Item::cond_result result;
496     conds= conds->remove_eq_conds(thd, &result, true);
497     if (result == Item::COND_FALSE)             // Impossible where
498     {
499       limit= 0;
500       query_plan.set_impossible_where();
501       if (thd->lex->describe || thd->lex->analyze_stmt)
502         goto produce_explain_and_leave;
503     }
504   }
505 
506 #ifdef WITH_PARTITION_STORAGE_ENGINE
507   if (prune_partitions(thd, table, conds))
508   {
509     free_underlaid_joins(thd, select_lex);
510 
511     query_plan.set_no_partitions();
512     if (thd->lex->describe || thd->lex->analyze_stmt)
513       goto produce_explain_and_leave;
514 
515     my_ok(thd, 0);
516     DBUG_RETURN(0);
517   }
518 #endif
519   /* Update the table->file->stats.records number */
520   table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
521   set_statistics_for_table(thd, table);
522 
523   table->covering_keys.clear_all();
524   table->quick_keys.clear_all();		// Can't use 'only index'
525 
526   select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error);
527   if (unlikely(error))
528     DBUG_RETURN(TRUE);
529   if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
530   {
531     query_plan.set_impossible_where();
532     if (thd->lex->describe || thd->lex->analyze_stmt)
533       goto produce_explain_and_leave;
534 
535     delete select;
536     free_underlaid_joins(thd, select_lex);
537     /*
538       Error was already created by quick select evaluation (check_quick()).
539       TODO: Add error code output parameter to Item::val_xxx() methods.
540       Currently they rely on the user checking DA for
541       errors when unwinding the stack after calling Item::val_xxx().
542     */
543     if (unlikely(thd->is_error()))
544       DBUG_RETURN(TRUE);
545     my_ok(thd, 0);
546     DBUG_RETURN(0);				// Nothing to delete
547   }
548 
549   /* If running in safe sql mode, don't allow updates without keys */
550   if (table->quick_keys.is_clear_all())
551   {
552     thd->set_status_no_index_used();
553     if (safe_update && !using_limit)
554     {
555       delete select;
556       free_underlaid_joins(thd, select_lex);
557       my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
558                  ER_THD(thd, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
559       DBUG_RETURN(TRUE);
560     }
561   }
562   if (options & OPTION_QUICK)
563     (void) table->file->extra(HA_EXTRA_QUICK);
564 
565   query_plan.scanned_rows= select? select->records: table->file->stats.records;
566   if (order)
567   {
568     table->update_const_key_parts(conds);
569     order= simple_remove_const(order, conds);
570 
571     if (select && select->quick && select->quick->unique_key_range())
572     { // Single row select (always "ordered")
573       query_plan.using_filesort= FALSE;
574       query_plan.index= MAX_KEY;
575     }
576     else
577     {
578       ha_rows scanned_limit= query_plan.scanned_rows;
579       query_plan.index= get_index_for_order(order, table, select, limit,
580                                             &scanned_limit,
581                                             &query_plan.using_filesort,
582                                             &reverse);
583       if (!query_plan.using_filesort)
584         query_plan.scanned_rows= scanned_limit;
585     }
586   }
587 
588   query_plan.select= select;
589   query_plan.possible_keys= select? select->possible_keys: key_map(0);
590 
591   /*
592     Ok, we have generated a query plan for the DELETE.
593      - if we're running EXPLAIN DELETE, goto produce explain output
594      - otherwise, execute the query plan
595   */
596   if (thd->lex->describe)
597     goto produce_explain_and_leave;
598 
599   if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd)))
600     goto got_error;
601   ANALYZE_START_TRACKING(&explain->command_tracker);
602 
603   DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
604                   dbug_serve_apcs(thd, 1););
605 
606   if (!(select && select->quick))
607     status_var_increment(thd->status_var.delete_scan_count);
608 
609   binlog_is_row= thd->is_current_stmt_binlog_format_row();
610   DBUG_PRINT("info", ("binlog_is_row: %s", binlog_is_row ? "TRUE" : "FALSE"));
611 
612   /*
613     We can use direct delete (delete that is done silently in the handler)
614     if none of the following conditions are true:
615     - There are triggers
616     - There is binary logging
617     - There is a virtual not stored column in the WHERE clause
618     - ORDER BY or LIMIT
619       - As this requires the rows to be deleted in a specific order
620       - Note that Spider can handle ORDER BY and LIMIT in a cluster with
621         one data node.  These conditions are therefore checked in
622         direct_delete_rows_init().
623 
624     Direct delete does not require a WHERE clause
625 
626     Later we also ensure that we are only using one table (no sub queries)
627   */
628 
629   if ((table->file->ha_table_flags() & HA_CAN_DIRECT_UPDATE_AND_DELETE) &&
630       !has_triggers && !binlog_is_row && !with_select &&
631       !table_list->has_period())
632   {
633     table->mark_columns_needed_for_delete();
634     if (!table->check_virtual_columns_marked_for_read())
635     {
636       DBUG_PRINT("info", ("Trying direct delete"));
637       bool use_direct_delete= !select || !select->cond;
638       if (!use_direct_delete &&
639           (select->cond->used_tables() & ~RAND_TABLE_BIT) == table->map)
640       {
641         DBUG_ASSERT(!table->file->pushed_cond);
642         if (!table->file->cond_push(select->cond))
643         {
644           use_direct_delete= TRUE;
645           table->file->pushed_cond= select->cond;
646         }
647       }
648       if (use_direct_delete && !table->file->direct_delete_rows_init())
649       {
650         /* Direct deleting is supported */
651         DBUG_PRINT("info", ("Using direct delete"));
652         THD_STAGE_INFO(thd, stage_updating);
653         if (!(error= table->file->ha_direct_delete_rows(&deleted)))
654           error= -1;
655         goto terminate_delete;
656       }
657     }
658   }
659 
660   if (query_plan.using_filesort)
661   {
662     {
663       Filesort fsort(order, HA_POS_ERROR, true, select);
664       DBUG_ASSERT(query_plan.index == MAX_KEY);
665 
666       Filesort_tracker *fs_tracker=
667         thd->lex->explain->get_upd_del_plan()->filesort_tracker;
668 
669       if (!(file_sort= filesort(thd, table, &fsort, fs_tracker)))
670         goto got_error;
671 
672       thd->inc_examined_row_count(file_sort->examined_rows);
673       /*
674         Filesort has already found and selected the rows we want to delete,
675         so we don't need the where clause
676       */
677       delete select;
678 
679       /*
680         If we are not in DELETE ... RETURNING, we can free subqueries. (in
681         DELETE ... RETURNING we can't, because the RETURNING part may have
682         a subquery in it)
683       */
684       if (!with_select)
685         free_underlaid_joins(thd, select_lex);
686       select= 0;
687     }
688   }
689 
690   /* If quick select is used, initialize it before retrieving rows. */
691   if (select && select->quick && select->quick->reset())
692     goto got_error;
693 
694   if (query_plan.index == MAX_KEY || (select && select->quick))
695     error= init_read_record(&info, thd, table, select, file_sort, 1, 1, FALSE);
696   else
697     error= init_read_record_idx(&info, thd, table, 1, query_plan.index,
698                                 reverse);
699   if (unlikely(error))
700     goto got_error;
701 
702   if (unlikely(init_ftfuncs(thd, select_lex, 1)))
703     goto got_error;
704 
705   if (table_list->has_period())
706   {
707     table->use_all_columns();
708     table->rpl_write_set= table->write_set;
709   }
710   else
711   {
712     table->mark_columns_needed_for_delete();
713   }
714 
715   if ((table->file->ha_table_flags() & HA_CAN_FORCE_BULK_DELETE) &&
716       !table->prepare_triggers_for_delete_stmt_or_event())
717     will_batch= !table->file->start_bulk_delete();
718 
719   if (with_select)
720   {
721     if (unlikely(result->send_result_set_metadata(select_lex->item_list,
722                                                   Protocol::SEND_NUM_ROWS |
723                                                   Protocol::SEND_EOF)))
724       goto cleanup;
725   }
726 
727   explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan();
728   explain->tracker.on_scan_init();
729 
730   if (!delete_while_scanning)
731   {
732     /*
733       The table we are going to delete appears in subqueries in the where
734       clause.  Instead of deleting the rows, first mark them deleted.
735     */
736     ha_rows tmplimit=limit;
737     deltempfile= new (thd->mem_root) Unique (refpos_order_cmp, table->file,
738                                              table->file->ref_length,
739                                              MEM_STRIP_BUF_SIZE);
740 
741     THD_STAGE_INFO(thd, stage_searching_rows_for_update);
742     while (!(error=info.read_record()) && !thd->killed &&
743           ! thd->is_error())
744     {
745       if (record_should_be_deleted(thd, table, select, explain, delete_history))
746       {
747         table->file->position(table->record[0]);
748         if (unlikely((error=
749                       deltempfile->unique_add((char*) table->file->ref))))
750         {
751           error= 1;
752           goto terminate_delete;
753         }
754         if (!--tmplimit && using_limit)
755           break;
756       }
757     }
758     end_read_record(&info);
759     if (unlikely(deltempfile->get(table)) ||
760         unlikely(table->file->ha_index_or_rnd_end()) ||
761         unlikely(init_read_record(&info, thd, table, 0, &deltempfile->sort, 0,
762                                   1, false)))
763     {
764       error= 1;
765       goto terminate_delete;
766     }
767     delete_record= true;
768   }
769 
770   /*
771     From SQL2016, Part 2, 15.7 <Effect of deleting rows from base table>,
772     General Rules, 8), we can conclude that DELETE FOR PORTTION OF time performs
773     0-2 INSERTS + DELETE. We can substitute INSERT+DELETE with one UPDATE, with
774     a condition of no side effects. The side effect is possible if there is a
775     BEFORE INSERT trigger, since it is the only one splitting DELETE and INSERT
776     operations.
777     Another possible side effect is related to tables of non-transactional
778     engines, since UPDATE is anyway atomic, and DELETE+INSERT is not.
779 
780     This optimization is not possible for system-versioned table.
781   */
782   portion_of_time_through_update=
783           !(table->triggers && table->triggers->has_triggers(TRG_EVENT_INSERT,
784                                                              TRG_ACTION_BEFORE))
785           && !table->versioned()
786           && table->file->has_transactions();
787 
788   THD_STAGE_INFO(thd, stage_updating);
789   while (likely(!(error=info.read_record())) && likely(!thd->killed) &&
790          likely(!thd->is_error()))
791   {
792     if (delete_while_scanning)
793       delete_record= record_should_be_deleted(thd, table, select, explain,
794                                               delete_history);
795     if (delete_record)
796     {
797       if (!delete_history && table->triggers &&
798           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
799                                             TRG_ACTION_BEFORE, FALSE))
800       {
801         error= 1;
802         break;
803       }
804 
805       if (with_select && result->send_data(select_lex->item_list) < 0)
806       {
807         error=1;
808         break;
809       }
810 
811       if (table_list->has_period() && portion_of_time_through_update)
812       {
813         bool need_delete= true;
814         error= update_portion_of_time(thd, table, table_list->period_conditions,
815                                       &need_delete);
816         if (likely(!error) && need_delete)
817           error= table->delete_row();
818       }
819       else
820       {
821         error= table->delete_row();
822 
823         ha_rows rows_inserted;
824         if (likely(!error) && table_list->has_period()
825             && !portion_of_time_through_update)
826           error= table->insert_portion_of_time(thd, table_list->period_conditions,
827                                                &rows_inserted);
828       }
829 
830       if (likely(!error))
831       {
832 	deleted++;
833         if (!delete_history && table->triggers &&
834             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
835                                               TRG_ACTION_AFTER, FALSE))
836         {
837           error= 1;
838           break;
839         }
840 	if (!--limit && using_limit)
841 	{
842 	  error= -1;
843 	  break;
844 	}
845       }
846       else
847       {
848 	table->file->print_error(error,
849                                  MYF(thd->lex->ignore ? ME_WARNING : 0));
850         if (thd->is_error())
851         {
852           error= 1;
853           break;
854         }
855       }
856     }
857     /*
858       Don't try unlocking the row if skip_record reported an error since in
859       this case the transaction might have been rolled back already.
860     */
861     else if (likely(!thd->is_error()))
862       table->file->unlock_row();  // Row failed selection, release lock on it
863     else
864       break;
865   }
866 
867 terminate_delete:
868   killed_status= thd->killed;
869   if (unlikely(killed_status != NOT_KILLED || thd->is_error()))
870     error= 1;					// Aborted
871   if (will_batch && unlikely((loc_error= table->file->end_bulk_delete())))
872   {
873     if (error != 1)
874       table->file->print_error(loc_error,MYF(0));
875     error=1;
876   }
877   THD_STAGE_INFO(thd, stage_end);
878   end_read_record(&info);
879   if (table_list->has_period())
880     table->file->ha_release_auto_increment();
881   if (options & OPTION_QUICK)
882     (void) table->file->extra(HA_EXTRA_NORMAL);
883   ANALYZE_STOP_TRACKING(&explain->command_tracker);
884 
885 cleanup:
886   /*
887     Invalidate the table in the query cache if something changed. This must
888     be before binlog writing and ha_autocommit_...
889   */
890   if (deleted)
891   {
892     query_cache_invalidate3(thd, table_list, 1);
893   }
894 
895   if (thd->lex->current_select->first_cond_optimization)
896   {
897     thd->lex->current_select->save_leaf_tables(thd);
898     thd->lex->current_select->first_cond_optimization= 0;
899   }
900 
901   delete deltempfile;
902   deltempfile=NULL;
903   delete select;
904   select= NULL;
905   transactional_table= table->file->has_transactions();
906 
907   if (!transactional_table && deleted > 0)
908     thd->transaction.stmt.modified_non_trans_table=
909       thd->transaction.all.modified_non_trans_table= TRUE;
910 
911   /* See similar binlogging code in sql_update.cc, for comments */
912   if (likely((error < 0) || thd->transaction.stmt.modified_non_trans_table))
913   {
914     if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
915     {
916       int errcode= 0;
917       if (error < 0)
918         thd->clear_error();
919       else
920         errcode= query_error_code(thd, killed_status == NOT_KILLED);
921 
922       ScopedStatementReplication scoped_stmt_rpl(
923           table->versioned(VERS_TRX_ID) ? thd : NULL);
924       /*
925         [binlog]: If 'handler::delete_all_rows()' was called and the
926         storage engine does not inject the rows itself, we replicate
927         statement-based; otherwise, 'ha_delete_row()' was used to
928         delete specific rows which we might log row-based.
929       */
930       int log_result= thd->binlog_query(query_type,
931                                         thd->query(), thd->query_length(),
932                                         transactional_table, FALSE, FALSE,
933                                         errcode);
934 
935       if (log_result > 0)
936       {
937 	error=1;
938       }
939     }
940   }
941   DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
942 
943   if (likely(error < 0) ||
944       (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
945   {
946     if (thd->lex->analyze_stmt)
947       goto send_nothing_and_leave;
948 
949     if (with_select)
950       result->send_eof();
951     else
952       my_ok(thd, deleted);
953     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
954   }
955   delete file_sort;
956   free_underlaid_joins(thd, select_lex);
957   if (table->file->pushed_cond)
958     table->file->cond_pop();
959   DBUG_RETURN(error >= 0 || thd->is_error());
960 
961   /* Special exits */
962 produce_explain_and_leave:
963   /*
964     We come here for various "degenerate" query plans: impossible WHERE,
965     no-partitions-used, impossible-range, etc.
966   */
967   if (!(query_plan.save_explain_delete_data(thd->mem_root, thd)))
968     goto got_error;
969 
970 send_nothing_and_leave:
971   /*
972     ANALYZE DELETE jumps here. We can't send explain right here, because
973     we might be using ANALYZE DELETE ...RETURNING, in which case we have
974     Protocol_discard active.
975   */
976 
977   delete select;
978   delete file_sort;
979   free_underlaid_joins(thd, select_lex);
980   if (table->file->pushed_cond)
981     table->file->cond_pop();
982 
983   DBUG_ASSERT(!return_error || thd->is_error() || thd->killed);
984   DBUG_RETURN((return_error || thd->is_error() || thd->killed) ? 1 : 0);
985 
986 got_error:
987   return_error= 1;
988   goto send_nothing_and_leave;
989 }
990 
991 
992 /*
993   Prepare items in DELETE statement
994 
995   SYNOPSIS
996     mysql_prepare_delete()
997     thd			- thread handler
998     table_list		- global/local table list
999     wild_num            - number of wildcards used in optional SELECT clause
1000     field_list          - list of items in optional SELECT clause
1001     conds		- conditions
1002 
1003   RETURN VALUE
1004     FALSE OK
1005     TRUE  error
1006 */
mysql_prepare_delete(THD * thd,TABLE_LIST * table_list,uint wild_num,List<Item> & field_list,Item ** conds,bool * delete_while_scanning)1007 int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
1008                          uint wild_num, List<Item> &field_list, Item **conds,
1009                          bool *delete_while_scanning)
1010 {
1011   Item *fake_conds= 0;
1012   SELECT_LEX *select_lex= thd->lex->first_select_lex();
1013   DBUG_ENTER("mysql_prepare_delete");
1014   List<Item> all_fields;
1015 
1016   *delete_while_scanning= true;
1017   thd->lex->allow_sum_func.clear_all();
1018   if (setup_tables_and_check_access(thd,
1019                                     &thd->lex->first_select_lex()->context,
1020                                     &thd->lex->first_select_lex()->
1021                                       top_join_list,
1022                                     table_list,
1023                                     select_lex->leaf_tables, FALSE,
1024                                     DELETE_ACL, SELECT_ACL, TRUE))
1025     DBUG_RETURN(TRUE);
1026 
1027   if (table_list->vers_conditions.is_set() && table_list->is_view_or_derived())
1028   {
1029     my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
1030     DBUG_RETURN(true);
1031   }
1032 
1033   if (table_list->has_period())
1034   {
1035     if (table_list->is_view_or_derived())
1036     {
1037       my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str);
1038       DBUG_RETURN(true);
1039     }
1040 
1041     if (select_lex->period_setup_conds(thd, table_list))
1042       DBUG_RETURN(true);
1043   }
1044 
1045   DBUG_ASSERT(table_list->table);
1046   // conds could be cached from previous SP call
1047   DBUG_ASSERT(!table_list->vers_conditions.need_setup() ||
1048               !*conds || thd->stmt_arena->is_stmt_execute());
1049   if (select_lex->vers_setup_conds(thd, table_list))
1050     DBUG_RETURN(TRUE);
1051 
1052   *conds= select_lex->where;
1053 
1054   if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num,
1055                               &select_lex->hidden_bit_fields)) ||
1056       setup_fields(thd, Ref_ptr_array(),
1057                    field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
1058       setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
1059       setup_ftfuncs(select_lex))
1060     DBUG_RETURN(TRUE);
1061   if (!table_list->single_table_updatable() ||
1062       check_key_in_view(thd, table_list))
1063   {
1064     my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "DELETE");
1065     DBUG_RETURN(TRUE);
1066   }
1067 
1068   /*
1069       Application-time periods: if FOR PORTION OF ... syntax used, DELETE
1070       statement could issue delete_row's mixed with write_row's. This causes
1071       problems for myisam and corrupts table, if deleting while scanning.
1072    */
1073   if (table_list->has_period()
1074       || unique_table(thd, table_list, table_list->next_global, 0))
1075     *delete_while_scanning= false;
1076 
1077   if (select_lex->inner_refs_list.elements &&
1078     fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
1079     DBUG_RETURN(TRUE);
1080 
1081   select_lex->fix_prepare_information(thd, conds, &fake_conds);
1082   DBUG_RETURN(FALSE);
1083 }
1084 
1085 
1086 /***************************************************************************
1087   Delete multiple tables from join
1088 ***************************************************************************/
1089 
1090 
refpos_order_cmp(void * arg,const void * a,const void * b)1091 extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
1092 {
1093   handler *file= (handler*)arg;
1094   return file->cmp_ref((const uchar*)a, (const uchar*)b);
1095 }
1096 
1097 /*
1098   make delete specific preparation and checks after opening tables
1099 
1100   SYNOPSIS
1101     mysql_multi_delete_prepare()
1102     thd         thread handler
1103 
1104   RETURN
1105     FALSE OK
1106     TRUE  Error
1107 */
1108 
mysql_multi_delete_prepare(THD * thd)1109 int mysql_multi_delete_prepare(THD *thd)
1110 {
1111   LEX *lex= thd->lex;
1112   TABLE_LIST *aux_tables= lex->auxiliary_table_list.first;
1113   TABLE_LIST *target_tbl;
1114   DBUG_ENTER("mysql_multi_delete_prepare");
1115 
1116   if (mysql_handle_derived(lex, DT_INIT))
1117     DBUG_RETURN(TRUE);
1118   if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
1119     DBUG_RETURN(TRUE);
1120   if (mysql_handle_derived(lex, DT_PREPARE))
1121     DBUG_RETURN(TRUE);
1122   /*
1123     setup_tables() need for VIEWs. JOIN::prepare() will not do it second
1124     time.
1125 
1126     lex->query_tables also point on local list of DELETE SELECT_LEX
1127   */
1128   if (setup_tables_and_check_access(thd,
1129                                     &thd->lex->first_select_lex()->context,
1130                                     &thd->lex->first_select_lex()->
1131                                       top_join_list,
1132                                     lex->query_tables,
1133                                     lex->first_select_lex()->leaf_tables,
1134                                     FALSE, DELETE_ACL, SELECT_ACL, FALSE))
1135     DBUG_RETURN(TRUE);
1136 
1137   /*
1138     Multi-delete can't be constructed over-union => we always have
1139     single SELECT on top and have to check underlying SELECTs of it
1140   */
1141   lex->first_select_lex()->set_unique_exclude();
1142   /* Fix tables-to-be-deleted-from list to point at opened tables */
1143   for (target_tbl= (TABLE_LIST*) aux_tables;
1144        target_tbl;
1145        target_tbl= target_tbl->next_local)
1146   {
1147 
1148     target_tbl->table= target_tbl->correspondent_table->table;
1149     if (target_tbl->correspondent_table->is_multitable())
1150     {
1151        my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
1152                 target_tbl->correspondent_table->view_db.str,
1153                 target_tbl->correspondent_table->view_name.str);
1154        DBUG_RETURN(TRUE);
1155     }
1156 
1157     if (!target_tbl->correspondent_table->single_table_updatable() ||
1158         check_key_in_view(thd, target_tbl->correspondent_table))
1159     {
1160       my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
1161                target_tbl->table_name.str, "DELETE");
1162       DBUG_RETURN(TRUE);
1163     }
1164   }
1165 
1166   for (target_tbl= (TABLE_LIST*) aux_tables;
1167        target_tbl;
1168        target_tbl= target_tbl->next_local)
1169   {
1170     /*
1171       Check that table from which we delete is not used somewhere
1172       inside subqueries/view.
1173     */
1174     {
1175       TABLE_LIST *duplicate;
1176       if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
1177                                    lex->query_tables, 0)))
1178       {
1179         update_non_unique_table_error(target_tbl->correspondent_table,
1180                                       "DELETE", duplicate);
1181         DBUG_RETURN(TRUE);
1182       }
1183     }
1184   }
1185   /*
1186     Reset the exclude flag to false so it doesn't interfare
1187     with further calls to unique_table
1188   */
1189   lex->first_select_lex()->exclude_from_table_unique_test= FALSE;
1190 
1191   if (lex->save_prep_leaf_tables())
1192     DBUG_RETURN(TRUE);
1193 
1194   DBUG_RETURN(FALSE);
1195 }
1196 
1197 
multi_delete(THD * thd_arg,TABLE_LIST * dt,uint num_of_tables_arg)1198 multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg):
1199     select_result_interceptor(thd_arg), delete_tables(dt), deleted(0), found(0),
1200     num_of_tables(num_of_tables_arg), error(0),
1201     do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
1202 {
1203   tempfiles= (Unique **) thd_arg->calloc(sizeof(Unique *) * num_of_tables);
1204 }
1205 
1206 
1207 int
prepare(List<Item> & values,SELECT_LEX_UNIT * u)1208 multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
1209 {
1210   DBUG_ENTER("multi_delete::prepare");
1211   unit= u;
1212   do_delete= 1;
1213   THD_STAGE_INFO(thd, stage_deleting_from_main_table);
1214   DBUG_RETURN(0);
1215 }
1216 
prepare_to_read_rows()1217 void multi_delete::prepare_to_read_rows()
1218 {
1219   /* see multi_update::prepare_to_read_rows() */
1220   for (TABLE_LIST *walk= delete_tables; walk; walk= walk->next_local)
1221   {
1222     TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
1223     tbl->table->mark_columns_needed_for_delete();
1224   }
1225 }
1226 
1227 bool
initialize_tables(JOIN * join)1228 multi_delete::initialize_tables(JOIN *join)
1229 {
1230   TABLE_LIST *walk;
1231   Unique **tempfiles_ptr;
1232   DBUG_ENTER("initialize_tables");
1233 
1234   if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
1235                error_if_full_join(join)))
1236     DBUG_RETURN(1);
1237 
1238   table_map tables_to_delete_from=0;
1239   delete_while_scanning= true;
1240   for (walk= delete_tables; walk; walk= walk->next_local)
1241   {
1242     TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
1243     tables_to_delete_from|= tbl->table->map;
1244     if (delete_while_scanning &&
1245         unique_table(thd, tbl, join->tables_list, 0))
1246     {
1247       /*
1248         If the table we are going to delete from appears
1249         in join, we need to defer delete. So the delete
1250         doesn't interfers with the scaning of results.
1251       */
1252       delete_while_scanning= false;
1253     }
1254   }
1255 
1256   walk= delete_tables;
1257 
1258   for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS,
1259                                        WITH_CONST_TABLES);
1260        tab;
1261        tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
1262   {
1263     if (!tab->bush_children && tab->table->map & tables_to_delete_from)
1264     {
1265       /* We are going to delete from this table */
1266       TABLE *tbl=walk->table=tab->table;
1267       walk= walk->next_local;
1268       /* Don't use KEYREAD optimization on this table */
1269       tbl->no_keyread=1;
1270       /* Don't use record cache */
1271       tbl->no_cache= 1;
1272       tbl->covering_keys.clear_all();
1273       if (tbl->file->has_transactions())
1274 	transactional_tables= 1;
1275       else
1276 	normal_tables= 1;
1277       tbl->prepare_triggers_for_delete_stmt_or_event();
1278       tbl->prepare_for_position();
1279     }
1280     else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
1281              walk == delete_tables)
1282     {
1283       /*
1284         We are not deleting from the table we are scanning. In this
1285         case send_data() shouldn't delete any rows a we may touch
1286         the rows in the deleted table many times
1287       */
1288       delete_while_scanning= false;
1289     }
1290   }
1291   walk= delete_tables;
1292   tempfiles_ptr= tempfiles;
1293   if (delete_while_scanning)
1294   {
1295     table_being_deleted= delete_tables;
1296     walk= walk->next_local;
1297   }
1298   for (;walk ;walk= walk->next_local)
1299   {
1300     TABLE *table=walk->table;
1301     *tempfiles_ptr++= new (thd->mem_root) Unique (refpos_order_cmp, table->file,
1302                                                   table->file->ref_length,
1303                                                   MEM_STRIP_BUF_SIZE);
1304   }
1305   init_ftfuncs(thd, thd->lex->current_select, 1);
1306   DBUG_RETURN(thd->is_fatal_error);
1307 }
1308 
1309 
~multi_delete()1310 multi_delete::~multi_delete()
1311 {
1312   for (table_being_deleted= delete_tables;
1313        table_being_deleted;
1314        table_being_deleted= table_being_deleted->next_local)
1315   {
1316     TABLE *table= table_being_deleted->table;
1317     table->no_keyread=0;
1318     table->no_cache= 0;
1319   }
1320 
1321   for (uint counter= 0; counter < num_of_tables; counter++)
1322   {
1323     if (tempfiles[counter])
1324       delete tempfiles[counter];
1325   }
1326 }
1327 
1328 
send_data(List<Item> & values)1329 int multi_delete::send_data(List<Item> &values)
1330 {
1331   int secure_counter= delete_while_scanning ? -1 : 0;
1332   TABLE_LIST *del_table;
1333   DBUG_ENTER("multi_delete::send_data");
1334 
1335   bool ignore= thd->lex->ignore;
1336 
1337   for (del_table= delete_tables;
1338        del_table;
1339        del_table= del_table->next_local, secure_counter++)
1340   {
1341     TABLE *table= del_table->table;
1342 
1343     /* Check if we are using outer join and we didn't find the row */
1344     if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
1345       continue;
1346 
1347     table->file->position(table->record[0]);
1348     found++;
1349 
1350     if (secure_counter < 0)
1351     {
1352       /* We are scanning the current table */
1353       DBUG_ASSERT(del_table == table_being_deleted);
1354       if (table->triggers &&
1355           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1356                                             TRG_ACTION_BEFORE, FALSE))
1357         DBUG_RETURN(1);
1358       table->status|= STATUS_DELETED;
1359 
1360       error= table->delete_row();
1361       if (likely(!error))
1362       {
1363         deleted++;
1364         if (!table->file->has_transactions())
1365           thd->transaction.stmt.modified_non_trans_table= TRUE;
1366         if (table->triggers &&
1367             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1368                                               TRG_ACTION_AFTER, FALSE))
1369           DBUG_RETURN(1);
1370       }
1371       else if (!ignore)
1372       {
1373         /*
1374           If the IGNORE option is used errors caused by ha_delete_row don't
1375           have to stop the iteration.
1376         */
1377         table->file->print_error(error,MYF(0));
1378         DBUG_RETURN(1);
1379       }
1380     }
1381     else
1382     {
1383       error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
1384       if (unlikely(error))
1385       {
1386 	error= 1;                               // Fatal error
1387 	DBUG_RETURN(1);
1388       }
1389     }
1390   }
1391   DBUG_RETURN(0);
1392 }
1393 
1394 
abort_result_set()1395 void multi_delete::abort_result_set()
1396 {
1397   DBUG_ENTER("multi_delete::abort_result_set");
1398 
1399   /* the error was handled or nothing deleted and no side effects return */
1400   if (error_handled ||
1401       (!thd->transaction.stmt.modified_non_trans_table && !deleted))
1402     DBUG_VOID_RETURN;
1403 
1404   /* Something already deleted so we have to invalidate cache */
1405   if (deleted)
1406     query_cache_invalidate3(thd, delete_tables, 1);
1407 
1408   if (thd->transaction.stmt.modified_non_trans_table)
1409     thd->transaction.all.modified_non_trans_table= TRUE;
1410   thd->transaction.all.m_unsafe_rollback_flags|=
1411     (thd->transaction.stmt.m_unsafe_rollback_flags & THD_TRANS::DID_WAIT);
1412 
1413   /*
1414     If rows from the first table only has been deleted and it is
1415     transactional, just do rollback.
1416     The same if all tables are transactional, regardless of where we are.
1417     In all other cases do attempt deletes ...
1418   */
1419   if (do_delete && normal_tables &&
1420       (table_being_deleted != delete_tables ||
1421        !table_being_deleted->table->file->has_transactions()))
1422   {
1423     /*
1424       We have to execute the recorded do_deletes() and write info into the
1425       error log
1426     */
1427     error= 1;
1428     send_eof();
1429     DBUG_ASSERT(error_handled);
1430     DBUG_VOID_RETURN;
1431   }
1432 
1433   if (thd->transaction.stmt.modified_non_trans_table)
1434   {
1435     /*
1436        there is only side effects; to binlog with the error
1437     */
1438     if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
1439     {
1440       int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
1441       /* possible error of writing binary log is ignored deliberately */
1442       (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
1443                                thd->query(), thd->query_length(),
1444                                transactional_tables, FALSE, FALSE, errcode);
1445     }
1446   }
1447   DBUG_VOID_RETURN;
1448 }
1449 
1450 
1451 
1452 /**
1453   Do delete from other tables.
1454 
1455   @retval 0 ok
1456   @retval 1 error
1457 
1458   @todo Is there any reason not use the normal nested-loops join? If not, and
1459   there is no documentation supporting it, this method and callee should be
1460   removed and there should be hooks within normal execution.
1461 */
1462 
do_deletes()1463 int multi_delete::do_deletes()
1464 {
1465   DBUG_ENTER("do_deletes");
1466   DBUG_ASSERT(do_delete);
1467 
1468   do_delete= 0;                                 // Mark called
1469   if (!found)
1470     DBUG_RETURN(0);
1471 
1472   table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
1473                         delete_tables);
1474 
1475   for (uint counter= 0; table_being_deleted;
1476        table_being_deleted= table_being_deleted->next_local, counter++)
1477   {
1478     TABLE *table = table_being_deleted->table;
1479     int local_error;
1480     if (unlikely(tempfiles[counter]->get(table)))
1481       DBUG_RETURN(1);
1482 
1483     local_error= do_table_deletes(table, &tempfiles[counter]->sort,
1484                                   thd->lex->ignore);
1485 
1486     if (unlikely(thd->killed) && likely(!local_error))
1487       DBUG_RETURN(1);
1488 
1489     if (unlikely(local_error == -1))            // End of file
1490       local_error= 0;
1491 
1492     if (unlikely(local_error))
1493       DBUG_RETURN(local_error);
1494   }
1495   DBUG_RETURN(0);
1496 }
1497 
1498 
1499 /**
1500    Implements the inner loop of nested-loops join within multi-DELETE
1501    execution.
1502 
1503    @param table The table from which to delete.
1504 
1505    @param ignore If used, all non fatal errors will be translated
1506    to warnings and we should not break the row-by-row iteration.
1507 
1508    @return Status code
1509 
1510    @retval  0 All ok.
1511    @retval  1 Triggers or handler reported error.
1512    @retval -1 End of file from handler.
1513 */
do_table_deletes(TABLE * table,SORT_INFO * sort_info,bool ignore)1514 int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info,
1515                                    bool ignore)
1516 {
1517   int local_error= 0;
1518   READ_RECORD info;
1519   ha_rows last_deleted= deleted;
1520   DBUG_ENTER("do_deletes_for_table");
1521 
1522   if (unlikely(init_read_record(&info, thd, table, NULL, sort_info, 0, 1,
1523                                 FALSE)))
1524     DBUG_RETURN(1);
1525 
1526   bool will_batch= !table->file->start_bulk_delete();
1527   while (likely(!(local_error= info.read_record())) && likely(!thd->killed))
1528   {
1529     if (table->triggers &&
1530         unlikely(table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1531                                                    TRG_ACTION_BEFORE, FALSE)))
1532     {
1533       local_error= 1;
1534       break;
1535     }
1536 
1537     local_error= table->delete_row();
1538     if (unlikely(local_error) && !ignore)
1539     {
1540       table->file->print_error(local_error, MYF(0));
1541       break;
1542     }
1543 
1544     /*
1545       Increase the reported number of deleted rows only if no error occurred
1546       during ha_delete_row.
1547       Also, don't execute the AFTER trigger if the row operation failed.
1548     */
1549     if (unlikely(!local_error))
1550     {
1551       deleted++;
1552       if (table->triggers &&
1553           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1554                                             TRG_ACTION_AFTER, FALSE))
1555       {
1556         local_error= 1;
1557         break;
1558       }
1559     }
1560   }
1561   if (will_batch)
1562   {
1563     int tmp_error= table->file->end_bulk_delete();
1564     if (unlikely(tmp_error) && !local_error)
1565     {
1566       local_error= tmp_error;
1567       table->file->print_error(local_error, MYF(0));
1568     }
1569   }
1570   if (last_deleted != deleted && !table->file->has_transactions())
1571     thd->transaction.stmt.modified_non_trans_table= TRUE;
1572 
1573   end_read_record(&info);
1574 
1575   DBUG_RETURN(local_error);
1576 }
1577 
1578 /*
1579   Send ok to the client
1580 
1581   return:  0 sucess
1582 	   1 error
1583 */
1584 
send_eof()1585 bool multi_delete::send_eof()
1586 {
1587   killed_state killed_status= NOT_KILLED;
1588   THD_STAGE_INFO(thd, stage_deleting_from_reference_tables);
1589 
1590   /* Does deletes for the last n - 1 tables, returns 0 if ok */
1591   int local_error= do_deletes();		// returns 0 if success
1592 
1593   /* compute a total error to know if something failed */
1594   local_error= local_error || error;
1595   killed_status= (local_error == 0)? NOT_KILLED : thd->killed;
1596   /* reset used flags */
1597   THD_STAGE_INFO(thd, stage_end);
1598 
1599   if (thd->transaction.stmt.modified_non_trans_table)
1600     thd->transaction.all.modified_non_trans_table= TRUE;
1601   thd->transaction.all.m_unsafe_rollback_flags|=
1602     (thd->transaction.stmt.m_unsafe_rollback_flags & THD_TRANS::DID_WAIT);
1603 
1604   /*
1605     We must invalidate the query cache before binlog writing and
1606     ha_autocommit_...
1607   */
1608   if (deleted)
1609   {
1610     query_cache_invalidate3(thd, delete_tables, 1);
1611   }
1612   if (likely((local_error == 0) ||
1613              thd->transaction.stmt.modified_non_trans_table))
1614   {
1615     if(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
1616     {
1617       int errcode= 0;
1618       if (likely(local_error == 0))
1619         thd->clear_error();
1620       else
1621         errcode= query_error_code(thd, killed_status == NOT_KILLED);
1622       thd->thread_specific_used= TRUE;
1623       if (unlikely(thd->binlog_query(THD::ROW_QUERY_TYPE,
1624                                      thd->query(), thd->query_length(),
1625                                      transactional_tables, FALSE, FALSE,
1626                                      errcode) > 0) &&
1627           !normal_tables)
1628       {
1629 	local_error=1;  // Log write failed: roll back the SQL statement
1630       }
1631     }
1632   }
1633   if (unlikely(local_error != 0))
1634     error_handled= TRUE; // to force early leave from ::abort_result_set()
1635 
1636   if (likely(!local_error && !thd->lex->analyze_stmt))
1637   {
1638     ::my_ok(thd, deleted);
1639   }
1640   return 0;
1641 }
1642