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