~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Brian Aker
  • Date: 2010-08-12 17:19:46 UTC
  • mfrom: (1701.1.1 turn-off-csv)
  • Revision ID: brian@tangent.org-20100812171946-n44naaqhg27gehlh
MErge Monty, remove CSV from auto-build

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  Delete of records and truncate of tables.
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"
34
33
 
35
34
namespace drizzled
36
35
{
43
42
  end of dispatch_command().
44
43
*/
45
44
 
46
 
bool delete_query(Session *session, TableList *table_list, COND *conds,
 
45
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
47
46
                  SQL_LIST *order, ha_rows limit, uint64_t,
48
47
                  bool reset_auto_increment)
49
48
{
56
55
  bool          const_cond_result;
57
56
  ha_rows       deleted= 0;
58
57
  uint32_t usable_index= MAX_KEY;
59
 
  Select_Lex   *select_lex= &session->getLex()->select_lex;
60
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
58
  Select_Lex   *select_lex= &session->lex->select_lex;
 
59
  Session::killed_state killed_status= Session::NOT_KILLED;
61
60
 
62
61
  if (session->openTablesLock(table_list))
63
62
  {
71
70
  session->set_proc_info("init");
72
71
  table->map=1;
73
72
 
74
 
  if (prepare_delete(session, table_list, &conds))
75
 
  {
76
 
    DRIZZLE_DELETE_DONE(1, 0);
77
 
    return true;
78
 
  }
 
73
  if (mysql_prepare_delete(session, table_list, &conds))
 
74
    goto err;
79
75
 
80
76
  /* check ORDER BY even if it can be ignored */
81
77
  if (order && order->elements)
84
80
    List<Item>   fields;
85
81
    List<Item>   all_fields;
86
82
 
 
83
    memset(&tables, 0, sizeof(tables));
87
84
    tables.table = table;
88
85
    tables.alias = table_list->alias;
89
86
 
90
87
      if (select_lex->setup_ref_array(session, order->elements) ||
91
88
          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->getLex()->select_lex);
96
 
        DRIZZLE_DELETE_DONE(1, 0);
97
 
 
98
 
        return true;
99
 
      }
 
89
                    fields, all_fields, (order_st*) order->first))
 
90
    {
 
91
      delete select;
 
92
      free_underlaid_joins(session, &session->lex->select_lex);
 
93
      goto err;
 
94
    }
100
95
  }
101
96
 
102
97
  const_cond= (!conds || conds->const_item());
103
98
 
104
 
  select_lex->no_error= session->getLex()->ignore;
 
99
  select_lex->no_error= session->lex->ignore;
105
100
 
106
101
  const_cond_result= const_cond && (!conds || conds->val_int());
107
102
  if (session->is_error())
163
158
  table->quick_keys.reset();            // Can't use 'only index'
164
159
  select= optimizer::make_select(table, 0, 0, conds, 0, &error);
165
160
  if (error)
166
 
  {
167
 
    DRIZZLE_DELETE_DONE(1, 0);
168
 
    return true;
169
 
  }
170
 
 
 
161
    goto err;
171
162
  if ((select && select->check_quick(session, false, limit)) || !limit)
172
163
  {
173
164
    delete select;
174
165
    free_underlaid_joins(session, select_lex);
175
166
    session->row_count_func= 0;
176
 
    if (session->is_error())
177
 
      return true;
178
167
    DRIZZLE_DELETE_DONE(0, 0);
179
168
    /**
180
169
     * Resetting the Diagnostic area to prevent
181
170
     * lp bug# 439719
182
171
     */
183
172
    session->main_da.reset_diagnostics_area();
184
 
    session->my_ok((ha_rows) session->rowCount());
 
173
    session->my_ok((ha_rows) session->row_count_func);
185
174
    /*
186
175
      We don't need to call reset_auto_increment in this case, because
187
176
      mysql_truncate always gives a NULL conds argument, hence we never
199
188
  if (order && order->elements)
200
189
  {
201
190
    uint32_t         length= 0;
202
 
    SortField  *sortorder;
 
191
    SORT_FIELD  *sortorder;
203
192
    ha_rows examined_rows;
204
193
 
205
194
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
206
 
      usable_index= optimizer::get_index_for_order(table, (Order*)(order->first), limit);
 
195
      usable_index= optimizer::get_index_for_order(table, (order_st*)(order->first), limit);
207
196
 
208
197
    if (usable_index == MAX_KEY)
209
198
    {
210
 
      FileSort filesort(*session);
211
199
      table->sort.io_cache= new internal::IO_CACHE;
212
200
 
213
201
 
214
 
      if (not (sortorder= make_unireg_sortorder((Order*) order->first, &length, NULL)) ||
215
 
          (table->sort.found_records = filesort.run(table, sortorder, length,
216
 
                                                    select, HA_POS_ERROR, 1,
217
 
                                                    examined_rows)) == HA_POS_ERROR)
 
202
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
 
203
                                             &length, NULL)) ||
 
204
          (table->sort.found_records = filesort(session, table, sortorder, length,
 
205
                                                select, HA_POS_ERROR, 1,
 
206
                                                &examined_rows))
 
207
          == HA_POS_ERROR)
218
208
      {
219
209
        delete select;
220
 
        free_underlaid_joins(session, &session->getLex()->select_lex);
221
 
 
222
 
        DRIZZLE_DELETE_DONE(1, 0);
223
 
        return true;
 
210
        free_underlaid_joins(session, &session->lex->select_lex);
 
211
        goto err;
224
212
      }
225
213
      /*
226
214
        Filesort has already found and selected the rows we want to delete,
237
225
  {
238
226
    delete select;
239
227
    free_underlaid_joins(session, select_lex);
240
 
    DRIZZLE_DELETE_DONE(1, 0);
241
 
    return true;
 
228
    goto err;
242
229
  }
243
230
 
244
231
  if (usable_index==MAX_KEY)
245
232
  {
246
 
    if ((error= info.init_read_record(session,table,select,1,1)))
247
 
    {
248
 
      table->print_error(error, MYF(0));
249
 
      delete select;
250
 
      free_underlaid_joins(session, select_lex);
251
 
      return true;
252
 
    }
 
233
    info.init_read_record(session,table,select,1,1);
253
234
  }
254
235
  else
255
236
  {
256
 
    if ((error= info.init_read_record_idx(session, table, 1, usable_index)))
257
 
    {
258
 
      table->print_error(error, MYF(0));
259
 
      delete select;
260
 
      free_underlaid_joins(session, select_lex);
261
 
      return true;
262
 
    }
 
237
    info.init_read_record_idx(session, table, 1, usable_index);
263
238
  }
264
239
 
265
240
  session->set_proc_info("updating");
266
241
 
267
242
  table->mark_columns_needed_for_delete();
268
243
 
269
 
  while (!(error=info.read_record(&info)) && !session->getKilled() &&
 
244
  while (!(error=info.read_record(&info)) && !session->killed &&
270
245
         ! session->is_error())
271
246
  {
272
247
    // session->is_error() is tested to disallow delete row on error
299
274
    else
300
275
      table->cursor->unlock_row();  // Row failed selection, release lock on it
301
276
  }
302
 
  killed_status= session->getKilled();
 
277
  killed_status= session->killed;
303
278
  if (killed_status != Session::NOT_KILLED || session->is_error())
304
279
    error= 1;                                   // Aborted
305
280
 
339
314
  free_underlaid_joins(session, select_lex);
340
315
 
341
316
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
342
 
  if (error < 0 || (session->getLex()->ignore && !session->is_fatal_error))
 
317
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
343
318
  {
344
319
    session->row_count_func= deleted;
345
320
    /**
347
322
     * lp bug# 439719
348
323
     */
349
324
    session->main_da.reset_diagnostics_area();    
350
 
    session->my_ok((ha_rows) session->rowCount());
 
325
    session->my_ok((ha_rows) session->row_count_func);
351
326
  }
352
327
  session->status_var.deleted_row_count+= deleted;
353
 
 
354
328
  return (error >= 0 || session->is_error());
 
329
 
 
330
err:
 
331
  DRIZZLE_DELETE_DONE(1, 0);
 
332
  return true;
355
333
}
356
334
 
357
335
 
359
337
  Prepare items in DELETE statement
360
338
 
361
339
  SYNOPSIS
362
 
    prepare_delete()
 
340
    mysql_prepare_delete()
363
341
    session                     - thread handler
364
342
    table_list          - global/local table list
365
343
    conds               - conditions
368
346
    false OK
369
347
    true  error
370
348
*/
371
 
int prepare_delete(Session *session, TableList *table_list, Item **conds)
 
349
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
372
350
{
373
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
351
  Select_Lex *select_lex= &session->lex->select_lex;
374
352
 
375
353
  List<Item> all_fields;
376
354
 
377
 
  session->getLex()->allow_sum_func= 0;
378
 
  if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
379
 
                                    &session->getLex()->select_lex.top_join_list,
 
355
  session->lex->allow_sum_func= 0;
 
356
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
357
                                    &session->lex->select_lex.top_join_list,
380
358
                                    table_list,
381
359
                                    &select_lex->leaf_tables, false) ||
382
360
      session->setup_conds(table_list, conds))
392
370
 
393
371
  if (select_lex->inner_refs_list.elements &&
394
372
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
395
 
    return(true);
 
373
    return(-1);
396
374
 
397
375
  return(false);
398
376
}
407
385
  This will work even if the .ISM and .ISD tables are destroyed
408
386
*/
409
387
 
410
 
bool truncate(Session& session, TableList *table_list)
 
388
bool mysql_truncate(Session& session, TableList *table_list)
411
389
{
412
390
  bool error;
413
391
  TransactionServices &transaction_services= TransactionServices::singleton();
415
393
  uint64_t save_options= session.options;
416
394
  table_list->lock_type= TL_WRITE;
417
395
  session.options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
418
 
  init_select(session.getLex());
419
 
  error= delete_query(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
 
396
  mysql_init_select(session.lex);
 
397
  error= mysql_delete(&session, table_list, (COND*) 0, (SQL_LIST*) 0,
420
398
                      HA_POS_ERROR, 0L, true);
421
399
  /*
422
400
    Safety, in case the engine ignored ha_enable_transaction(false)
423
401
    above. Also clears session->transaction.*.
424
402
  */
425
 
  error= transaction_services.autocommitOrRollback(session, error);
 
403
  error= transaction_services.autocommitOrRollback(&session, error);
426
404
  session.options= save_options;
427
405
 
428
406
  return error;