1 /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /*
24   Delete of records tables.
25 
26   Multi-table deletes were introduced by Monty and Sinisa
27 */
28 
29 #include "sql_priv.h"
30 #include "unireg.h"
31 #include "sql_delete.h"
32 #include "sql_cache.h"                          // query_cache_*
33 #include "sql_base.h"                           // open_temprary_table
34 #include "sql_table.h"                         // build_table_filename
35 #include "sql_view.h"             // check_key_in_view, mysql_frm_type
36 #include "sql_acl.h"              // *_ACL
37 #include "filesort.h"             // filesort
38 #include "sql_select.h"
39 #include "opt_trace.h"                          // Opt_trace_object
40 #include "opt_explain.h"
41 #include "records.h"                            // init_read_record,
42                                                 // end_read_record
43 #include "sql_optimizer.h"                      // remove_eq_conds
44 #include "sql_resolver.h"                       // setup_order, fix_inner_refs
45 
46 /**
47   Implement DELETE SQL word.
48 
49   @note Like implementations of other DDL/DML in MySQL, this function
50   relies on the caller to close the thread tables. This is done in the
51   end of dispatch_command().
52 */
53 
mysql_delete(THD * thd,TABLE_LIST * table_list,Item * conds,SQL_I_List<ORDER> * order_list,ha_rows limit,ulonglong options)54 bool mysql_delete(THD *thd, TABLE_LIST *table_list, Item *conds,
55                   SQL_I_List<ORDER> *order_list, ha_rows limit, ulonglong options)
56 {
57   bool          will_batch;
58   int		error, loc_error;
59   TABLE		*table;
60   SQL_SELECT	*select=0;
61   READ_RECORD	info;
62   bool          using_limit=limit != HA_POS_ERROR;
63   bool		transactional_table, safe_update, const_cond;
64   bool          const_cond_result;
65   ha_rows	deleted= 0;
66   bool          reverse= FALSE;
67   bool          read_removal= false;
68   bool          skip_record;
69   bool          need_sort= FALSE;
70   bool          err= true;
71   ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
72                            order_list->first : NULL);
73   uint usable_index= MAX_KEY;
74   SELECT_LEX   *select_lex= &thd->lex->select_lex;
75   THD::killed_state killed_status= THD::NOT_KILLED;
76   THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
77   DBUG_ENTER("mysql_delete");
78 
79   if (open_normal_and_derived_tables(thd, table_list, 0))
80     DBUG_RETURN(TRUE);
81 
82   if (!(table= table_list->table))
83   {
84     my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
85 	     table_list->view_db.str, table_list->view_name.str);
86     DBUG_RETURN(TRUE);
87   }
88   THD_STAGE_INFO(thd, stage_init);
89   table->map=1;
90 
91   if (mysql_prepare_delete(thd, table_list, &conds))
92     DBUG_RETURN(TRUE);
93 
94   /* check ORDER BY even if it can be ignored */
95   if (order)
96   {
97     TABLE_LIST   tables;
98     List<Item>   fields;
99     List<Item>   all_fields;
100 
101     memset(&tables, 0, sizeof(tables));
102     tables.table = table;
103     tables.alias = table_list->alias;
104 
105       if (select_lex->setup_ref_array(thd, order_list->elements) ||
106 	  setup_order(thd, select_lex->ref_pointer_array, &tables,
107                     fields, all_fields, order))
108     {
109       free_underlaid_joins(thd, &thd->lex->select_lex);
110       DBUG_RETURN(TRUE);
111     }
112   }
113 
114 #ifdef WITH_PARTITION_STORAGE_ENGINE
115   /*
116     Non delete tables are pruned in JOIN::prepare,
117     only the delete table needs this.
118   */
119   if (prune_partitions(thd, table, conds))
120     DBUG_RETURN(true);
121   if (table->all_partitions_pruned_away)
122     goto exit_all_parts_pruned_away;
123 #endif
124 
125   if (lock_tables(thd, table_list, thd->lex->table_count, 0))
126     DBUG_RETURN(true);
127 
128   const_cond= (!conds || conds->const_item());
129   safe_update= MY_TEST(thd->variables.option_bits & OPTION_SAFE_UPDATES);
130   if (safe_update && const_cond)
131   {
132     my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
133                ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
134     DBUG_RETURN(TRUE);
135   }
136 
137   select_lex->no_error= thd->lex->ignore;
138 
139   const_cond_result= const_cond && (!conds || conds->val_int());
140   if (thd->is_error())
141   {
142     /* Error evaluating val_int(). */
143     DBUG_RETURN(TRUE);
144   }
145 
146   /*
147     Test if the user wants to delete all rows and deletion doesn't have
148     any side-effects (because of triggers), so we can use optimized
149     handler::delete_all_rows() method.
150 
151     We can use delete_all_rows() if and only if:
152     - We allow new functions (not using option --skip-new)
153     - There is no limit clause
154     - The condition is constant
155     - If there is a condition, then it it produces a non-zero value
156     - If the current command is DELETE FROM with no where clause, then:
157       - We should not be binlogging this statement in row-based, and
158       - there should be no delete triggers associated with the table.
159   */
160   if (!using_limit && const_cond_result &&
161       !(specialflag & SPECIAL_NO_NEW_FUNC) &&
162        (!thd->is_current_stmt_binlog_format_row() &&
163         !(table->triggers && table->triggers->has_delete_triggers())))
164   {
165     /* Update the table->file->stats.records number */
166     table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
167     ha_rows const maybe_deleted= table->file->stats.records;
168 
169     if (thd->lex->describe)
170     {
171       err= explain_no_table(thd, "Deleting all rows", maybe_deleted);
172       goto exit_without_my_ok;
173     }
174 
175     DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
176     if (!(error=table->file->ha_delete_all_rows()))
177     {
178       /*
179         If delete_all_rows() is used, it is not possible to log the
180         query in row format, so we have to log it in statement format.
181       */
182       query_type= THD::STMT_QUERY_TYPE;
183       error= -1;
184       deleted= maybe_deleted;
185       goto cleanup;
186     }
187     if (error != HA_ERR_WRONG_COMMAND)
188     {
189       table->file->print_error(error,MYF(0));
190       error=0;
191       goto cleanup;
192     }
193     /* Handler didn't support fast delete; Delete rows one by one */
194   }
195 
196   if (conds)
197   {
198     COND_EQUAL *cond_equal= NULL;
199     Item::cond_result result;
200 
201     conds= optimize_cond(thd, conds, &cond_equal, select_lex->join_list,
202                          true, &result);
203     if (result == Item::COND_FALSE)             // Impossible where
204     {
205       limit= 0;
206 
207       if (thd->lex->describe)
208       {
209         err= explain_no_table(thd, "Impossible WHERE");
210         goto exit_without_my_ok;
211       }
212     }
213     if (conds)
214     {
215       conds= substitute_for_best_equal_field(conds, cond_equal, 0);
216       conds->update_used_tables();
217     }
218   }
219 
220   /* Update the table->file->stats.records number */
221   table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
222 
223   table->covering_keys.clear_all();
224   table->quick_keys.clear_all();		// Can't use 'only index'
225   table->possible_quick_keys.clear_all();
226 
227 #ifdef WITH_PARTITION_STORAGE_ENGINE
228   /* Prune a second time to be able to prune on subqueries in WHERE clause. */
229   if (prune_partitions(thd, table, conds))
230     DBUG_RETURN(true);
231   if (table->all_partitions_pruned_away)
232     goto exit_all_parts_pruned_away;
233 #endif
234 
235   select=make_select(table, 0, 0, conds, 0, &error);
236   if (error)
237     DBUG_RETURN(TRUE);
238 
239   { // Enter scope for optimizer trace wrapper
240     Opt_trace_object wrapper(&thd->opt_trace);
241     wrapper.add_utf8_table(table);
242 
243     if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
244     {
245       if (thd->lex->describe && !error && !thd->is_error())
246       {
247         err= explain_no_table(thd, "Impossible WHERE");
248         goto exit_without_my_ok;
249       }
250       delete select;
251       free_underlaid_joins(thd, select_lex);
252       /*
253          Error was already created by quick select evaluation (check_quick()).
254          TODO: Add error code output parameter to Item::val_xxx() methods.
255          Currently they rely on the user checking DA for
256          errors when unwinding the stack after calling Item::val_xxx().
257       */
258       if (thd->is_error())
259         DBUG_RETURN(true);
260       my_ok(thd, 0);
261       DBUG_RETURN(false);                       // Nothing to delete
262     }
263   } // Ends scope for optimizer trace wrapper
264 
265   /* If running in safe sql mode, don't allow updates without keys */
266   if (table->quick_keys.is_clear_all())
267   {
268     thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
269     if (safe_update && !using_limit)
270     {
271       delete select;
272       free_underlaid_joins(thd, select_lex);
273       my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
274                  ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
275       DBUG_RETURN(TRUE);
276     }
277   }
278 
279   if (order)
280   {
281     table->update_const_key_parts(conds);
282     order= simple_remove_const(order, conds);
283 
284     usable_index= get_index_for_order(order, table, select, limit,
285                                       &need_sort, &reverse);
286   }
287 
288   if (thd->lex->describe)
289   {
290     err= explain_single_table_modification(thd, table, select, usable_index,
291                                            limit, false, need_sort, false);
292     goto exit_without_my_ok;
293   }
294 
295   if (options & OPTION_QUICK)
296     (void) table->file->extra(HA_EXTRA_QUICK);
297 
298   if (need_sort)
299   {
300     ha_rows examined_rows;
301     ha_rows found_rows;
302 
303     {
304       Filesort fsort(order, HA_POS_ERROR, select);
305       DBUG_ASSERT(usable_index == MAX_KEY);
306       table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
307                                                    MYF(MY_FAE | MY_ZEROFILL));
308 
309       if ((table->sort.found_records= filesort(thd, table, &fsort, true,
310                                                &examined_rows, &found_rows))
311 	  == HA_POS_ERROR)
312       {
313         goto exit_without_my_ok;
314       }
315       thd->inc_examined_row_count(examined_rows);
316       /*
317         Filesort has already found and selected the rows we want to delete,
318         so we don't need the where clause
319       */
320       delete select;
321       free_underlaid_joins(thd, select_lex);
322       select= 0;
323     }
324   }
325 
326   /* If quick select is used, initialize it before retrieving rows. */
327   if (select && select->quick && (error= select->quick->reset()))
328   {
329     table->file->print_error(error, MYF(0));
330     goto exit_without_my_ok;
331   }
332 
333   if (select_lex->has_ft_funcs() && init_ftfuncs(thd, select_lex, 1))
334     goto exit_without_my_ok;
335 
336   if (usable_index==MAX_KEY || (select && select->quick))
337     error= init_read_record(&info, thd, table, select, 1, 1, FALSE);
338   else
339     error= init_read_record_idx(&info, thd, table, 1, usable_index, reverse);
340 
341   if (error)
342     goto exit_without_my_ok;
343 
344   THD_STAGE_INFO(thd, stage_updating);
345 
346   if (table->triggers &&
347       table->triggers->has_triggers(TRG_EVENT_DELETE,
348                                     TRG_ACTION_AFTER))
349   {
350     /*
351       The table has AFTER DELETE triggers that might access to subject table
352       and therefore might need delete to be done immediately. So we turn-off
353       the batching.
354     */
355     (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
356     will_batch= FALSE;
357   }
358   else
359     will_batch= !table->file->start_bulk_delete();
360 
361   table->mark_columns_needed_for_delete();
362 
363   if ((table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL) &&
364       !using_limit &&
365       !(table->triggers && table->triggers->has_delete_triggers()) &&
366       select && select->quick && select->quick->index != MAX_KEY)
367     read_removal= table->check_read_removal(select->quick->index);
368 
369   while (!(error=info.read_record(&info)) && !thd->killed &&
370 	 ! thd->is_error())
371   {
372     thd->inc_examined_row_count(1);
373     // thd->is_error() is tested to disallow delete row on error
374     if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
375     {
376 
377       if (table->triggers &&
378           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
379                                             TRG_ACTION_BEFORE, FALSE))
380       {
381         error= 1;
382         break;
383       }
384 
385       if (!(error= table->file->ha_delete_row(table->record[0])))
386       {
387 	deleted++;
388         if (table->triggers &&
389             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
390                                               TRG_ACTION_AFTER, FALSE))
391         {
392           error= 1;
393           break;
394         }
395 	if (!--limit && using_limit)
396 	{
397 	  error= -1;
398 	  break;
399 	}
400       }
401       else
402       {
403 	table->file->print_error(error,MYF(0));
404 	/*
405 	  In < 4.0.14 we set the error number to 0 here, but that
406 	  was not sensible, because then MySQL would not roll back the
407 	  failed DELETE, and also wrote it to the binlog. For MyISAM
408 	  tables a DELETE probably never should fail (?), but for
409 	  InnoDB it can fail in a FOREIGN KEY error or an
410 	  out-of-tablespace error.
411 	*/
412  	error= 1;
413 	break;
414       }
415     }
416     /*
417       Don't try unlocking the row if skip_record reported an error since in
418       this case the transaction might have been rolled back already.
419     */
420     else if (!thd->is_error())
421       table->file->unlock_row();  // Row failed selection, release lock on it
422     else
423       break;
424   }
425   killed_status= thd->killed;
426   if (killed_status != THD::NOT_KILLED || thd->is_error())
427     error= 1;					// Aborted
428   if (will_batch && (loc_error= table->file->end_bulk_delete()))
429   {
430     if (error != 1)
431       table->file->print_error(loc_error,MYF(0));
432     error=1;
433   }
434   if (read_removal)
435   {
436     /* Only handler knows how many records were really written */
437     deleted= table->file->end_read_removal();
438   }
439   THD_STAGE_INFO(thd, stage_end);
440   end_read_record(&info);
441   if (options & OPTION_QUICK)
442     (void) table->file->extra(HA_EXTRA_NORMAL);
443 
444 cleanup:
445   DBUG_ASSERT(!thd->lex->describe);
446   /*
447     Invalidate the table in the query cache if something changed. This must
448     be before binlog writing and ha_autocommit_...
449   */
450   if (deleted)
451   {
452     query_cache_invalidate3(thd, table_list, 1);
453   }
454 
455   delete select;
456   select= NULL;
457   transactional_table= table->file->has_transactions();
458 
459   if (!transactional_table && deleted > 0)
460     thd->transaction.stmt.mark_modified_non_trans_table();
461 
462   /* See similar binlogging code in sql_update.cc, for comments */
463   if ((error < 0) || thd->transaction.stmt.cannot_safely_rollback())
464   {
465     if (mysql_bin_log.is_open())
466     {
467       int errcode= 0;
468       if (error < 0)
469         thd->clear_error();
470       else
471         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
472 
473       /*
474         [binlog]: If 'handler::delete_all_rows()' was called and the
475         storage engine does not inject the rows itself, we replicate
476         statement-based; otherwise, 'ha_delete_row()' was used to
477         delete specific rows which we might log row-based.
478       */
479       int log_result= thd->binlog_query(query_type,
480                                         thd->query(), thd->query_length(),
481                                         transactional_table, FALSE, FALSE,
482                                         errcode);
483 
484       if (log_result)
485       {
486 	error=1;
487       }
488     }
489   }
490   DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.cannot_safely_rollback());
491   free_underlaid_joins(thd, select_lex);
492   if (error < 0 ||
493       (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
494   {
495     my_ok(thd, deleted);
496     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
497   }
498   DBUG_RETURN(thd->is_error() || thd->killed);
499 
500 #ifdef WITH_PARTITION_STORAGE_ENGINE
501 exit_all_parts_pruned_away:
502   /* No matching records */
503   if (!thd->lex->describe)
504   {
505     my_ok(thd, 0);
506     DBUG_RETURN(0);
507   }
508   err= explain_no_table(thd, "No matching rows after partition pruning");
509 #endif
510 
511 exit_without_my_ok:
512   delete select;
513   free_underlaid_joins(thd, select_lex);
514   table->set_keyread(false);
515   DBUG_RETURN((err || thd->is_error() || thd->killed) ? 1 : 0);
516 }
517 
518 
519 /*
520   Prepare items in DELETE statement
521 
522   SYNOPSIS
523     mysql_prepare_delete()
524     thd			- thread handler
525     table_list		- global/local table list
526     conds		- conditions
527 
528   RETURN VALUE
529     FALSE OK
530     TRUE  error
531 */
mysql_prepare_delete(THD * thd,TABLE_LIST * table_list,Item ** conds)532 int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
533 {
534   Item *fake_conds= 0;
535   SELECT_LEX *select_lex= &thd->lex->select_lex;
536   DBUG_ENTER("mysql_prepare_delete");
537   List<Item> all_fields;
538 
539   thd->lex->allow_sum_func= 0;
540   if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
541                                     &thd->lex->select_lex.top_join_list,
542                                     table_list,
543                                     &select_lex->leaf_tables, FALSE,
544                                     DELETE_ACL, SELECT_ACL) ||
545       setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
546       setup_ftfuncs(select_lex))
547     DBUG_RETURN(TRUE);
548   if (!table_list->updatable || check_key_in_view(thd, table_list))
549   {
550     my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
551     DBUG_RETURN(TRUE);
552   }
553   {
554     TABLE_LIST *duplicate;
555     if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
556     {
557       update_non_unique_table_error(table_list, "DELETE", duplicate);
558       DBUG_RETURN(TRUE);
559     }
560   }
561 
562   if (select_lex->inner_refs_list.elements &&
563     fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
564     DBUG_RETURN(TRUE);
565 
566   select_lex->fix_prepare_information(thd, conds, &fake_conds);
567   DBUG_RETURN(FALSE);
568 }
569 
570 
571 /***************************************************************************
572   Delete multiple tables from join
573 ***************************************************************************/
574 
575 #define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
576 
refpos_order_cmp(const void * arg,const void * a,const void * b)577 extern "C" int refpos_order_cmp(const void* arg, const void *a,const void *b)
578 {
579   handler *file= (handler*)arg;
580   return file->cmp_ref((const uchar*)a, (const uchar*)b);
581 }
582 
583 /**
584   Make delete specific preparation and checks after opening tables.
585 
586   @param      thd          Thread context.
587   @param[out] table_count  Number of tables to be deleted from.
588 
589   @retval false - success.
590   @retval true  - error.
591 */
592 
mysql_multi_delete_prepare(THD * thd,uint * table_count)593 int mysql_multi_delete_prepare(THD *thd, uint *table_count)
594 {
595   LEX *lex= thd->lex;
596   TABLE_LIST *aux_tables= lex->auxiliary_table_list.first;
597   TABLE_LIST *target_tbl;
598   DBUG_ENTER("mysql_multi_delete_prepare");
599 
600   /*
601     setup_tables() need for VIEWs. JOIN::prepare() will not do it second
602     time.
603 
604     lex->query_tables also point on local list of DELETE SELECT_LEX
605   */
606   if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
607                                     &thd->lex->select_lex.top_join_list,
608                                     lex->query_tables,
609                                     &lex->select_lex.leaf_tables, FALSE,
610                                     DELETE_ACL, SELECT_ACL))
611     DBUG_RETURN(TRUE);
612 
613   *table_count= 0;
614 
615   /*
616     Multi-delete can't be constructed over-union => we always have
617     single SELECT on top and have to check underlying SELECTs of it
618   */
619   lex->select_lex.exclude_from_table_unique_test= TRUE;
620   /* Fix tables-to-be-deleted-from list to point at opened tables */
621   for (target_tbl= (TABLE_LIST*) aux_tables;
622        target_tbl;
623        target_tbl= target_tbl->next_local)
624   {
625     ++(*table_count);
626 
627     if (!(target_tbl->table= target_tbl->correspondent_table->table))
628     {
629       DBUG_ASSERT(target_tbl->correspondent_table->view &&
630                   target_tbl->correspondent_table->multitable_view);
631       my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
632                target_tbl->correspondent_table->view_db.str,
633                target_tbl->correspondent_table->view_name.str);
634       DBUG_RETURN(TRUE);
635     }
636 
637     if (!target_tbl->correspondent_table->updatable ||
638         check_key_in_view(thd, target_tbl->correspondent_table))
639     {
640       my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
641                target_tbl->table_name, "DELETE");
642       DBUG_RETURN(TRUE);
643     }
644     /*
645       Check that table from which we delete is not used somewhere
646       inside subqueries/view.
647     */
648     {
649       TABLE_LIST *duplicate;
650       if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
651                                    lex->query_tables, 0)))
652       {
653         update_non_unique_table_error(target_tbl->correspondent_table,
654                                       "DELETE", duplicate);
655         DBUG_RETURN(TRUE);
656       }
657     }
658   }
659   /*
660     Reset the exclude flag to false so it doesn't interfare
661     with further calls to unique_table
662   */
663   lex->select_lex.exclude_from_table_unique_test= FALSE;
664   DBUG_RETURN(FALSE);
665 }
666 
667 
multi_delete(TABLE_LIST * dt,uint num_of_tables_arg)668 multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
669   : delete_tables(dt), deleted(0), found(0),
670     num_of_tables(num_of_tables_arg), error(0),
671     do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
672 {
673   tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
674 }
675 
676 
677 int
prepare(List<Item> & values,SELECT_LEX_UNIT * u)678 multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
679 {
680   DBUG_ENTER("multi_delete::prepare");
681   unit= u;
682   do_delete= 1;
683   THD_STAGE_INFO(thd, stage_deleting_from_main_table);
684   DBUG_RETURN(0);
685 }
686 
687 
688 bool
initialize_tables(JOIN * join)689 multi_delete::initialize_tables(JOIN *join)
690 {
691   TABLE_LIST *walk;
692   Unique **tempfiles_ptr;
693   DBUG_ENTER("initialize_tables");
694 
695   if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join))
696     DBUG_RETURN(1);
697 
698   table_map tables_to_delete_from=0;
699   delete_while_scanning= 1;
700   for (walk= delete_tables; walk; walk= walk->next_local)
701   {
702     tables_to_delete_from|= walk->table->map;
703     if (delete_while_scanning &&
704         unique_table(thd, walk, join->tables_list, false))
705     {
706       /*
707         If the table we are going to delete from appears
708         in join, we need to defer delete. So the delete
709         doesn't interfers with the scaning of results.
710       */
711       delete_while_scanning= 0;
712     }
713   }
714 
715 
716   walk= delete_tables;
717   for (uint i= 0; i < join->primary_tables; i++)
718   {
719     JOIN_TAB *const tab= join->join_tab + i;
720     if (tab->table->map & tables_to_delete_from)
721     {
722       /* We are going to delete from this table */
723       TABLE *tbl=walk->table=tab->table;
724       walk= walk->next_local;
725       /* Don't use KEYREAD optimization on this table */
726       tbl->no_keyread=1;
727       /* Don't use record cache */
728       tbl->no_cache= 1;
729       tbl->covering_keys.clear_all();
730       if (tbl->file->has_transactions())
731 	transactional_tables= 1;
732       else
733 	normal_tables= 1;
734       if (tbl->triggers &&
735           tbl->triggers->has_triggers(TRG_EVENT_DELETE,
736                                       TRG_ACTION_AFTER))
737       {
738 	/*
739           The table has AFTER DELETE triggers that might access to subject
740           table and therefore might need delete to be done immediately.
741           So we turn-off the batching.
742         */
743 	(void) tbl->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
744       }
745       tbl->prepare_for_position();
746       tbl->mark_columns_needed_for_delete();
747     }
748     else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
749              walk == delete_tables)
750     {
751       /*
752         We are not deleting from the table we are scanning. In this
753         case send_data() shouldn't delete any rows a we may touch
754         the rows in the deleted table many times
755       */
756       delete_while_scanning= 0;
757     }
758   }
759   walk= delete_tables;
760   tempfiles_ptr= tempfiles;
761   if (delete_while_scanning)
762   {
763     table_being_deleted= delete_tables;
764     walk= walk->next_local;
765   }
766   for (;walk ;walk= walk->next_local)
767   {
768     TABLE *table=walk->table;
769     *tempfiles_ptr++= new Unique (refpos_order_cmp,
770 				  (void *) table->file,
771 				  table->file->ref_length,
772 				  MEM_STRIP_BUF_SIZE);
773   }
774   if (thd->lex->current_select->has_ft_funcs() &&
775       init_ftfuncs(thd, thd->lex->current_select, 1))
776      DBUG_RETURN(true);
777 
778   DBUG_RETURN(thd->is_fatal_error != 0);
779 }
780 
781 
~multi_delete()782 multi_delete::~multi_delete()
783 {
784   for (table_being_deleted= delete_tables;
785        table_being_deleted;
786        table_being_deleted= table_being_deleted->next_local)
787   {
788     TABLE *table= table_being_deleted->table;
789     table->no_keyread=0;
790   }
791 
792   for (uint counter= 0; counter < num_of_tables; counter++)
793   {
794     if (tempfiles[counter])
795       delete tempfiles[counter];
796   }
797 }
798 
799 
send_data(List<Item> & values)800 bool multi_delete::send_data(List<Item> &values)
801 {
802   int secure_counter= delete_while_scanning ? -1 : 0;
803   TABLE_LIST *del_table;
804   DBUG_ENTER("multi_delete::send_data");
805 
806   bool ignore= thd->lex->current_select->no_error;
807 
808   for (del_table= delete_tables;
809        del_table;
810        del_table= del_table->next_local, secure_counter++)
811   {
812     TABLE *table= del_table->table;
813 
814     /* Check if we are using outer join and we didn't find the row */
815     if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
816       continue;
817 
818     table->file->position(table->record[0]);
819     found++;
820 
821     if (secure_counter < 0)
822     {
823       /* We are scanning the current table */
824       DBUG_ASSERT(del_table == table_being_deleted);
825       if (table->triggers &&
826           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
827                                             TRG_ACTION_BEFORE, FALSE))
828         DBUG_RETURN(1);
829       table->status|= STATUS_DELETED;
830       if (!(error=table->file->ha_delete_row(table->record[0])))
831       {
832         deleted++;
833         if (!table->file->has_transactions())
834           thd->transaction.stmt.mark_modified_non_trans_table();
835         if (table->triggers &&
836             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
837                                               TRG_ACTION_AFTER, FALSE))
838           DBUG_RETURN(1);
839       }
840       else if (!ignore)
841       {
842         /*
843           If the IGNORE option is used errors caused by ha_delete_row don't
844           have to stop the iteration.
845         */
846         table->file->print_error(error,MYF(0));
847         DBUG_RETURN(1);
848       }
849     }
850     else
851     {
852       error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
853       if (error)
854       {
855 	error= 1;                               // Fatal error
856 	DBUG_RETURN(1);
857       }
858     }
859   }
860   DBUG_RETURN(0);
861 }
862 
863 
send_error(uint errcode,const char * err)864 void multi_delete::send_error(uint errcode,const char *err)
865 {
866   DBUG_ENTER("multi_delete::send_error");
867 
868   /* First send error what ever it is ... */
869   my_message(errcode, err, MYF(0));
870 
871   DBUG_VOID_RETURN;
872 }
873 
874 
abort_result_set()875 void multi_delete::abort_result_set()
876 {
877   DBUG_ENTER("multi_delete::abort_result_set");
878 
879   /* the error was handled or nothing deleted and no side effects return */
880   if (error_handled ||
881       (!thd->transaction.stmt.cannot_safely_rollback() && !deleted))
882     DBUG_VOID_RETURN;
883 
884   /* Something already deleted so we have to invalidate cache */
885   if (deleted)
886     query_cache_invalidate3(thd, delete_tables, 1);
887 
888   /*
889     If rows from the first table only has been deleted and it is
890     transactional, just do rollback.
891     The same if all tables are transactional, regardless of where we are.
892     In all other cases do attempt deletes ...
893   */
894   if (do_delete && normal_tables &&
895       (table_being_deleted != delete_tables ||
896        !table_being_deleted->table->file->has_transactions()))
897   {
898     /*
899       We have to execute the recorded do_deletes() and write info into the
900       error log
901     */
902     error= 1;
903     send_eof();
904     DBUG_ASSERT(error_handled);
905     DBUG_VOID_RETURN;
906   }
907 
908   if (thd->transaction.stmt.cannot_safely_rollback())
909   {
910     /*
911        there is only side effects; to binlog with the error
912     */
913     if (mysql_bin_log.is_open())
914     {
915       int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
916       /* possible error of writing binary log is ignored deliberately */
917       (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
918                                thd->query(), thd->query_length(),
919                                transactional_tables, FALSE, FALSE, errcode);
920     }
921   }
922   DBUG_VOID_RETURN;
923 }
924 
925 
926 
927 /**
928   Do delete from other tables.
929 
930   @retval 0 ok
931   @retval 1 error
932 
933   @todo Is there any reason not use the normal nested-loops join? If not, and
934   there is no documentation supporting it, this method and callee should be
935   removed and there should be hooks within normal execution.
936 */
937 
do_deletes()938 int multi_delete::do_deletes()
939 {
940   DBUG_ENTER("do_deletes");
941   DBUG_ASSERT(do_delete);
942 
943   do_delete= 0;                                 // Mark called
944   if (!found)
945     DBUG_RETURN(0);
946 
947   table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
948                         delete_tables);
949 
950   for (uint counter= 0; table_being_deleted;
951        table_being_deleted= table_being_deleted->next_local, counter++)
952   {
953     TABLE *table = table_being_deleted->table;
954     if (tempfiles[counter]->get(table))
955       DBUG_RETURN(1);
956 
957     int local_error=
958       do_table_deletes(table, thd->lex->current_select->no_error);
959 
960     if (thd->killed && !local_error)
961       DBUG_RETURN(1);
962 
963     if (local_error == -1)				// End of file
964       local_error = 0;
965 
966     if (local_error)
967       DBUG_RETURN(local_error);
968   }
969   DBUG_RETURN(0);
970 }
971 
972 
973 /**
974    Implements the inner loop of nested-loops join within multi-DELETE
975    execution.
976 
977    @param table The table from which to delete.
978 
979    @param ignore If used, all non fatal errors will be translated
980    to warnings and we should not break the row-by-row iteration.
981 
982    @return Status code
983 
984    @retval  0 All ok.
985    @retval  1 Triggers or handler reported error.
986    @retval -1 End of file from handler.
987 */
do_table_deletes(TABLE * table,bool ignore)988 int multi_delete::do_table_deletes(TABLE *table, bool ignore)
989 {
990   int local_error= 0;
991   READ_RECORD info;
992   ha_rows last_deleted= deleted;
993   DBUG_ENTER("do_deletes_for_table");
994   if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE))
995     DBUG_RETURN(1);
996   /*
997     Ignore any rows not found in reference tables as they may already have
998     been deleted by foreign key handling
999   */
1000   info.ignore_not_found_rows= 1;
1001   bool will_batch= !table->file->start_bulk_delete();
1002   while (!(local_error= info.read_record(&info)) && !thd->killed)
1003   {
1004     if (table->triggers &&
1005         table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1006                                           TRG_ACTION_BEFORE, FALSE))
1007     {
1008       local_error= 1;
1009       break;
1010     }
1011 
1012     local_error= table->file->ha_delete_row(table->record[0]);
1013     if (local_error && !ignore)
1014     {
1015       table->file->print_error(local_error, MYF(0));
1016       break;
1017     }
1018 
1019     /*
1020       Increase the reported number of deleted rows only if no error occurred
1021       during ha_delete_row.
1022       Also, don't execute the AFTER trigger if the row operation failed.
1023     */
1024     if (!local_error)
1025     {
1026       deleted++;
1027       if (table->triggers &&
1028           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
1029                                             TRG_ACTION_AFTER, FALSE))
1030       {
1031         local_error= 1;
1032         break;
1033       }
1034     }
1035   }
1036   if (will_batch)
1037   {
1038     int tmp_error= table->file->end_bulk_delete();
1039     if (tmp_error && !local_error)
1040     {
1041       local_error= tmp_error;
1042       table->file->print_error(local_error, MYF(0));
1043     }
1044   }
1045   if (last_deleted != deleted && !table->file->has_transactions())
1046     thd->transaction.stmt.mark_modified_non_trans_table();
1047 
1048   end_read_record(&info);
1049 
1050   DBUG_RETURN(local_error);
1051 }
1052 
1053 /*
1054   Send ok to the client
1055 
1056   return:  0 sucess
1057 	   1 error
1058 */
1059 
send_eof()1060 bool multi_delete::send_eof()
1061 {
1062   THD::killed_state killed_status= THD::NOT_KILLED;
1063   THD_STAGE_INFO(thd, stage_deleting_from_reference_tables);
1064 
1065   /* Does deletes for the last n - 1 tables, returns 0 if ok */
1066   int local_error= do_deletes();		// returns 0 if success
1067 
1068   /* compute a total error to know if something failed */
1069   local_error= local_error || error;
1070   killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
1071   /* reset used flags */
1072   THD_STAGE_INFO(thd, stage_end);
1073 
1074   /*
1075     We must invalidate the query cache before binlog writing and
1076     ha_autocommit_...
1077   */
1078   if (deleted)
1079   {
1080     query_cache_invalidate3(thd, delete_tables, 1);
1081   }
1082   if ((local_error == 0) || thd->transaction.stmt.cannot_safely_rollback())
1083   {
1084     if (mysql_bin_log.is_open())
1085     {
1086       int errcode= 0;
1087       if (local_error == 0)
1088         thd->clear_error();
1089       else
1090         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
1091       thd->thread_specific_used= TRUE;
1092       if (thd->binlog_query(THD::ROW_QUERY_TYPE,
1093                             thd->query(), thd->query_length(),
1094                             transactional_tables, FALSE, FALSE, errcode) &&
1095           !normal_tables)
1096       {
1097 	local_error=1;  // Log write failed: roll back the SQL statement
1098       }
1099     }
1100   }
1101   if (local_error != 0)
1102     error_handled= TRUE; // to force early leave from ::send_error()
1103 
1104   if (!local_error)
1105   {
1106     ::my_ok(thd, deleted);
1107   }
1108   return 0;
1109 }
1110 
1111