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