~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
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 as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Delete of records and truncate of tables.
18
19
  Multi-table deletes were introduced by Monty and Sinisa
20
*/
21
22
#include "mysql_priv.h"
23
#include "sql_select.h"
202.3.6 by Monty Taylor
First pass at gettexizing the error messages.
24
#include <drizzled/drizzled_error_messages.h>
1 by brian
clean slate
25
26
/**
27
  Implement DELETE SQL word.
28
29
  @note Like implementations of other DDL/DML in MySQL, this function
30
  relies on the caller to close the thread tables. This is done in the
31
  end of dispatch_command().
32
*/
33
34
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
151 by Brian Aker
Ulonglong to uint64_t
35
                  SQL_LIST *order, ha_rows limit, uint64_t options,
1 by brian
clean slate
36
                  bool reset_auto_increment)
37
{
38
  bool          will_batch;
39
  int		error, loc_error;
40
  TABLE		*table;
41
  SQL_SELECT	*select=0;
42
  READ_RECORD	info;
43
  bool          using_limit=limit != HA_POS_ERROR;
44
  bool		transactional_table, safe_update, const_cond;
45
  bool          const_cond_result;
46
  ha_rows	deleted= 0;
47
  uint usable_index= MAX_KEY;
48
  SELECT_LEX   *select_lex= &thd->lex->select_lex;
49
  THD::killed_state killed_status= THD::NOT_KILLED;
51.2.2 by Patrick Galbraith
Removed DBUGs from
50
  
1 by brian
clean slate
51
52
  if (open_and_lock_tables(thd, table_list))
163 by Brian Aker
Merge Monty's code.
53
    return(true);
1 by brian
clean slate
54
  /* TODO look at this error */
55
  if (!(table= table_list->table))
56
  {
57
    my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
163 by Brian Aker
Merge Monty's code.
58
    return(true);
1 by brian
clean slate
59
  }
60
  thd_proc_info(thd, "init");
61
  table->map=1;
62
63
  if (mysql_prepare_delete(thd, table_list, &conds))
64
    goto err;
65
66
  /* check ORDER BY even if it can be ignored */
67
  if (order && order->elements)
68
  {
69
    TABLE_LIST   tables;
70
    List<Item>   fields;
71
    List<Item>   all_fields;
72
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
73
    memset((char*) &tables, 0, sizeof(tables));
1 by brian
clean slate
74
    tables.table = table;
75
    tables.alias = table_list->alias;
76
77
      if (select_lex->setup_ref_array(thd, order->elements) ||
78
	  setup_order(thd, select_lex->ref_pointer_array, &tables,
79
                    fields, all_fields, (ORDER*) order->first))
80
    {
81
      delete select;
82
      free_underlaid_joins(thd, &thd->lex->select_lex);
83
      goto err;
84
    }
85
  }
86
87
  const_cond= (!conds || conds->const_item());
88
  safe_update=test(thd->options & OPTION_SAFE_UPDATES);
89
  if (safe_update && const_cond)
90
  {
91
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
92
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
93
    goto err;
94
  }
95
96
  select_lex->no_error= thd->lex->ignore;
97
98
  const_cond_result= const_cond && (!conds || conds->val_int());
99
  if (thd->is_error())
100
  {
101
    /* Error evaluating val_int(). */
163 by Brian Aker
Merge Monty's code.
102
    return(true);
1 by brian
clean slate
103
  }
104
105
  /*
106
    Test if the user wants to delete all rows and deletion doesn't have
107
    any side-effects (because of triggers), so we can use optimized
108
    handler::delete_all_rows() method.
109
110
    We implement fast TRUNCATE for InnoDB even if triggers are
111
    present.  TRUNCATE ignores triggers.
112
113
    We can use delete_all_rows() if and only if:
114
    - We allow new functions (not using option --skip-new), and are
115
      not in safe mode (not using option --safe-mode)
116
    - There is no limit clause
117
    - The condition is constant
118
    - If there is a condition, then it it produces a non-zero value
119
    - If the current command is DELETE FROM with no where clause
120
      (i.e., not TRUNCATE) then:
121
      - We should not be binlogging this statement row-based, and
122
      - there should be no delete triggers associated with the table.
123
  */
124
  if (!using_limit && const_cond_result &&
125
      !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
126
      (thd->lex->sql_command == SQLCOM_TRUNCATE ||
127
       (!thd->current_stmt_binlog_row_based)))
128
  {
129
    /* Update the table->file->stats.records number */
130
    table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
131
    ha_rows const maybe_deleted= table->file->stats.records;
132
    if (!(error=table->file->ha_delete_all_rows()))
133
    {
134
      error= -1;				// ok
135
      deleted= maybe_deleted;
136
      goto cleanup;
137
    }
138
    if (error != HA_ERR_WRONG_COMMAND)
139
    {
140
      table->file->print_error(error,MYF(0));
141
      error=0;
142
      goto cleanup;
143
    }
144
    /* Handler didn't support fast delete; Delete rows one by one */
145
  }
146
  if (conds)
147
  {
148
    Item::cond_result result;
149
    conds= remove_eq_conds(thd, conds, &result);
150
    if (result == Item::COND_FALSE)             // Impossible where
151
      limit= 0;
152
  }
153
154
  /* Update the table->file->stats.records number */
155
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
156
157
  table->covering_keys.clear_all();
158
  table->quick_keys.clear_all();		// Can't use 'only index'
159
  select=make_select(table, 0, 0, conds, 0, &error);
160
  if (error)
161
    goto err;
162
  if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
163
  {
164
    delete select;
165
    free_underlaid_joins(thd, select_lex);
166
    thd->row_count_func= 0;
167
    MYSQL_DELETE_END();
168
    my_ok(thd, (ha_rows) thd->row_count_func);
169
    /*
170
      We don't need to call reset_auto_increment in this case, because
171
      mysql_truncate always gives a NULL conds argument, hence we never
172
      get here.
173
    */
51.2.2 by Patrick Galbraith
Removed DBUGs from
174
    return(0);				// Nothing to delete
1 by brian
clean slate
175
  }
176
177
  /* If running in safe sql mode, don't allow updates without keys */
178
  if (table->quick_keys.is_clear_all())
179
  {
180
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
181
    if (safe_update && !using_limit)
182
    {
183
      delete select;
184
      free_underlaid_joins(thd, select_lex);
185
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
186
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
187
      goto err;
188
    }
189
  }
190
  if (options & OPTION_QUICK)
191
    (void) table->file->extra(HA_EXTRA_QUICK);
192
193
  if (order && order->elements)
194
  {
195
    uint         length= 0;
196
    SORT_FIELD  *sortorder;
197
    ha_rows examined_rows;
198
    
199
    if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
200
      usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
201
202
    if (usable_index == MAX_KEY)
203
    {
204
      table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
205
                                                   MYF(MY_FAE | MY_ZEROFILL));
206
    
207
      if (!(sortorder= make_unireg_sortorder((ORDER*) order->first,
208
                                             &length, NULL)) ||
209
	  (table->sort.found_records = filesort(thd, table, sortorder, length,
210
                                                select, HA_POS_ERROR, 1,
211
                                                &examined_rows))
212
	  == HA_POS_ERROR)
213
      {
214
        delete select;
215
        free_underlaid_joins(thd, &thd->lex->select_lex);
216
        goto err;
217
      }
218
      /*
219
        Filesort has already found and selected the rows we want to delete,
220
        so we don't need the where clause
221
      */
222
      delete select;
223
      free_underlaid_joins(thd, select_lex);
224
      select= 0;
225
    }
226
  }
227
228
  /* If quick select is used, initialize it before retrieving rows. */
229
  if (select && select->quick && select->quick->reset())
230
  {
231
    delete select;
232
    free_underlaid_joins(thd, select_lex);
233
    goto err;
234
  }
235
  if (usable_index==MAX_KEY)
236
    init_read_record(&info,thd,table,select,1,1);
237
  else
238
    init_read_record_idx(&info, thd, table, 1, usable_index);
239
240
  thd_proc_info(thd, "updating");
241
242
  will_batch= !table->file->start_bulk_delete();
243
244
245
  table->mark_columns_needed_for_delete();
246
247
  while (!(error=info.read_record(&info)) && !thd->killed &&
248
	 ! thd->is_error())
249
  {
250
    // thd->is_error() is tested to disallow delete row on error
251
    if (!(select && select->skip_record())&& ! thd->is_error() )
252
    {
253
      if (!(error= table->file->ha_delete_row(table->record[0])))
254
      {
255
	deleted++;
256
	if (!--limit && using_limit)
257
	{
258
	  error= -1;
259
	  break;
260
	}
261
      }
262
      else
263
      {
264
	table->file->print_error(error,MYF(0));
265
	/*
266
	  In < 4.0.14 we set the error number to 0 here, but that
267
	  was not sensible, because then MySQL would not roll back the
268
	  failed DELETE, and also wrote it to the binlog. For MyISAM
269
	  tables a DELETE probably never should fail (?), but for
270
	  InnoDB it can fail in a FOREIGN KEY error or an
271
	  out-of-tablespace error.
272
	*/
273
 	error= 1;
274
	break;
275
      }
276
    }
277
    else
278
      table->file->unlock_row();  // Row failed selection, release lock on it
279
  }
280
  killed_status= thd->killed;
281
  if (killed_status != THD::NOT_KILLED || thd->is_error())
282
    error= 1;					// Aborted
283
  if (will_batch && (loc_error= table->file->end_bulk_delete()))
284
  {
285
    if (error != 1)
286
      table->file->print_error(loc_error,MYF(0));
287
    error=1;
288
  }
289
  thd_proc_info(thd, "end");
290
  end_read_record(&info);
291
  if (options & OPTION_QUICK)
292
    (void) table->file->extra(HA_EXTRA_NORMAL);
293
294
  if (reset_auto_increment && (error < 0))
295
  {
296
    /*
297
      We're really doing a truncate and need to reset the table's
298
      auto-increment counter.
299
    */
300
    int error2= table->file->ha_reset_auto_increment(0);
301
302
    if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
303
    {
304
      table->file->print_error(error2, MYF(0));
305
      error= 1;
306
    }
307
  }
308
309
cleanup:
310
311
  delete select;
312
  transactional_table= table->file->has_transactions();
313
314
  if (!transactional_table && deleted > 0)
163 by Brian Aker
Merge Monty's code.
315
    thd->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
316
  
317
  /* See similar binlogging code in sql_update.cc, for comments */
318
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
319
  {
320
    if (mysql_bin_log.is_open())
321
    {
322
      if (error < 0)
323
        thd->clear_error();
324
      /*
325
        [binlog]: If 'handler::delete_all_rows()' was called and the
326
        storage engine does not inject the rows itself, we replicate
327
        statement-based; otherwise, 'ha_delete_row()' was used to
328
        delete specific rows which we might log row-based.
329
      */
330
      int log_result= thd->binlog_query(THD::ROW_QUERY_TYPE,
331
                                        thd->query, thd->query_length,
163 by Brian Aker
Merge Monty's code.
332
                                        transactional_table, false, killed_status);
1 by brian
clean slate
333
334
      if (log_result && transactional_table)
335
      {
336
	error=1;
337
      }
338
    }
339
    if (thd->transaction.stmt.modified_non_trans_table)
163 by Brian Aker
Merge Monty's code.
340
      thd->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
341
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
342
  assert(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
1 by brian
clean slate
343
  free_underlaid_joins(thd, select_lex);
344
345
  MYSQL_DELETE_END();
346
  if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
347
  {
348
    thd->row_count_func= deleted;
349
    my_ok(thd, (ha_rows) thd->row_count_func);
350
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
351
  return(error >= 0 || thd->is_error());
1 by brian
clean slate
352
353
err:
354
  MYSQL_DELETE_END();
163 by Brian Aker
Merge Monty's code.
355
  return(true);
1 by brian
clean slate
356
}
357
358
359
/*
360
  Prepare items in DELETE statement
361
362
  SYNOPSIS
363
    mysql_prepare_delete()
364
    thd			- thread handler
365
    table_list		- global/local table list
366
    conds		- conditions
367
368
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
369
    false OK
370
    true  error
1 by brian
clean slate
371
*/
372
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
373
{
374
  SELECT_LEX *select_lex= &thd->lex->select_lex;
51.2.2 by Patrick Galbraith
Removed DBUGs from
375
  
1 by brian
clean slate
376
  List<Item> all_fields;
377
378
  /*
379
    Statement-based replication of DELETE ... LIMIT is not safe as order of
380
    rows is not defined, so in mixed mode we go to row-based.
381
382
    Note that we may consider a statement as safe if ORDER BY primary_key
383
    is present. However it may confuse users to see very similiar statements
384
    replicated differently.
385
  */
386
  if (thd->lex->current_select->select_limit)
387
  {
388
    thd->lex->set_stmt_unsafe();
389
    thd->set_current_stmt_binlog_row_based_if_mixed();
390
  }
391
  thd->lex->allow_sum_func= 0;
392
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
393
                                    &thd->lex->select_lex.top_join_list,
394
                                    table_list, 
395
                                    &select_lex->leaf_tables, false) ||
396
      setup_conds(thd, table_list, select_lex->leaf_tables, conds))
163 by Brian Aker
Merge Monty's code.
397
    return(true);
1 by brian
clean slate
398
  {
399
    TABLE_LIST *duplicate;
400
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
401
    {
402
      update_non_unique_table_error(table_list, "DELETE", duplicate);
163 by Brian Aker
Merge Monty's code.
403
      return(true);
1 by brian
clean slate
404
    }
405
  }
406
407
  if (select_lex->inner_refs_list.elements &&
408
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
51.2.2 by Patrick Galbraith
Removed DBUGs from
409
    return(-1);
1 by brian
clean slate
410
163 by Brian Aker
Merge Monty's code.
411
  return(false);
1 by brian
clean slate
412
}
413
414
415
/***************************************************************************
416
  Delete multiple tables from join 
417
***************************************************************************/
418
419
#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
420
421
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
422
{
423
  handler *file= (handler*)arg;
424
  return file->cmp_ref((const uchar*)a, (const uchar*)b);
425
}
426
427
/*
428
  make delete specific preparation and checks after opening tables
429
430
  SYNOPSIS
431
    mysql_multi_delete_prepare()
432
    thd         thread handler
433
434
  RETURN
163 by Brian Aker
Merge Monty's code.
435
    false OK
436
    true  Error
1 by brian
clean slate
437
*/
438
439
int mysql_multi_delete_prepare(THD *thd)
440
{
441
  LEX *lex= thd->lex;
442
  TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
443
  TABLE_LIST *target_tbl;
51.2.2 by Patrick Galbraith
Removed DBUGs from
444
  
1 by brian
clean slate
445
446
  /*
447
    setup_tables() need for VIEWs. JOIN::prepare() will not do it second
448
    time.
449
450
    lex->query_tables also point on local list of DELETE SELECT_LEX
451
  */
452
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
453
                                    &thd->lex->select_lex.top_join_list,
454
                                    lex->query_tables,
455
                                    &lex->select_lex.leaf_tables, false))
163 by Brian Aker
Merge Monty's code.
456
    return(true);
1 by brian
clean slate
457
458
459
  /*
460
    Multi-delete can't be constructed over-union => we always have
461
    single SELECT on top and have to check underlying SELECTs of it
462
  */
163 by Brian Aker
Merge Monty's code.
463
  lex->select_lex.exclude_from_table_unique_test= true;
1 by brian
clean slate
464
  /* Fix tables-to-be-deleted-from list to point at opened tables */
465
  for (target_tbl= (TABLE_LIST*) aux_tables;
466
       target_tbl;
467
       target_tbl= target_tbl->next_local)
468
  {
469
    if (!(target_tbl->table= target_tbl->correspondent_table->table))
470
    {
51.2.2 by Patrick Galbraith
Removed DBUGs from
471
      assert(target_tbl->correspondent_table->merge_underlying_list &&
1 by brian
clean slate
472
                  target_tbl->correspondent_table->merge_underlying_list->
473
                  next_local);
474
      my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
163 by Brian Aker
Merge Monty's code.
475
      return(true);
1 by brian
clean slate
476
    }
477
478
    /*
479
      Check that table from which we delete is not used somewhere
480
      inside subqueries/view.
481
    */
482
    {
483
      TABLE_LIST *duplicate;
484
      if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
485
                                   lex->query_tables, 0)))
486
      {
487
        update_non_unique_table_error(target_tbl->correspondent_table,
488
                                      "DELETE", duplicate);
163 by Brian Aker
Merge Monty's code.
489
        return(true);
1 by brian
clean slate
490
      }
491
    }
492
  }
163 by Brian Aker
Merge Monty's code.
493
  return(false);
1 by brian
clean slate
494
}
495
496
497
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
498
  : delete_tables(dt), deleted(0), found(0),
499
    num_of_tables(num_of_tables_arg), error(0),
500
    do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
501
{
502
  tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
503
}
504
505
506
int
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
507
multi_delete::prepare(List<Item> &values __attribute__((unused)),
77.1.45 by Monty Taylor
Warning fixes.
508
                      SELECT_LEX_UNIT *u)
1 by brian
clean slate
509
{
51.2.2 by Patrick Galbraith
Removed DBUGs from
510
  
1 by brian
clean slate
511
  unit= u;
512
  do_delete= 1;
513
  thd_proc_info(thd, "deleting from main table");
51.2.2 by Patrick Galbraith
Removed DBUGs from
514
  return(0);
1 by brian
clean slate
515
}
516
517
518
bool
519
multi_delete::initialize_tables(JOIN *join)
520
{
521
  TABLE_LIST *walk;
522
  Unique **tempfiles_ptr;
51.2.2 by Patrick Galbraith
Removed DBUGs from
523
  
1 by brian
clean slate
524
525
  if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
51.2.2 by Patrick Galbraith
Removed DBUGs from
526
    return(1);
1 by brian
clean slate
527
528
  table_map tables_to_delete_from=0;
529
  for (walk= delete_tables; walk; walk= walk->next_local)
530
    tables_to_delete_from|= walk->table->map;
531
532
  walk= delete_tables;
533
  delete_while_scanning= 1;
534
  for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
535
       tab < end;
536
       tab++)
537
  {
538
    if (tab->table->map & tables_to_delete_from)
539
    {
540
      /* We are going to delete from this table */
541
      TABLE *tbl=walk->table=tab->table;
542
      walk= walk->next_local;
543
      /* Don't use KEYREAD optimization on this table */
544
      tbl->no_keyread=1;
545
      /* Don't use record cache */
546
      tbl->no_cache= 1;
547
      tbl->covering_keys.clear_all();
548
      if (tbl->file->has_transactions())
549
	transactional_tables= 1;
550
      else
551
	normal_tables= 1;
552
      tbl->prepare_for_position();
553
      tbl->mark_columns_needed_for_delete();
554
    }
555
    else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
556
             walk == delete_tables)
557
    {
558
      /*
559
        We are not deleting from the table we are scanning. In this
560
        case send_data() shouldn't delete any rows a we may touch
561
        the rows in the deleted table many times
562
      */
563
      delete_while_scanning= 0;
564
    }
565
  }
566
  walk= delete_tables;
567
  tempfiles_ptr= tempfiles;
568
  if (delete_while_scanning)
569
  {
570
    table_being_deleted= delete_tables;
571
    walk= walk->next_local;
572
  }
573
  for (;walk ;walk= walk->next_local)
574
  {
575
    TABLE *table=walk->table;
576
    *tempfiles_ptr++= new Unique (refpos_order_cmp,
577
				  (void *) table->file,
578
				  table->file->ref_length,
579
				  MEM_STRIP_BUF_SIZE);
580
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
581
  return(thd->is_fatal_error != 0);
1 by brian
clean slate
582
}
583
584
585
multi_delete::~multi_delete()
586
{
587
  for (table_being_deleted= delete_tables;
588
       table_being_deleted;
589
       table_being_deleted= table_being_deleted->next_local)
590
  {
591
    TABLE *table= table_being_deleted->table;
592
    table->no_keyread=0;
593
  }
594
595
  for (uint counter= 0; counter < num_of_tables; counter++)
596
  {
597
    if (tempfiles[counter])
598
      delete tempfiles[counter];
599
  }
600
}
601
602
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
603
bool multi_delete::send_data(List<Item> &values __attribute__((unused)))
1 by brian
clean slate
604
{
605
  int secure_counter= delete_while_scanning ? -1 : 0;
606
  TABLE_LIST *del_table;
51.2.2 by Patrick Galbraith
Removed DBUGs from
607
  
1 by brian
clean slate
608
609
  for (del_table= delete_tables;
610
       del_table;
611
       del_table= del_table->next_local, secure_counter++)
612
  {
613
    TABLE *table= del_table->table;
614
615
    /* Check if we are using outer join and we didn't find the row */
616
    if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
617
      continue;
618
619
    table->file->position(table->record[0]);
620
    found++;
621
622
    if (secure_counter < 0)
623
    {
624
      /* We are scanning the current table */
51.2.2 by Patrick Galbraith
Removed DBUGs from
625
      assert(del_table == table_being_deleted);
1 by brian
clean slate
626
      table->status|= STATUS_DELETED;
627
      if (!(error=table->file->ha_delete_row(table->record[0])))
628
      {
629
        deleted++;
630
        if (!table->file->has_transactions())
163 by Brian Aker
Merge Monty's code.
631
          thd->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
632
      }
633
      else
634
      {
635
        table->file->print_error(error,MYF(0));
51.2.2 by Patrick Galbraith
Removed DBUGs from
636
        return(1);
1 by brian
clean slate
637
      }
638
    }
639
    else
640
    {
641
      error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
642
      if (error)
643
      {
644
	error= 1;                               // Fatal error
51.2.2 by Patrick Galbraith
Removed DBUGs from
645
	return(1);
1 by brian
clean slate
646
      }
647
    }
648
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
649
  return(0);
1 by brian
clean slate
650
}
651
652
653
void multi_delete::send_error(uint errcode,const char *err)
654
{
51.2.2 by Patrick Galbraith
Removed DBUGs from
655
  
1 by brian
clean slate
656
657
  /* First send error what ever it is ... */
658
  my_message(errcode, err, MYF(0));
659
51.2.2 by Patrick Galbraith
Removed DBUGs from
660
  return;
1 by brian
clean slate
661
}
662
663
664
void multi_delete::abort()
665
{
51.2.2 by Patrick Galbraith
Removed DBUGs from
666
  
1 by brian
clean slate
667
668
  /* the error was handled or nothing deleted and no side effects return */
669
  if (error_handled ||
670
      (!thd->transaction.stmt.modified_non_trans_table && !deleted))
51.2.2 by Patrick Galbraith
Removed DBUGs from
671
    return;
1 by brian
clean slate
672
673
  /*
674
    If rows from the first table only has been deleted and it is
675
    transactional, just do rollback.
676
    The same if all tables are transactional, regardless of where we are.
677
    In all other cases do attempt deletes ...
678
  */
679
  if (do_delete && normal_tables &&
680
      (table_being_deleted != delete_tables ||
681
       !table_being_deleted->table->file->has_transactions()))
682
  {
683
    /*
684
      We have to execute the recorded do_deletes() and write info into the
685
      error log
686
    */
687
    error= 1;
688
    send_eof();
51.2.2 by Patrick Galbraith
Removed DBUGs from
689
    assert(error_handled);
690
    return;
1 by brian
clean slate
691
  }
692
  
693
  if (thd->transaction.stmt.modified_non_trans_table)
694
  {
695
    /* 
696
       there is only side effects; to binlog with the error
697
    */
698
    if (mysql_bin_log.is_open())
699
    {
700
      thd->binlog_query(THD::ROW_QUERY_TYPE,
701
                        thd->query, thd->query_length,
163 by Brian Aker
Merge Monty's code.
702
                        transactional_tables, false);
1 by brian
clean slate
703
    }
704
    thd->transaction.all.modified_non_trans_table= true;
705
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
706
  return;
1 by brian
clean slate
707
}
708
709
710
711
/*
712
  Do delete from other tables.
713
  Returns values:
714
	0 ok
715
	1 error
716
*/
717
718
int multi_delete::do_deletes()
719
{
720
  int local_error= 0, counter= 0, tmp_error;
721
  bool will_batch;
51.2.2 by Patrick Galbraith
Removed DBUGs from
722
  
723
  assert(do_delete);
1 by brian
clean slate
724
725
  do_delete= 0;                                 // Mark called
726
  if (!found)
51.2.2 by Patrick Galbraith
Removed DBUGs from
727
    return(0);
1 by brian
clean slate
728
729
  table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
730
                        delete_tables);
731
 
732
  for (; table_being_deleted;
733
       table_being_deleted= table_being_deleted->next_local, counter++)
734
  { 
735
    ha_rows last_deleted= deleted;
736
    TABLE *table = table_being_deleted->table;
737
    if (tempfiles[counter]->get(table))
738
    {
739
      local_error=1;
740
      break;
741
    }
742
743
    READ_RECORD	info;
744
    init_read_record(&info,thd,table,NULL,0,1);
745
    /*
746
      Ignore any rows not found in reference tables as they may already have
747
      been deleted by foreign key handling
748
    */
749
    info.ignore_not_found_rows= 1;
750
    will_batch= !table->file->start_bulk_delete();
751
    while (!(local_error=info.read_record(&info)) && !thd->killed)
752
    {
753
      if ((local_error=table->file->ha_delete_row(table->record[0])))
754
      {
755
	table->file->print_error(local_error,MYF(0));
756
	break;
757
      }
758
      deleted++;
759
    }
760
    if (will_batch && (tmp_error= table->file->end_bulk_delete()))
761
    {
762
      if (!local_error)
763
      {
764
        local_error= tmp_error;
765
        table->file->print_error(local_error,MYF(0));
766
      }
767
    }
768
    if (last_deleted != deleted && !table->file->has_transactions())
163 by Brian Aker
Merge Monty's code.
769
      thd->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
770
    end_read_record(&info);
771
    if (thd->killed && !local_error)
772
      local_error= 1;
773
    if (local_error == -1)				// End of file
774
      local_error = 0;
775
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
776
  return(local_error);
1 by brian
clean slate
777
}
778
779
780
/*
781
  Send ok to the client
782
783
  return:  0 sucess
784
	   1 error
785
*/
786
787
bool multi_delete::send_eof()
788
{
789
  THD::killed_state killed_status= THD::NOT_KILLED;
790
  thd_proc_info(thd, "deleting from reference tables");
791
792
  /* Does deletes for the last n - 1 tables, returns 0 if ok */
793
  int local_error= do_deletes();		// returns 0 if success
794
795
  /* compute a total error to know if something failed */
796
  local_error= local_error || error;
797
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
798
  /* reset used flags */
799
  thd_proc_info(thd, "end");
800
801
  if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
802
  {
803
    if (mysql_bin_log.is_open())
804
    {
805
      if (local_error == 0)
806
        thd->clear_error();
807
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
808
                            thd->query, thd->query_length,
163 by Brian Aker
Merge Monty's code.
809
                            transactional_tables, false, killed_status) &&
1 by brian
clean slate
810
          !normal_tables)
811
      {
812
	local_error=1;  // Log write failed: roll back the SQL statement
813
      }
814
    }
815
    if (thd->transaction.stmt.modified_non_trans_table)
163 by Brian Aker
Merge Monty's code.
816
      thd->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
817
  }
818
  if (local_error != 0)
163 by Brian Aker
Merge Monty's code.
819
    error_handled= true; // to force early leave from ::send_error()
1 by brian
clean slate
820
821
  if (!local_error)
822
  {
823
    thd->row_count_func= deleted;
824
    ::my_ok(thd, (ha_rows) thd->row_count_func);
825
  }
826
  return 0;
827
}
828
829
830
/***************************************************************************
831
  TRUNCATE TABLE
832
****************************************************************************/
833
834
/*
835
  Optimize delete of all rows by doing a full generate of the table
836
  This will work even if the .ISM and .ISD tables are destroyed
837
838
  dont_send_ok should be set if:
839
  - We should always wants to generate the table (even if the table type
840
    normally can't safely do this.
841
  - We don't want an ok to be sent to the end user.
842
  - We don't want to log the truncate command
843
  - If we want to have a name lock on the table on exit without errors.
844
*/
845
846
bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
847
{
848
  HA_CREATE_INFO create_info;
849
  char path[FN_REFLEN];
850
  TABLE *table;
851
  bool error;
852
  uint path_length;
51.2.2 by Patrick Galbraith
Removed DBUGs from
853
  
1 by brian
clean slate
854
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
855
  memset((char*) &create_info, 0, sizeof(create_info));
1 by brian
clean slate
856
  /* If it is a temporary table, close and regenerate it */
857
  if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
858
  {
859
    handlerton *table_type= table->s->db_type();
860
    TABLE_SHARE *share= table->s;
861
    bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
862
863
    if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
864
      goto trunc_by_del;
865
866
    table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
867
    
868
    close_temporary_table(thd, table, 0, 0);    // Don't free share
869
    ha_create_table(thd, share->normalized_path.str,
870
                    share->db.str, share->table_name.str, &create_info, 1);
871
    // We don't need to call invalidate() because this table is not in cache
872
    if ((error= (int) !(open_temporary_table(thd, share->path.str,
873
                                             share->db.str,
874
					     share->table_name.str, 1,
875
                                             OTM_OPEN))))
876
      (void) rm_temporary_table(table_type, path, frm_only);
877
    free_table_share(share);
878
    my_free((char*) table,MYF(0));
879
    /*
880
      If we return here we will not have logged the truncation to the bin log
881
      and we will not my_ok() to the client.
882
    */
883
    goto end;
884
  }
885
886
  path_length= build_table_filename(path, sizeof(path), table_list->db,
887
                                    table_list->table_name, reg_ext, 0);
888
889
  if (!dont_send_ok)
890
  {
891
    enum legacy_db_type table_type;
892
    mysql_frm_type(thd, path, &table_type);
893
    if (table_type == DB_TYPE_UNKNOWN)
894
    {
895
      my_error(ER_NO_SUCH_TABLE, MYF(0),
896
               table_list->db, table_list->table_name);
163 by Brian Aker
Merge Monty's code.
897
      return(true);
1 by brian
clean slate
898
    }
899
900
    if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type),
901
                                      HTON_CAN_RECREATE))
902
      goto trunc_by_del;
903
904
    if (lock_and_wait_for_table_name(thd, table_list))
163 by Brian Aker
Merge Monty's code.
905
      return(true);
1 by brian
clean slate
906
  }
907
908
  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
909
  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
910
  // '\0';
911
  path[path_length - reg_ext_length] = 0;
912
  VOID(pthread_mutex_lock(&LOCK_open));
913
  error= ha_create_table(thd, path, table_list->db, table_list->table_name,
914
                         &create_info, 1);
915
  VOID(pthread_mutex_unlock(&LOCK_open));
916
917
end:
918
  if (!dont_send_ok)
919
  {
920
    if (!error)
921
    {
922
      /*
923
        TRUNCATE must always be statement-based binlogged (not row-based) so
924
        we don't test current_stmt_binlog_row_based.
925
      */
163 by Brian Aker
Merge Monty's code.
926
      write_bin_log(thd, true, thd->query, thd->query_length);
1 by brian
clean slate
927
      my_ok(thd);		// This should return record count
928
    }
929
    VOID(pthread_mutex_lock(&LOCK_open));
930
    unlock_table_name(thd, table_list);
931
    VOID(pthread_mutex_unlock(&LOCK_open));
932
  }
933
  else if (error)
934
  {
935
    VOID(pthread_mutex_lock(&LOCK_open));
936
    unlock_table_name(thd, table_list);
937
    VOID(pthread_mutex_unlock(&LOCK_open));
938
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
939
  return(error);
1 by brian
clean slate
940
941
trunc_by_del:
942
  /* Probably InnoDB table */
151 by Brian Aker
Ulonglong to uint64_t
943
  uint64_t save_options= thd->options;
1 by brian
clean slate
944
  table_list->lock_type= TL_WRITE;
945
  thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
163 by Brian Aker
Merge Monty's code.
946
  ha_enable_transaction(thd, false);
1 by brian
clean slate
947
  mysql_init_select(thd->lex);
948
  bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
949
  thd->clear_current_stmt_binlog_row_based();
950
  error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
163 by Brian Aker
Merge Monty's code.
951
                      HA_POS_ERROR, 0LL, true);
952
  ha_enable_transaction(thd, true);
1 by brian
clean slate
953
  /*
163 by Brian Aker
Merge Monty's code.
954
    Safety, in case the engine ignored ha_enable_transaction(false)
1 by brian
clean slate
955
    above. Also clears thd->transaction.*.
956
  */
957
  error= ha_autocommit_or_rollback(thd, error);
958
  ha_commit(thd);
959
  thd->options= save_options;
960
  thd->current_stmt_binlog_row_based= save_binlog_row_based;
51.2.2 by Patrick Galbraith
Removed DBUGs from
961
  return(error);
1 by brian
clean slate
962
}