~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Olaf van der Spek
  • Date: 2011-10-24 21:23:54 UTC
  • mto: This revision was merged to the branch mainline in revision 2449.
  • Revision ID: olafvdspek@gmail.com-20111024212354-j32gbc2sbsw0985q
Use str_ref

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
  Multi-table deletes were introduced by Monty and Sinisa
20
20
*/
21
 
#include "config.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"
28
 
#include "drizzled/probes.h"
29
 
#include "drizzled/optimizer/range.h"
30
 
#include "drizzled/records.h"
31
 
#include "drizzled/internal/iocache.h"
32
 
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/filesort.h"
 
21
#include <config.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>
 
28
#include <drizzled/probes.h>
 
29
#include <drizzled/optimizer/range.h>
 
30
#include <drizzled/records.h>
 
31
#include <drizzled/internal/iocache.h>
 
32
#include <drizzled/transaction_services.h>
 
33
#include <drizzled/filesort.h>
 
34
#include <drizzled/sql_lex.h>
 
35
#include <drizzled/diagnostics_area.h>
 
36
#include <drizzled/statistics_variables.h>
 
37
#include <drizzled/session/transactions.h>
34
38
 
35
 
namespace drizzled
36
 
{
 
39
namespace drizzled {
37
40
 
38
41
/**
39
42
  Implement DELETE SQL word.
43
46
  end of dispatch_command().
44
47
*/
45
48
 
46
 
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
 
49
bool delete_query(Session *session, TableList *table_list, COND *conds,
47
50
                  SQL_LIST *order, ha_rows limit, uint64_t,
48
51
                  bool reset_auto_increment)
49
52
{
52
55
  optimizer::SqlSelect *select= NULL;
53
56
  ReadRecord    info;
54
57
  bool          using_limit=limit != HA_POS_ERROR;
55
 
  bool          transactional_table, const_cond;
56
 
  bool          const_cond_result;
57
58
  ha_rows       deleted= 0;
58
59
  uint32_t usable_index= MAX_KEY;
59
 
  Select_Lex   *select_lex= &session->lex->select_lex;
 
60
  Select_Lex   *select_lex= &session->lex().select_lex;
60
61
  Session::killed_state_t killed_status= Session::NOT_KILLED;
61
62
 
62
63
  if (session->openTablesLock(table_list))
71
72
  session->set_proc_info("init");
72
73
  table->map=1;
73
74
 
74
 
  if (mysql_prepare_delete(session, table_list, &conds))
 
75
  if (prepare_delete(session, table_list, &conds))
75
76
  {
76
77
    DRIZZLE_DELETE_DONE(1, 0);
77
78
    return true;
87
88
    tables.table = table;
88
89
    tables.alias = table_list->alias;
89
90
 
90
 
      if (select_lex->setup_ref_array(session, order->elements) ||
91
 
          setup_order(session, select_lex->ref_pointer_array, &tables,
92
 
                    fields, all_fields, (Order*) order->first))
93
 
      {
94
 
        delete select;
95
 
        free_underlaid_joins(session, &session->lex->select_lex);
96
 
        DRIZZLE_DELETE_DONE(1, 0);
 
91
    select_lex->setup_ref_array(session, order->elements);
 
92
    if (setup_order(session, select_lex->ref_pointer_array, &tables, fields, all_fields, (Order*) order->first))
 
93
    {
 
94
      delete select;
 
95
      free_underlaid_joins(session, &session->lex().select_lex);
 
96
      DRIZZLE_DELETE_DONE(1, 0);
97
97
 
98
 
        return true;
99
 
      }
 
98
      return true;
 
99
    }
100
100
  }
101
101
 
102
 
  const_cond= (!conds || conds->const_item());
103
 
 
104
 
  select_lex->no_error= session->lex->ignore;
105
 
 
106
 
  const_cond_result= const_cond && (!conds || conds->val_int());
 
102
  bool const_cond= not conds || conds->const_item();
 
103
 
 
104
  select_lex->no_error= session->lex().ignore;
 
105
 
 
106
  bool const_cond_result= const_cond && (!conds || conds->val_int());
107
107
  if (session->is_error())
108
108
  {
109
109
    /* Error evaluating val_int(). */
110
 
    return(true);
 
110
    return true;
111
111
  }
112
112
 
113
113
  /*
173
173
    delete select;
174
174
    free_underlaid_joins(session, select_lex);
175
175
    session->row_count_func= 0;
 
176
    if (session->is_error())
 
177
      return true;
176
178
    DRIZZLE_DELETE_DONE(0, 0);
177
179
    /**
178
180
     * Resetting the Diagnostic area to prevent
179
181
     * lp bug# 439719
180
182
     */
181
 
    session->main_da.reset_diagnostics_area();
182
 
    session->my_ok((ha_rows) session->row_count_func);
 
183
    session->main_da().reset_diagnostics_area();
 
184
    session->my_ok((ha_rows) session->rowCount());
183
185
    /*
184
186
      We don't need to call reset_auto_increment in this case, because
185
187
      mysql_truncate always gives a NULL conds argument, hence we never
196
198
 
197
199
  if (order && order->elements)
198
200
  {
199
 
    uint32_t         length= 0;
200
 
    SortField  *sortorder;
201
 
    ha_rows examined_rows;
202
 
 
203
201
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
204
202
      usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
205
203
 
206
204
    if (usable_index == MAX_KEY)
207
205
    {
208
206
      FileSort filesort(*session);
209
 
      table->sort.io_cache= new internal::IO_CACHE;
210
 
 
211
 
 
212
 
      if (not (sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL)) ||
213
 
          (table->sort.found_records = filesort.run(table, sortorder, length,
214
 
                                                    select, HA_POS_ERROR, 1,
215
 
                                                    examined_rows)) == HA_POS_ERROR)
 
207
      table->sort.io_cache= new internal::io_cache_st;
 
208
      uint32_t length= 0;
 
209
      SortField* sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL);
 
210
      ha_rows examined_rows;
 
211
      if ((table->sort.found_records= filesort.run(table, sortorder, length, select, HA_POS_ERROR, 1, examined_rows)) == HA_POS_ERROR)
216
212
      {
217
213
        delete select;
218
 
        free_underlaid_joins(session, &session->lex->select_lex);
 
214
        free_underlaid_joins(session, &session->lex().select_lex);
219
215
 
220
216
        DRIZZLE_DELETE_DONE(1, 0);
221
217
        return true;
241
237
 
242
238
  if (usable_index==MAX_KEY)
243
239
  {
244
 
    info.init_read_record(session,table,select,1,1);
 
240
    if ((error= info.init_read_record(session,table,select,1,1)))
 
241
    {
 
242
      table->print_error(error, MYF(0));
 
243
      delete select;
 
244
      free_underlaid_joins(session, select_lex);
 
245
      return true;
 
246
    }
245
247
  }
246
248
  else
247
249
  {
248
 
    info.init_read_record_idx(session, table, 1, usable_index);
 
250
    if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
 
251
    {
 
252
      table->print_error(error, MYF(0));
 
253
      delete select;
 
254
      free_underlaid_joins(session, select_lex);
 
255
      return true;
 
256
    }
249
257
  }
250
258
 
251
259
  session->set_proc_info("updating");
310
318
  }
311
319
 
312
320
  delete select;
313
 
  transactional_table= table->cursor->has_transactions();
 
321
  bool transactional_table= table->cursor->has_transactions();
314
322
 
315
323
  if (!transactional_table && deleted > 0)
316
324
    session->transaction.stmt.markModifiedNonTransData();
325
333
  free_underlaid_joins(session, select_lex);
326
334
 
327
335
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
328
 
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
 
336
  if (error < 0 || (session->lex().ignore && !session->is_fatal_error))
329
337
  {
330
338
    session->row_count_func= deleted;
331
339
    /**
332
340
     * Resetting the Diagnostic area to prevent
333
341
     * lp bug# 439719
334
342
     */
335
 
    session->main_da.reset_diagnostics_area();    
336
 
    session->my_ok((ha_rows) session->row_count_func);
 
343
    session->main_da().reset_diagnostics_area();
 
344
    session->my_ok((ha_rows) session->rowCount());
337
345
  }
338
346
  session->status_var.deleted_row_count+= deleted;
339
347
 
345
353
  Prepare items in DELETE statement
346
354
 
347
355
  SYNOPSIS
348
 
    mysql_prepare_delete()
 
356
    prepare_delete()
349
357
    session                     - thread handler
350
358
    table_list          - global/local table list
351
359
    conds               - conditions
354
362
    false OK
355
363
    true  error
356
364
*/
357
 
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
 
365
int prepare_delete(Session *session, TableList *table_list, Item **conds)
358
366
{
359
 
  Select_Lex *select_lex= &session->lex->select_lex;
 
367
  Select_Lex *select_lex= &session->lex().select_lex;
 
368
  session->lex().allow_sum_func= 0;
 
369
  if (setup_tables_and_check_access(session, &session->lex().select_lex.context, &select_lex->top_join_list, 
 
370
    table_list, &select_lex->leaf_tables, false) ||
 
371
      session->setup_conds(table_list, conds))
 
372
    return true;
360
373
 
 
374
  if (unique_table(table_list, table_list->next_global))
 
375
  {
 
376
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
 
377
    return true;
 
378
  }
361
379
  List<Item> all_fields;
362
 
 
363
 
  session->lex->allow_sum_func= 0;
364
 
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
365
 
                                    &session->lex->select_lex.top_join_list,
366
 
                                    table_list,
367
 
                                    &select_lex->leaf_tables, false) ||
368
 
      session->setup_conds(table_list, conds))
369
 
    return(true);
370
 
  {
371
 
    TableList *duplicate;
372
 
    if ((duplicate= unique_table(table_list, table_list->next_global)))
373
 
    {
374
 
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
375
 
      return(true);
376
 
    }
377
 
  }
378
 
 
379
 
  if (select_lex->inner_refs_list.elements &&
380
 
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
381
 
    return(-1);
382
 
 
383
 
  return(false);
 
380
  if (select_lex->inner_refs_list.size() && fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
 
381
    return true;
 
382
  return false;
384
383
}
385
384
 
386
385
 
393
392
  This will work even if the .ISM and .ISD tables are destroyed
394
393
*/
395
394
 
396
 
bool mysql_truncate(Session& session, TableList *table_list)
 
395
bool truncate(Session& session, TableList *table_list)
397
396
{
398
 
  bool error;
399
 
  TransactionServices &transaction_services= TransactionServices::singleton();
400
 
 
401
397
  uint64_t save_options= session.options;
402
398
  table_list->lock_type= TL_WRITE;
403
399
  session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
404
 
  mysql_init_select(session.lex);
405
 
  error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
406
 
                      HA_POS_ERROR, 0L, true);
 
400
  init_select(&session.lex());
 
401
  int error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0, HA_POS_ERROR, 0L, true);
407
402
  /*
408
403
    Safety, in case the engine ignored ha_enable_transaction(false)
409
404
    above. Also clears session->transaction.*.
410
405
  */
411
 
  error= transaction_services.autocommitOrRollback(&session, error);
 
406
  error= TransactionServices::autocommitOrRollback(session, error);
412
407
  session.options= save_options;
413
 
 
414
408
  return error;
415
409
}
416
410