~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
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
21
#include <drizzled/server_includes.h>
22
#include <drizzled/sql_select.h>
549 by Monty Taylor
Took gettext.h out of header files.
23
#include <drizzled/error.h>
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
24
#include <drizzled/probes.h>
575.4.7 by Monty Taylor
More header cleanup.
25
#include <drizzled/sql_parse.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
26
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
27
#include <drizzled/lock.h>
1 by brian
clean slate
28
29
/**
30
  Implement DELETE SQL word.
31
32
  @note Like implementations of other DDL/DML in MySQL, this function
33
  relies on the caller to close the thread tables. This is done in the
34
  end of dispatch_command().
35
*/
36
520.1.22 by Brian Aker
Second pass of thd cleanup
37
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
151 by Brian Aker
Ulonglong to uint64_t
38
                  SQL_LIST *order, ha_rows limit, uint64_t options,
1 by brian
clean slate
39
                  bool reset_auto_increment)
40
{
41
  bool          will_batch;
42
  int		error, loc_error;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
43
  Table		*table;
1 by brian
clean slate
44
  SQL_SELECT	*select=0;
45
  READ_RECORD	info;
46
  bool          using_limit=limit != HA_POS_ERROR;
47
  bool		transactional_table, safe_update, const_cond;
48
  bool          const_cond_result;
49
  ha_rows	deleted= 0;
482 by Brian Aker
Remove uint.
50
  uint32_t usable_index= MAX_KEY;
520.1.22 by Brian Aker
Second pass of thd cleanup
51
  SELECT_LEX   *select_lex= &session->lex->select_lex;
520.1.21 by Brian Aker
THD -> Session rename
52
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
53
1 by brian
clean slate
54
520.1.22 by Brian Aker
Second pass of thd cleanup
55
  if (open_and_lock_tables(session, table_list))
163 by Brian Aker
Merge Monty's code.
56
    return(true);
1 by brian
clean slate
57
  /* TODO look at this error */
58
  if (!(table= table_list->table))
59
  {
60
    my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
163 by Brian Aker
Merge Monty's code.
61
    return(true);
1 by brian
clean slate
62
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
63
  session->set_proc_info("init");
1 by brian
clean slate
64
  table->map=1;
65
520.1.22 by Brian Aker
Second pass of thd cleanup
66
  if (mysql_prepare_delete(session, table_list, &conds))
1 by brian
clean slate
67
    goto err;
68
69
  /* check ORDER BY even if it can be ignored */
70
  if (order && order->elements)
71
  {
327.2.4 by Brian Aker
Refactoring table.h
72
    TableList   tables;
1 by brian
clean slate
73
    List<Item>   fields;
74
    List<Item>   all_fields;
75
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
76
    memset(&tables, 0, sizeof(tables));
1 by brian
clean slate
77
    tables.table = table;
78
    tables.alias = table_list->alias;
79
520.1.22 by Brian Aker
Second pass of thd cleanup
80
      if (select_lex->setup_ref_array(session, order->elements) ||
81
	  setup_order(session, select_lex->ref_pointer_array, &tables,
327.2.3 by Brian Aker
Refactoring of class Table
82
                    fields, all_fields, (order_st*) order->first))
1 by brian
clean slate
83
    {
84
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
85
      free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
86
      goto err;
87
    }
88
  }
89
90
  const_cond= (!conds || conds->const_item());
520.1.22 by Brian Aker
Second pass of thd cleanup
91
  safe_update=test(session->options & OPTION_SAFE_UPDATES);
1 by brian
clean slate
92
  if (safe_update && const_cond)
93
  {
94
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
95
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
96
    goto err;
97
  }
98
520.1.22 by Brian Aker
Second pass of thd cleanup
99
  select_lex->no_error= session->lex->ignore;
1 by brian
clean slate
100
101
  const_cond_result= const_cond && (!conds || conds->val_int());
520.1.22 by Brian Aker
Second pass of thd cleanup
102
  if (session->is_error())
1 by brian
clean slate
103
  {
104
    /* Error evaluating val_int(). */
163 by Brian Aker
Merge Monty's code.
105
    return(true);
1 by brian
clean slate
106
  }
107
108
  /*
109
    Test if the user wants to delete all rows and deletion doesn't have
110
    any side-effects (because of triggers), so we can use optimized
111
    handler::delete_all_rows() method.
112
113
    We implement fast TRUNCATE for InnoDB even if triggers are
114
    present.  TRUNCATE ignores triggers.
115
116
    We can use delete_all_rows() if and only if:
117
    - We allow new functions (not using option --skip-new), and are
118
      not in safe mode (not using option --safe-mode)
119
    - There is no limit clause
120
    - The condition is constant
121
    - If there is a condition, then it it produces a non-zero value
122
    - If the current command is DELETE FROM with no where clause
123
      (i.e., not TRUNCATE) then:
124
      - We should not be binlogging this statement row-based, and
125
      - there should be no delete triggers associated with the table.
126
  */
581 by Brian Aker
Second pass through on replication row patch
127
  if (!using_limit && const_cond_result)
1 by brian
clean slate
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;
520.1.22 by Brian Aker
Second pass of thd cleanup
149
    conds= remove_eq_conds(session, conds, &result);
1 by brian
clean slate
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;
520.1.22 by Brian Aker
Second pass of thd cleanup
162
  if ((select && select->check_quick(session, safe_update, limit)) || !limit)
1 by brian
clean slate
163
  {
164
    delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
165
    free_underlaid_joins(session, select_lex);
166
    session->row_count_func= 0;
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
167
    DRIZZLE_DELETE_END();
520.1.22 by Brian Aker
Second pass of thd cleanup
168
    my_ok(session, (ha_rows) session->row_count_func);
1 by brian
clean slate
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
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
180
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
1 by brian
clean slate
181
    if (safe_update && !using_limit)
182
    {
183
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
184
      free_underlaid_joins(session, select_lex);
1 by brian
clean slate
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
  {
482 by Brian Aker
Remove uint.
195
    uint32_t         length= 0;
1 by brian
clean slate
196
    SORT_FIELD  *sortorder;
197
    ha_rows examined_rows;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
198
1 by brian
clean slate
199
    if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
327.2.3 by Brian Aker
Refactoring of class Table
200
      usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
1 by brian
clean slate
201
202
    if (usable_index == MAX_KEY)
203
    {
684 by Brian Aker
Mass cleanup for casting.
204
      table->sort.io_cache= new IO_CACHE;
641.3.9 by Monty Taylor
More removal of my_malloc.
205
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
206
207
327.2.3 by Brian Aker
Refactoring of class Table
208
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
1 by brian
clean slate
209
                                             &length, NULL)) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
210
	  (table->sort.found_records = filesort(session, table, sortorder, length,
1 by brian
clean slate
211
                                                select, HA_POS_ERROR, 1,
212
                                                &examined_rows))
213
	  == HA_POS_ERROR)
214
      {
215
        delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
216
        free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
217
        goto err;
218
      }
219
      /*
220
        Filesort has already found and selected the rows we want to delete,
221
        so we don't need the where clause
222
      */
223
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
224
      free_underlaid_joins(session, select_lex);
1 by brian
clean slate
225
      select= 0;
226
    }
227
  }
228
229
  /* If quick select is used, initialize it before retrieving rows. */
230
  if (select && select->quick && select->quick->reset())
231
  {
232
    delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
233
    free_underlaid_joins(session, select_lex);
1 by brian
clean slate
234
    goto err;
235
  }
236
  if (usable_index==MAX_KEY)
520.1.22 by Brian Aker
Second pass of thd cleanup
237
    init_read_record(&info,session,table,select,1,1);
1 by brian
clean slate
238
  else
520.1.22 by Brian Aker
Second pass of thd cleanup
239
    init_read_record_idx(&info, session, table, 1, usable_index);
1 by brian
clean slate
240
520.1.22 by Brian Aker
Second pass of thd cleanup
241
  session->set_proc_info("updating");
1 by brian
clean slate
242
243
  will_batch= !table->file->start_bulk_delete();
244
245
246
  table->mark_columns_needed_for_delete();
247
520.1.22 by Brian Aker
Second pass of thd cleanup
248
  while (!(error=info.read_record(&info)) && !session->killed &&
249
	 ! session->is_error())
1 by brian
clean slate
250
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
251
    // session->is_error() is tested to disallow delete row on error
252
    if (!(select && select->skip_record())&& ! session->is_error() )
1 by brian
clean slate
253
    {
254
      if (!(error= table->file->ha_delete_row(table->record[0])))
255
      {
256
	deleted++;
257
	if (!--limit && using_limit)
258
	{
259
	  error= -1;
260
	  break;
261
	}
262
      }
263
      else
264
      {
265
	table->file->print_error(error,MYF(0));
266
	/*
267
	  In < 4.0.14 we set the error number to 0 here, but that
268
	  was not sensible, because then MySQL would not roll back the
269
	  failed DELETE, and also wrote it to the binlog. For MyISAM
270
	  tables a DELETE probably never should fail (?), but for
271
	  InnoDB it can fail in a FOREIGN KEY error or an
272
	  out-of-tablespace error.
273
	*/
274
 	error= 1;
275
	break;
276
      }
277
    }
278
    else
279
      table->file->unlock_row();  // Row failed selection, release lock on it
280
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
281
  killed_status= session->killed;
282
  if (killed_status != Session::NOT_KILLED || session->is_error())
1 by brian
clean slate
283
    error= 1;					// Aborted
284
  if (will_batch && (loc_error= table->file->end_bulk_delete()))
285
  {
286
    if (error != 1)
287
      table->file->print_error(loc_error,MYF(0));
288
    error=1;
289
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
290
  session->set_proc_info("end");
1 by brian
clean slate
291
  end_read_record(&info);
292
  if (options & OPTION_QUICK)
293
    (void) table->file->extra(HA_EXTRA_NORMAL);
294
295
  if (reset_auto_increment && (error < 0))
296
  {
297
    /*
298
      We're really doing a truncate and need to reset the table's
299
      auto-increment counter.
300
    */
301
    int error2= table->file->ha_reset_auto_increment(0);
302
303
    if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
304
    {
305
      table->file->print_error(error2, MYF(0));
306
      error= 1;
307
    }
308
  }
309
310
cleanup:
311
312
  delete select;
313
  transactional_table= table->file->has_transactions();
314
315
  if (!transactional_table && deleted > 0)
520.1.22 by Brian Aker
Second pass of thd cleanup
316
    session->transaction.stmt.modified_non_trans_table= true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
317
1 by brian
clean slate
318
  /* See similar binlogging code in sql_update.cc, for comments */
520.1.22 by Brian Aker
Second pass of thd cleanup
319
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
320
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
321
    if (session->transaction.stmt.modified_non_trans_table)
322
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
323
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
324
  assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
325
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
326
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
327
  DRIZZLE_DELETE_END();
520.1.22 by Brian Aker
Second pass of thd cleanup
328
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
1 by brian
clean slate
329
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
330
    session->row_count_func= deleted;
331
    my_ok(session, (ha_rows) session->row_count_func);
1 by brian
clean slate
332
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
333
  return(error >= 0 || session->is_error());
1 by brian
clean slate
334
335
err:
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
336
  DRIZZLE_DELETE_END();
163 by Brian Aker
Merge Monty's code.
337
  return(true);
1 by brian
clean slate
338
}
339
340
341
/*
342
  Prepare items in DELETE statement
343
344
  SYNOPSIS
345
    mysql_prepare_delete()
520.1.22 by Brian Aker
Second pass of thd cleanup
346
    session			- thread handler
1 by brian
clean slate
347
    table_list		- global/local table list
348
    conds		- conditions
349
350
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
351
    false OK
352
    true  error
1 by brian
clean slate
353
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
354
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
1 by brian
clean slate
355
{
520.1.22 by Brian Aker
Second pass of thd cleanup
356
  SELECT_LEX *select_lex= &session->lex->select_lex;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
357
1 by brian
clean slate
358
  List<Item> all_fields;
359
520.1.22 by Brian Aker
Second pass of thd cleanup
360
  session->lex->allow_sum_func= 0;
361
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
362
                                    &session->lex->select_lex.top_join_list,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
363
                                    table_list,
1 by brian
clean slate
364
                                    &select_lex->leaf_tables, false) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
365
      setup_conds(session, table_list, select_lex->leaf_tables, conds))
163 by Brian Aker
Merge Monty's code.
366
    return(true);
1 by brian
clean slate
367
  {
327.2.4 by Brian Aker
Refactoring table.h
368
    TableList *duplicate;
520.1.22 by Brian Aker
Second pass of thd cleanup
369
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
1 by brian
clean slate
370
    {
371
      update_non_unique_table_error(table_list, "DELETE", duplicate);
163 by Brian Aker
Merge Monty's code.
372
      return(true);
1 by brian
clean slate
373
    }
374
  }
375
376
  if (select_lex->inner_refs_list.elements &&
520.1.22 by Brian Aker
Second pass of thd cleanup
377
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
51.2.2 by Patrick Galbraith
Removed DBUGs from
378
    return(-1);
1 by brian
clean slate
379
163 by Brian Aker
Merge Monty's code.
380
  return(false);
1 by brian
clean slate
381
}
382
383
384
/***************************************************************************
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
385
  Delete multiple tables from join
1 by brian
clean slate
386
***************************************************************************/
387
520.1.22 by Brian Aker
Second pass of thd cleanup
388
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
1 by brian
clean slate
389
390
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
391
{
392
  handler *file= (handler*)arg;
481 by Brian Aker
Remove all of uchar.
393
  return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
1 by brian
clean slate
394
}
395
396
/*
397
  make delete specific preparation and checks after opening tables
398
399
  SYNOPSIS
400
    mysql_multi_delete_prepare()
520.1.22 by Brian Aker
Second pass of thd cleanup
401
    session         thread handler
1 by brian
clean slate
402
403
  RETURN
163 by Brian Aker
Merge Monty's code.
404
    false OK
405
    true  Error
1 by brian
clean slate
406
*/
407
520.1.22 by Brian Aker
Second pass of thd cleanup
408
int mysql_multi_delete_prepare(Session *session)
1 by brian
clean slate
409
{
520.1.22 by Brian Aker
Second pass of thd cleanup
410
  LEX *lex= session->lex;
327.2.4 by Brian Aker
Refactoring table.h
411
  TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
412
  TableList *target_tbl;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
413
1 by brian
clean slate
414
415
  /*
416
    setup_tables() need for VIEWs. JOIN::prepare() will not do it second
417
    time.
418
419
    lex->query_tables also point on local list of DELETE SELECT_LEX
420
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
421
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
422
                                    &session->lex->select_lex.top_join_list,
1 by brian
clean slate
423
                                    lex->query_tables,
424
                                    &lex->select_lex.leaf_tables, false))
163 by Brian Aker
Merge Monty's code.
425
    return(true);
1 by brian
clean slate
426
427
428
  /*
429
    Multi-delete can't be constructed over-union => we always have
430
    single SELECT on top and have to check underlying SELECTs of it
431
  */
163 by Brian Aker
Merge Monty's code.
432
  lex->select_lex.exclude_from_table_unique_test= true;
1 by brian
clean slate
433
  /* Fix tables-to-be-deleted-from list to point at opened tables */
327.2.4 by Brian Aker
Refactoring table.h
434
  for (target_tbl= (TableList*) aux_tables;
1 by brian
clean slate
435
       target_tbl;
436
       target_tbl= target_tbl->next_local)
437
  {
438
    if (!(target_tbl->table= target_tbl->correspondent_table->table))
439
    {
51.2.2 by Patrick Galbraith
Removed DBUGs from
440
      assert(target_tbl->correspondent_table->merge_underlying_list &&
1 by brian
clean slate
441
                  target_tbl->correspondent_table->merge_underlying_list->
442
                  next_local);
443
      my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
163 by Brian Aker
Merge Monty's code.
444
      return(true);
1 by brian
clean slate
445
    }
446
447
    /*
448
      Check that table from which we delete is not used somewhere
449
      inside subqueries/view.
450
    */
451
    {
327.2.4 by Brian Aker
Refactoring table.h
452
      TableList *duplicate;
520.1.22 by Brian Aker
Second pass of thd cleanup
453
      if ((duplicate= unique_table(session, target_tbl->correspondent_table,
1 by brian
clean slate
454
                                   lex->query_tables, 0)))
455
      {
456
        update_non_unique_table_error(target_tbl->correspondent_table,
457
                                      "DELETE", duplicate);
163 by Brian Aker
Merge Monty's code.
458
        return(true);
1 by brian
clean slate
459
      }
460
    }
461
  }
163 by Brian Aker
Merge Monty's code.
462
  return(false);
1 by brian
clean slate
463
}
464
465
482 by Brian Aker
Remove uint.
466
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
1 by brian
clean slate
467
  : delete_tables(dt), deleted(0), found(0),
468
    num_of_tables(num_of_tables_arg), error(0),
469
    do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
470
{
471
  tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
472
}
473
474
475
int
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
476
multi_delete::prepare(List<Item> &, SELECT_LEX_UNIT *u)
1 by brian
clean slate
477
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
478
1 by brian
clean slate
479
  unit= u;
480
  do_delete= 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
481
  session->set_proc_info("deleting from main table");
51.2.2 by Patrick Galbraith
Removed DBUGs from
482
  return(0);
1 by brian
clean slate
483
}
484
485
486
bool
487
multi_delete::initialize_tables(JOIN *join)
488
{
327.2.4 by Brian Aker
Refactoring table.h
489
  TableList *walk;
1 by brian
clean slate
490
  Unique **tempfiles_ptr;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
491
1 by brian
clean slate
492
520.1.22 by Brian Aker
Second pass of thd cleanup
493
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
51.2.2 by Patrick Galbraith
Removed DBUGs from
494
    return(1);
1 by brian
clean slate
495
496
  table_map tables_to_delete_from=0;
497
  for (walk= delete_tables; walk; walk= walk->next_local)
498
    tables_to_delete_from|= walk->table->map;
499
500
  walk= delete_tables;
501
  delete_while_scanning= 1;
502
  for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
503
       tab < end;
504
       tab++)
505
  {
506
    if (tab->table->map & tables_to_delete_from)
507
    {
508
      /* We are going to delete from this table */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
509
      Table *tbl=walk->table=tab->table;
1 by brian
clean slate
510
      walk= walk->next_local;
511
      /* Don't use KEYREAD optimization on this table */
512
      tbl->no_keyread=1;
513
      /* Don't use record cache */
514
      tbl->no_cache= 1;
515
      tbl->covering_keys.clear_all();
516
      if (tbl->file->has_transactions())
517
	transactional_tables= 1;
518
      else
519
	normal_tables= 1;
520
      tbl->prepare_for_position();
521
      tbl->mark_columns_needed_for_delete();
522
    }
523
    else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
524
             walk == delete_tables)
525
    {
526
      /*
527
        We are not deleting from the table we are scanning. In this
528
        case send_data() shouldn't delete any rows a we may touch
529
        the rows in the deleted table many times
530
      */
531
      delete_while_scanning= 0;
532
    }
533
  }
534
  walk= delete_tables;
535
  tempfiles_ptr= tempfiles;
536
  if (delete_while_scanning)
537
  {
538
    table_being_deleted= delete_tables;
539
    walk= walk->next_local;
540
  }
541
  for (;walk ;walk= walk->next_local)
542
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
543
    Table *table=walk->table;
1 by brian
clean slate
544
    *tempfiles_ptr++= new Unique (refpos_order_cmp,
545
				  (void *) table->file,
546
				  table->file->ref_length,
547
				  MEM_STRIP_BUF_SIZE);
548
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
549
  return(session->is_fatal_error != 0);
1 by brian
clean slate
550
}
551
552
553
multi_delete::~multi_delete()
554
{
555
  for (table_being_deleted= delete_tables;
556
       table_being_deleted;
557
       table_being_deleted= table_being_deleted->next_local)
558
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
559
    Table *table= table_being_deleted->table;
1 by brian
clean slate
560
    table->no_keyread=0;
561
  }
562
482 by Brian Aker
Remove uint.
563
  for (uint32_t counter= 0; counter < num_of_tables; counter++)
1 by brian
clean slate
564
  {
565
    if (tempfiles[counter])
566
      delete tempfiles[counter];
567
  }
568
}
569
570
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
571
bool multi_delete::send_data(List<Item> &)
1 by brian
clean slate
572
{
573
  int secure_counter= delete_while_scanning ? -1 : 0;
327.2.4 by Brian Aker
Refactoring table.h
574
  TableList *del_table;
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
575
1 by brian
clean slate
576
577
  for (del_table= delete_tables;
578
       del_table;
579
       del_table= del_table->next_local, secure_counter++)
580
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
581
    Table *table= del_table->table;
1 by brian
clean slate
582
583
    /* Check if we are using outer join and we didn't find the row */
584
    if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
585
      continue;
586
587
    table->file->position(table->record[0]);
588
    found++;
589
590
    if (secure_counter < 0)
591
    {
592
      /* We are scanning the current table */
51.2.2 by Patrick Galbraith
Removed DBUGs from
593
      assert(del_table == table_being_deleted);
1 by brian
clean slate
594
      table->status|= STATUS_DELETED;
595
      if (!(error=table->file->ha_delete_row(table->record[0])))
596
      {
597
        deleted++;
598
        if (!table->file->has_transactions())
520.1.22 by Brian Aker
Second pass of thd cleanup
599
          session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
600
      }
601
      else
602
      {
603
        table->file->print_error(error,MYF(0));
51.2.2 by Patrick Galbraith
Removed DBUGs from
604
        return(1);
1 by brian
clean slate
605
      }
606
    }
607
    else
608
    {
609
      error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
610
      if (error)
611
      {
612
	error= 1;                               // Fatal error
51.2.2 by Patrick Galbraith
Removed DBUGs from
613
	return(1);
1 by brian
clean slate
614
      }
615
    }
616
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
617
  return(0);
1 by brian
clean slate
618
}
619
620
482 by Brian Aker
Remove uint.
621
void multi_delete::send_error(uint32_t errcode,const char *err)
1 by brian
clean slate
622
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
623
1 by brian
clean slate
624
625
  /* First send error what ever it is ... */
626
  my_message(errcode, err, MYF(0));
627
51.2.2 by Patrick Galbraith
Removed DBUGs from
628
  return;
1 by brian
clean slate
629
}
630
631
632
void multi_delete::abort()
633
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
634
1 by brian
clean slate
635
636
  /* the error was handled or nothing deleted and no side effects return */
637
  if (error_handled ||
520.1.22 by Brian Aker
Second pass of thd cleanup
638
      (!session->transaction.stmt.modified_non_trans_table && !deleted))
51.2.2 by Patrick Galbraith
Removed DBUGs from
639
    return;
1 by brian
clean slate
640
641
  /*
642
    If rows from the first table only has been deleted and it is
643
    transactional, just do rollback.
644
    The same if all tables are transactional, regardless of where we are.
645
    In all other cases do attempt deletes ...
646
  */
647
  if (do_delete && normal_tables &&
648
      (table_being_deleted != delete_tables ||
649
       !table_being_deleted->table->file->has_transactions()))
650
  {
651
    /*
652
      We have to execute the recorded do_deletes() and write info into the
653
      error log
654
    */
655
    error= 1;
656
    send_eof();
51.2.2 by Patrick Galbraith
Removed DBUGs from
657
    assert(error_handled);
658
    return;
1 by brian
clean slate
659
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
660
520.1.22 by Brian Aker
Second pass of thd cleanup
661
  if (session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
662
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
663
    session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
664
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
665
  return;
1 by brian
clean slate
666
}
667
668
669
670
/*
671
  Do delete from other tables.
672
  Returns values:
673
	0 ok
674
	1 error
675
*/
676
677
int multi_delete::do_deletes()
678
{
679
  int local_error= 0, counter= 0, tmp_error;
680
  bool will_batch;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
681
51.2.2 by Patrick Galbraith
Removed DBUGs from
682
  assert(do_delete);
1 by brian
clean slate
683
684
  do_delete= 0;                                 // Mark called
685
  if (!found)
51.2.2 by Patrick Galbraith
Removed DBUGs from
686
    return(0);
1 by brian
clean slate
687
688
  table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
689
                        delete_tables);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
690
1 by brian
clean slate
691
  for (; table_being_deleted;
692
       table_being_deleted= table_being_deleted->next_local, counter++)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
693
  {
1 by brian
clean slate
694
    ha_rows last_deleted= deleted;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
695
    Table *table = table_being_deleted->table;
1 by brian
clean slate
696
    if (tempfiles[counter]->get(table))
697
    {
698
      local_error=1;
699
      break;
700
    }
701
702
    READ_RECORD	info;
520.1.22 by Brian Aker
Second pass of thd cleanup
703
    init_read_record(&info,session,table,NULL,0,1);
1 by brian
clean slate
704
    /*
705
      Ignore any rows not found in reference tables as they may already have
706
      been deleted by foreign key handling
707
    */
708
    info.ignore_not_found_rows= 1;
709
    will_batch= !table->file->start_bulk_delete();
520.1.22 by Brian Aker
Second pass of thd cleanup
710
    while (!(local_error=info.read_record(&info)) && !session->killed)
1 by brian
clean slate
711
    {
712
      if ((local_error=table->file->ha_delete_row(table->record[0])))
713
      {
714
	table->file->print_error(local_error,MYF(0));
715
	break;
716
      }
717
      deleted++;
718
    }
719
    if (will_batch && (tmp_error= table->file->end_bulk_delete()))
720
    {
721
      if (!local_error)
722
      {
723
        local_error= tmp_error;
724
        table->file->print_error(local_error,MYF(0));
725
      }
726
    }
727
    if (last_deleted != deleted && !table->file->has_transactions())
520.1.22 by Brian Aker
Second pass of thd cleanup
728
      session->transaction.stmt.modified_non_trans_table= true;
1 by brian
clean slate
729
    end_read_record(&info);
520.1.22 by Brian Aker
Second pass of thd cleanup
730
    if (session->killed && !local_error)
1 by brian
clean slate
731
      local_error= 1;
732
    if (local_error == -1)				// End of file
733
      local_error = 0;
734
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
735
  return(local_error);
1 by brian
clean slate
736
}
737
738
739
/*
740
  Send ok to the client
741
742
  return:  0 sucess
743
	   1 error
744
*/
745
746
bool multi_delete::send_eof()
747
{
520.1.21 by Brian Aker
THD -> Session rename
748
  Session::killed_state killed_status= Session::NOT_KILLED;
520.1.22 by Brian Aker
Second pass of thd cleanup
749
  session->set_proc_info("deleting from reference tables");
1 by brian
clean slate
750
751
  /* Does deletes for the last n - 1 tables, returns 0 if ok */
752
  int local_error= do_deletes();		// returns 0 if success
753
754
  /* compute a total error to know if something failed */
755
  local_error= local_error || error;
520.1.22 by Brian Aker
Second pass of thd cleanup
756
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
1 by brian
clean slate
757
  /* reset used flags */
520.1.22 by Brian Aker
Second pass of thd cleanup
758
  session->set_proc_info("end");
1 by brian
clean slate
759
520.1.22 by Brian Aker
Second pass of thd cleanup
760
  if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
761
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
762
    if (session->transaction.stmt.modified_non_trans_table)
763
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
764
  }
765
  if (local_error != 0)
163 by Brian Aker
Merge Monty's code.
766
    error_handled= true; // to force early leave from ::send_error()
1 by brian
clean slate
767
768
  if (!local_error)
769
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
770
    session->row_count_func= deleted;
771
    ::my_ok(session, (ha_rows) session->row_count_func);
1 by brian
clean slate
772
  }
773
  return 0;
774
}
775
776
777
/***************************************************************************
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
778
  TRUNCATE Table
1 by brian
clean slate
779
****************************************************************************/
780
781
/*
782
  Optimize delete of all rows by doing a full generate of the table
783
  This will work even if the .ISM and .ISD tables are destroyed
784
785
  dont_send_ok should be set if:
786
  - We should always wants to generate the table (even if the table type
787
    normally can't safely do this.
788
  - We don't want an ok to be sent to the end user.
789
  - We don't want to log the truncate command
790
  - If we want to have a name lock on the table on exit without errors.
791
*/
792
520.1.22 by Brian Aker
Second pass of thd cleanup
793
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
1 by brian
clean slate
794
{
795
  HA_CREATE_INFO create_info;
796
  char path[FN_REFLEN];
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
797
  Table *table;
1 by brian
clean slate
798
  bool error;
482 by Brian Aker
Remove uint.
799
  uint32_t path_length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
800
1 by brian
clean slate
801
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
802
  memset(&create_info, 0, sizeof(create_info));
1 by brian
clean slate
803
  /* If it is a temporary table, close and regenerate it */
520.1.22 by Brian Aker
Second pass of thd cleanup
804
  if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
1 by brian
clean slate
805
  {
806
    handlerton *table_type= table->s->db_type();
807
    TABLE_SHARE *share= table->s;
808
631.1.2 by Yoshinori Sano
Move hton_flag_bits and HTON_* to handlerton.h. Remove TODOs previously added.
809
    if (!ha_check_storage_engine_flag(table_type, HTON_BIT_CAN_RECREATE))
1 by brian
clean slate
810
      goto trunc_by_del;
811
812
    table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
813
520.1.22 by Brian Aker
Second pass of thd cleanup
814
    close_temporary_table(session, table, 0, 0);    // Don't free share
815
    ha_create_table(session, share->normalized_path.str,
1 by brian
clean slate
816
                    share->db.str, share->table_name.str, &create_info, 1);
817
    // We don't need to call invalidate() because this table is not in cache
520.1.22 by Brian Aker
Second pass of thd cleanup
818
    if ((error= (int) !(open_temporary_table(session, share->path.str,
1 by brian
clean slate
819
                                             share->db.str,
820
					     share->table_name.str, 1,
821
                                             OTM_OPEN))))
590.1.3 by Stewart Smith
remove frm_only create_info option
822
      (void) rm_temporary_table(table_type, path);
1 by brian
clean slate
823
    free_table_share(share);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
824
    free((char*) table);
1 by brian
clean slate
825
    /*
826
      If we return here we will not have logged the truncation to the bin log
827
      and we will not my_ok() to the client.
828
    */
829
    goto end;
830
  }
831
832
  path_length= build_table_filename(path, sizeof(path), table_list->db,
833
                                    table_list->table_name, reg_ext, 0);
834
835
  if (!dont_send_ok)
410 by Brian Aker
Removed legacy type, but truncate is no longer doing recreate. This should
836
    goto trunc_by_del;
1 by brian
clean slate
837
838
  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
839
  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
840
  // '\0';
841
  path[path_length - reg_ext_length] = 0;
398.1.10 by Monty Taylor
Actually removed VOID() this time.
842
  pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
843
  error= ha_create_table(session, path, table_list->db, table_list->table_name,
1 by brian
clean slate
844
                         &create_info, 1);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
845
  pthread_mutex_unlock(&LOCK_open);
1 by brian
clean slate
846
847
end:
848
  if (!dont_send_ok)
849
  {
850
    if (!error)
851
    {
852
      /*
853
        TRUNCATE must always be statement-based binlogged (not row-based) so
854
        we don't test current_stmt_binlog_row_based.
855
      */
520.1.22 by Brian Aker
Second pass of thd cleanup
856
      write_bin_log(session, true, session->query, session->query_length);
857
      my_ok(session);		// This should return record count
1 by brian
clean slate
858
    }
398.1.10 by Monty Taylor
Actually removed VOID() this time.
859
    pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
860
    unlock_table_name(session, table_list);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
861
    pthread_mutex_unlock(&LOCK_open);
1 by brian
clean slate
862
  }
863
  else if (error)
864
  {
398.1.10 by Monty Taylor
Actually removed VOID() this time.
865
    pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
866
    unlock_table_name(session, table_list);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
867
    pthread_mutex_unlock(&LOCK_open);
1 by brian
clean slate
868
  }
51.2.2 by Patrick Galbraith
Removed DBUGs from
869
  return(error);
1 by brian
clean slate
870
871
trunc_by_del:
872
  /* Probably InnoDB table */
520.1.22 by Brian Aker
Second pass of thd cleanup
873
  uint64_t save_options= session->options;
1 by brian
clean slate
874
  table_list->lock_type= TL_WRITE;
520.1.22 by Brian Aker
Second pass of thd cleanup
875
  session->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
876
  ha_enable_transaction(session, false);
877
  mysql_init_select(session->lex);
878
  error= mysql_delete(session, table_list, (COND*) 0, (SQL_LIST*) 0,
398.1.8 by Monty Taylor
Enabled -Wlong-long.
879
                      HA_POS_ERROR, 0L, true);
520.1.22 by Brian Aker
Second pass of thd cleanup
880
  ha_enable_transaction(session, true);
1 by brian
clean slate
881
  /*
163 by Brian Aker
Merge Monty's code.
882
    Safety, in case the engine ignored ha_enable_transaction(false)
520.1.22 by Brian Aker
Second pass of thd cleanup
883
    above. Also clears session->transaction.*.
1 by brian
clean slate
884
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
885
  error= ha_autocommit_or_rollback(session, error);
886
  ha_commit(session);
887
  session->options= save_options;
51.2.2 by Patrick Galbraith
Removed DBUGs from
888
  return(error);
1 by brian
clean slate
889
}