~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
*/
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
21
#include "config.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
22
#include "drizzled/sql_select.h"
23
#include "drizzled/error.h"
24
#include "drizzled/probes.h"
25
#include "drizzled/sql_parse.h"
26
#include "drizzled/sql_base.h"
27
#include "drizzled/lock.h"
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
28
#include "drizzled/probes.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
29
#include "drizzled/optimizer/range.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
30
#include "drizzled/records.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
31
#include "drizzled/internal/iocache.h"
1 by brian
clean slate
32
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
33
using namespace drizzled;
34
1 by brian
clean slate
35
/**
36
  Implement DELETE SQL word.
37
38
  @note Like implementations of other DDL/DML in MySQL, this function
39
  relies on the caller to close the thread tables. This is done in the
40
  end of dispatch_command().
41
*/
42
520.1.22 by Brian Aker
Second pass of thd cleanup
43
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
44
                  SQL_LIST *order, ha_rows limit, uint64_t,
1 by brian
clean slate
45
                  bool reset_auto_increment)
46
{
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
47
  int		error;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
48
  Table		*table;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
49
  optimizer::SqlSelect *select= NULL;
1 by brian
clean slate
50
  READ_RECORD	info;
51
  bool          using_limit=limit != HA_POS_ERROR;
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
52
  bool		transactional_table, const_cond;
1 by brian
clean slate
53
  bool          const_cond_result;
54
  ha_rows	deleted= 0;
482 by Brian Aker
Remove uint.
55
  uint32_t usable_index= MAX_KEY;
846 by Brian Aker
Removing on typedeffed class.
56
  Select_Lex   *select_lex= &session->lex->select_lex;
520.1.21 by Brian Aker
THD -> Session rename
57
  Session::killed_state killed_status= Session::NOT_KILLED;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
58
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
59
  if (session->openTablesLock(table_list))
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
60
  {
61
    DRIZZLE_DELETE_DONE(1, 0);
1109.1.2 by Brian Aker
More from the table patch
62
    return true;
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
63
  }
737 by Brian Aker
Updates for dead code removal (and forced assert() in delete).
64
65
  table= table_list->table;
66
  assert(table);
67
520.1.22 by Brian Aker
Second pass of thd cleanup
68
  session->set_proc_info("init");
1 by brian
clean slate
69
  table->map=1;
70
520.1.22 by Brian Aker
Second pass of thd cleanup
71
  if (mysql_prepare_delete(session, table_list, &conds))
1 by brian
clean slate
72
    goto err;
73
74
  /* check ORDER BY even if it can be ignored */
75
  if (order && order->elements)
76
  {
327.2.4 by Brian Aker
Refactoring table.h
77
    TableList   tables;
1 by brian
clean slate
78
    List<Item>   fields;
79
    List<Item>   all_fields;
80
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
81
    memset(&tables, 0, sizeof(tables));
1 by brian
clean slate
82
    tables.table = table;
83
    tables.alias = table_list->alias;
84
520.1.22 by Brian Aker
Second pass of thd cleanup
85
      if (select_lex->setup_ref_array(session, order->elements) ||
86
	  setup_order(session, select_lex->ref_pointer_array, &tables,
327.2.3 by Brian Aker
Refactoring of class Table
87
                    fields, all_fields, (order_st*) order->first))
1 by brian
clean slate
88
    {
89
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
90
      free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
91
      goto err;
92
    }
93
  }
94
95
  const_cond= (!conds || conds->const_item());
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
  {
1208.3.2 by brian
Update for Cursor renaming.
127
    /* Update the table->cursor->stats.records number */
128
    table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
129
    ha_rows const maybe_deleted= table->cursor->stats.records;
130
    if (!(error=table->cursor->ha_delete_all_rows()))
1 by brian
clean slate
131
    {
132
      error= -1;				// ok
133
      deleted= maybe_deleted;
134
      goto cleanup;
135
    }
136
    if (error != HA_ERR_WRONG_COMMAND)
137
    {
1216.1.1 by Brian Aker
Move print_error up to Engine.
138
      table->print_error(error,MYF(0));
1 by brian
clean slate
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
1208.3.2 by brian
Update for Cursor renaming.
152
  /* Update the table->cursor->stats.records number */
153
  table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1 by brian
clean slate
154
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
155
  table->covering_keys.reset();
156
  table->quick_keys.reset();		// Can't use 'only index'
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
157
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
1 by brian
clean slate
158
  if (error)
159
    goto err;
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
160
  if ((select && select->check_quick(session, false, 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;
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
165
    DRIZZLE_DELETE_DONE(0, 0);
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
166
    /**
167
     * Resetting the Diagnostic area to prevent
168
     * lp bug# 439719
169
     */
170
    session->main_da.reset_diagnostics_area();
836 by Brian Aker
Fixed session call from function to method.
171
    session->my_ok((ha_rows) session->row_count_func);
1 by brian
clean slate
172
    /*
173
      We don't need to call reset_auto_increment in this case, because
174
      mysql_truncate always gives a NULL conds argument, hence we never
175
      get here.
176
    */
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
177
    return 0; // Nothing to delete
1 by brian
clean slate
178
  }
179
180
  /* If running in safe sql mode, don't allow updates without keys */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
181
  if (table->quick_keys.none())
1 by brian
clean slate
182
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
183
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
1 by brian
clean slate
184
  }
185
186
  if (order && order->elements)
187
  {
482 by Brian Aker
Remove uint.
188
    uint32_t         length= 0;
1 by brian
clean slate
189
    SORT_FIELD  *sortorder;
190
    ha_rows examined_rows;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
191
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
192
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
193
      usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
1 by brian
clean slate
194
195
    if (usable_index == MAX_KEY)
196
    {
684 by Brian Aker
Mass cleanup for casting.
197
      table->sort.io_cache= new IO_CACHE;
641.3.9 by Monty Taylor
More removal of my_malloc.
198
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
199
200
327.2.3 by Brian Aker
Refactoring of class Table
201
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
1 by brian
clean slate
202
                                             &length, NULL)) ||
520.1.22 by Brian Aker
Second pass of thd cleanup
203
	  (table->sort.found_records = filesort(session, table, sortorder, length,
1 by brian
clean slate
204
                                                select, HA_POS_ERROR, 1,
205
                                                &examined_rows))
206
	  == HA_POS_ERROR)
207
      {
208
        delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
209
        free_underlaid_joins(session, &session->lex->select_lex);
1 by brian
clean slate
210
        goto err;
211
      }
212
      /*
213
        Filesort has already found and selected the rows we want to delete,
214
        so we don't need the where clause
215
      */
216
      delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
217
      free_underlaid_joins(session, select_lex);
1 by brian
clean slate
218
      select= 0;
219
    }
220
  }
221
222
  /* If quick select is used, initialize it before retrieving rows. */
223
  if (select && select->quick && select->quick->reset())
224
  {
225
    delete select;
520.1.22 by Brian Aker
Second pass of thd cleanup
226
    free_underlaid_joins(session, select_lex);
1 by brian
clean slate
227
    goto err;
228
  }
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
229
1 by brian
clean slate
230
  if (usable_index==MAX_KEY)
520.1.22 by Brian Aker
Second pass of thd cleanup
231
    init_read_record(&info,session,table,select,1,1);
1 by brian
clean slate
232
  else
520.1.22 by Brian Aker
Second pass of thd cleanup
233
    init_read_record_idx(&info, session, table, 1, usable_index);
1 by brian
clean slate
234
520.1.22 by Brian Aker
Second pass of thd cleanup
235
  session->set_proc_info("updating");
1 by brian
clean slate
236
237
  table->mark_columns_needed_for_delete();
238
520.1.22 by Brian Aker
Second pass of thd cleanup
239
  while (!(error=info.read_record(&info)) && !session->killed &&
240
	 ! session->is_error())
1 by brian
clean slate
241
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
242
    // session->is_error() is tested to disallow delete row on error
243
    if (!(select && select->skip_record())&& ! session->is_error() )
1 by brian
clean slate
244
    {
1208.3.2 by brian
Update for Cursor renaming.
245
      if (!(error= table->cursor->ha_delete_row(table->record[0])))
1 by brian
clean slate
246
      {
247
	deleted++;
248
	if (!--limit && using_limit)
249
	{
250
	  error= -1;
251
	  break;
252
	}
253
      }
254
      else
255
      {
1216.1.1 by Brian Aker
Move print_error up to Engine.
256
	table->print_error(error,MYF(0));
1 by brian
clean slate
257
	/*
258
	  In < 4.0.14 we set the error number to 0 here, but that
259
	  was not sensible, because then MySQL would not roll back the
260
	  failed DELETE, and also wrote it to the binlog. For MyISAM
261
	  tables a DELETE probably never should fail (?), but for
262
	  InnoDB it can fail in a FOREIGN KEY error or an
263
	  out-of-tablespace error.
264
	*/
265
 	error= 1;
266
	break;
267
      }
268
    }
269
    else
1208.3.2 by brian
Update for Cursor renaming.
270
      table->cursor->unlock_row();  // Row failed selection, release lock on it
1 by brian
clean slate
271
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
272
  killed_status= session->killed;
273
  if (killed_status != Session::NOT_KILLED || session->is_error())
1 by brian
clean slate
274
    error= 1;					// Aborted
1237.6.1 by Brian Aker
Remove dead bits in parser/whitespace/etc.
275
520.1.22 by Brian Aker
Second pass of thd cleanup
276
  session->set_proc_info("end");
1 by brian
clean slate
277
  end_read_record(&info);
278
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
279
cleanup:
280
1 by brian
clean slate
281
  if (reset_auto_increment && (error < 0))
282
  {
283
    /*
284
      We're really doing a truncate and need to reset the table's
285
      auto-increment counter.
286
    */
1208.3.2 by brian
Update for Cursor renaming.
287
    int error2= table->cursor->ha_reset_auto_increment(0);
1 by brian
clean slate
288
289
    if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
290
    {
1216.1.1 by Brian Aker
Move print_error up to Engine.
291
      table->print_error(error2, MYF(0));
1 by brian
clean slate
292
      error= 1;
293
    }
294
  }
295
296
  delete select;
1208.3.2 by brian
Update for Cursor renaming.
297
  transactional_table= table->cursor->has_transactions();
1 by brian
clean slate
298
299
  if (!transactional_table && deleted > 0)
520.1.22 by Brian Aker
Second pass of thd cleanup
300
    session->transaction.stmt.modified_non_trans_table= true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
301
1 by brian
clean slate
302
  /* See similar binlogging code in sql_update.cc, for comments */
520.1.22 by Brian Aker
Second pass of thd cleanup
303
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
1 by brian
clean slate
304
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
305
    if (session->transaction.stmt.modified_non_trans_table)
306
      session->transaction.all.modified_non_trans_table= true;
1 by brian
clean slate
307
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
308
  assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
309
  free_underlaid_joins(session, select_lex);
1 by brian
clean slate
310
1126.10.25 by Padraig O'Sullivan
Updated calls to some dtrace probes to cast the parameter to const char *
311
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
520.1.22 by Brian Aker
Second pass of thd cleanup
312
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
1 by brian
clean slate
313
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
314
    session->row_count_func= deleted;
1124.2.14 by Diego Medina
* On certain UPDATE and DELETE statements, drizzled failed an assert() in
315
    /**
316
     * Resetting the Diagnostic area to prevent
317
     * lp bug# 439719
318
     */
1124.2.16 by Diego Medina
uncommented a call to reset_diagnostics_area()
319
    session->main_da.reset_diagnostics_area();    
836 by Brian Aker
Fixed session call from function to method.
320
    session->my_ok((ha_rows) session->row_count_func);
1 by brian
clean slate
321
  }
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
322
  return (error >= 0 || session->is_error());
1 by brian
clean slate
323
324
err:
1126.10.18 by Padraig O'Sullivan
Various small build fixes for when dtrace is enabled.
325
  DRIZZLE_DELETE_DONE(1, 0);
1126.10.7 by Padraig O'Sullivan
Added calls to the dtrace delete begin/end probes.
326
  return true;
1 by brian
clean slate
327
}
328
329
330
/*
331
  Prepare items in DELETE statement
332
333
  SYNOPSIS
334
    mysql_prepare_delete()
520.1.22 by Brian Aker
Second pass of thd cleanup
335
    session			- thread handler
1 by brian
clean slate
336
    table_list		- global/local table list
337
    conds		- conditions
338
339
  RETURN VALUE
163 by Brian Aker
Merge Monty's code.
340
    false OK
341
    true  error
1 by brian
clean slate
342
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
343
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
1 by brian
clean slate
344
{
846 by Brian Aker
Removing on typedeffed class.
345
  Select_Lex *select_lex= &session->lex->select_lex;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
346
1 by brian
clean slate
347
  List<Item> all_fields;
348
520.1.22 by Brian Aker
Second pass of thd cleanup
349
  session->lex->allow_sum_func= 0;
350
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
351
                                    &session->lex->select_lex.top_join_list,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
352
                                    table_list,
1 by brian
clean slate
353
                                    &select_lex->leaf_tables, false) ||
1109.1.5 by Brian Aker
More extraction from sql_base
354
      session->setup_conds(table_list, conds))
163 by Brian Aker
Merge Monty's code.
355
    return(true);
1 by brian
clean slate
356
  {
327.2.4 by Brian Aker
Refactoring table.h
357
    TableList *duplicate;
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
358
    if ((duplicate= unique_table(table_list, table_list->next_global)))
1 by brian
clean slate
359
    {
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
360
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
163 by Brian Aker
Merge Monty's code.
361
      return(true);
1 by brian
clean slate
362
    }
363
  }
364
365
  if (select_lex->inner_refs_list.elements &&
520.1.22 by Brian Aker
Second pass of thd cleanup
366
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
51.2.2 by Patrick Galbraith
Removed DBUGs from
367
    return(-1);
1 by brian
clean slate
368
163 by Brian Aker
Merge Monty's code.
369
  return(false);
1 by brian
clean slate
370
}
371
372
373
/***************************************************************************
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
374
  TRUNCATE Table
1 by brian
clean slate
375
****************************************************************************/
376
377
/*
378
  Optimize delete of all rows by doing a full generate of the table
379
  This will work even if the .ISM and .ISD tables are destroyed
380
*/
381
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
382
bool mysql_truncate(Session& session, TableList *table_list)
1 by brian
clean slate
383
{
384
  bool error;
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
385
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
386
  uint64_t save_options= session.options;
1 by brian
clean slate
387
  table_list->lock_type= TL_WRITE;
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
388
  session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
389
  ha_enable_transaction(&session, false);
390
  mysql_init_select(session.lex);
391
  error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
398.1.8 by Monty Taylor
Enabled -Wlong-long.
392
                      HA_POS_ERROR, 0L, true);
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
393
  ha_enable_transaction(&session, true);
1 by brian
clean slate
394
  /*
163 by Brian Aker
Merge Monty's code.
395
    Safety, in case the engine ignored ha_enable_transaction(false)
520.1.22 by Brian Aker
Second pass of thd cleanup
396
    above. Also clears session->transaction.*.
1 by brian
clean slate
397
  */
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
398
  error= ha_autocommit_or_rollback(&session, error);
399
  ha_commit(&session);
400
  session.options= save_options;
401
1208.2.2 by Brian Aker
Merge Truncate patch. This fixes all of the "half setup" of Truncate. Still
402
  return error;
1 by brian
clean slate
403
}