~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Monty Taylor
  • Date: 2009-01-30 21:02:37 UTC
  • mto: (779.7.3 devel)
  • mto: This revision was merged to the branch mainline in revision 823.
  • Revision ID: mordred@inaugust.com-20090130210237-3n6ld8a9jc084jko
Commented out a test in subselect_sj - I think it might be a regression. Jay?

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
*/
21
21
#include <drizzled/server_includes.h>
22
22
#include <drizzled/sql_select.h>
23
 
#include <drizzled/drizzled_error_messages.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>
24
28
 
25
29
/**
26
30
  Implement DELETE SQL word.
30
34
  end of dispatch_command().
31
35
*/
32
36
 
33
 
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
 
37
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
34
38
                  SQL_LIST *order, ha_rows limit, uint64_t options,
35
39
                  bool reset_auto_increment)
36
40
{
37
41
  bool          will_batch;
38
42
  int           error, loc_error;
39
 
  TABLE         *table;
 
43
  Table         *table;
40
44
  SQL_SELECT    *select=0;
41
45
  READ_RECORD   info;
42
46
  bool          using_limit=limit != HA_POS_ERROR;
43
47
  bool          transactional_table, safe_update, const_cond;
44
48
  bool          const_cond_result;
45
49
  ha_rows       deleted= 0;
46
 
  uint usable_index= MAX_KEY;
47
 
  SELECT_LEX   *select_lex= &thd->lex->select_lex;
48
 
  THD::killed_state killed_status= THD::NOT_KILLED;
49
 
  
50
 
 
51
 
  if (open_and_lock_tables(thd, table_list))
52
 
    return(true);
53
 
  /* TODO look at this error */
54
 
  if (!(table= table_list->table))
55
 
  {
56
 
    my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
57
 
    return(true);
58
 
  }
59
 
  thd_proc_info(thd, "init");
 
50
  uint32_t usable_index= MAX_KEY;
 
51
  SELECT_LEX   *select_lex= &session->lex->select_lex;
 
52
  Session::killed_state killed_status= Session::NOT_KILLED;
 
53
 
 
54
 
 
55
  if (open_and_lock_tables(session, table_list))
 
56
    return(true);
 
57
 
 
58
  table= table_list->table;
 
59
  assert(table);
 
60
 
 
61
  session->set_proc_info("init");
60
62
  table->map=1;
61
63
 
62
 
  if (mysql_prepare_delete(thd, table_list, &conds))
 
64
  if (mysql_prepare_delete(session, table_list, &conds))
63
65
    goto err;
64
66
 
65
67
  /* check ORDER BY even if it can be ignored */
66
68
  if (order && order->elements)
67
69
  {
68
 
    TABLE_LIST   tables;
 
70
    TableList   tables;
69
71
    List<Item>   fields;
70
72
    List<Item>   all_fields;
71
73
 
73
75
    tables.table = table;
74
76
    tables.alias = table_list->alias;
75
77
 
76
 
      if (select_lex->setup_ref_array(thd, order->elements) ||
77
 
          setup_order(thd, select_lex->ref_pointer_array, &tables,
78
 
                    fields, all_fields, (ORDER*) order->first))
 
78
      if (select_lex->setup_ref_array(session, order->elements) ||
 
79
          setup_order(session, select_lex->ref_pointer_array, &tables,
 
80
                    fields, all_fields, (order_st*) order->first))
79
81
    {
80
82
      delete select;
81
 
      free_underlaid_joins(thd, &thd->lex->select_lex);
 
83
      free_underlaid_joins(session, &session->lex->select_lex);
82
84
      goto err;
83
85
    }
84
86
  }
85
87
 
86
88
  const_cond= (!conds || conds->const_item());
87
 
  safe_update=test(thd->options & OPTION_SAFE_UPDATES);
 
89
  safe_update=test(session->options & OPTION_SAFE_UPDATES);
88
90
  if (safe_update && const_cond)
89
91
  {
90
92
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
92
94
    goto err;
93
95
  }
94
96
 
95
 
  select_lex->no_error= thd->lex->ignore;
 
97
  select_lex->no_error= session->lex->ignore;
96
98
 
97
99
  const_cond_result= const_cond && (!conds || conds->val_int());
98
 
  if (thd->is_error())
 
100
  if (session->is_error())
99
101
  {
100
102
    /* Error evaluating val_int(). */
101
103
    return(true);
120
122
      - We should not be binlogging this statement row-based, and
121
123
      - there should be no delete triggers associated with the table.
122
124
  */
123
 
  if (!using_limit && const_cond_result &&
124
 
      !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
125
 
      (thd->lex->sql_command == SQLCOM_TRUNCATE ||
126
 
       (!thd->current_stmt_binlog_row_based)))
 
125
  if (!using_limit && const_cond_result)
127
126
  {
128
127
    /* Update the table->file->stats.records number */
129
128
    table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
145
144
  if (conds)
146
145
  {
147
146
    Item::cond_result result;
148
 
    conds= remove_eq_conds(thd, conds, &result);
 
147
    conds= remove_eq_conds(session, conds, &result);
149
148
    if (result == Item::COND_FALSE)             // Impossible where
150
149
      limit= 0;
151
150
  }
158
157
  select=make_select(table, 0, 0, conds, 0, &error);
159
158
  if (error)
160
159
    goto err;
161
 
  if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
 
160
  if ((select && select->check_quick(session, safe_update, limit)) || !limit)
162
161
  {
163
162
    delete select;
164
 
    free_underlaid_joins(thd, select_lex);
165
 
    thd->row_count_func= 0;
 
163
    free_underlaid_joins(session, select_lex);
 
164
    session->row_count_func= 0;
166
165
    DRIZZLE_DELETE_END();
167
 
    my_ok(thd, (ha_rows) thd->row_count_func);
 
166
    my_ok(session, (ha_rows) session->row_count_func);
168
167
    /*
169
168
      We don't need to call reset_auto_increment in this case, because
170
169
      mysql_truncate always gives a NULL conds argument, hence we never
176
175
  /* If running in safe sql mode, don't allow updates without keys */
177
176
  if (table->quick_keys.is_clear_all())
178
177
  {
179
 
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
178
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
180
179
    if (safe_update && !using_limit)
181
180
    {
182
181
      delete select;
183
 
      free_underlaid_joins(thd, select_lex);
 
182
      free_underlaid_joins(session, select_lex);
184
183
      my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
185
184
                 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
186
185
      goto err;
191
190
 
192
191
  if (order && order->elements)
193
192
  {
194
 
    uint         length= 0;
 
193
    uint32_t         length= 0;
195
194
    SORT_FIELD  *sortorder;
196
195
    ha_rows examined_rows;
197
 
    
 
196
 
198
197
    if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
199
 
      usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
 
198
      usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
200
199
 
201
200
    if (usable_index == MAX_KEY)
202
201
    {
203
 
      table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
204
 
                                                   MYF(MY_FAE | MY_ZEROFILL));
205
 
    
206
 
      if (!(sortorder= make_unireg_sortorder((ORDER*) order->first,
 
202
      table->sort.io_cache= new IO_CACHE;
 
203
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
 
204
 
 
205
 
 
206
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
207
207
                                             &length, NULL)) ||
208
 
          (table->sort.found_records = filesort(thd, table, sortorder, length,
 
208
          (table->sort.found_records = filesort(session, table, sortorder, length,
209
209
                                                select, HA_POS_ERROR, 1,
210
210
                                                &examined_rows))
211
211
          == HA_POS_ERROR)
212
212
      {
213
213
        delete select;
214
 
        free_underlaid_joins(thd, &thd->lex->select_lex);
 
214
        free_underlaid_joins(session, &session->lex->select_lex);
215
215
        goto err;
216
216
      }
217
217
      /*
219
219
        so we don't need the where clause
220
220
      */
221
221
      delete select;
222
 
      free_underlaid_joins(thd, select_lex);
 
222
      free_underlaid_joins(session, select_lex);
223
223
      select= 0;
224
224
    }
225
225
  }
228
228
  if (select && select->quick && select->quick->reset())
229
229
  {
230
230
    delete select;
231
 
    free_underlaid_joins(thd, select_lex);
 
231
    free_underlaid_joins(session, select_lex);
232
232
    goto err;
233
233
  }
234
234
  if (usable_index==MAX_KEY)
235
 
    init_read_record(&info,thd,table,select,1,1);
 
235
    init_read_record(&info,session,table,select,1,1);
236
236
  else
237
 
    init_read_record_idx(&info, thd, table, 1, usable_index);
 
237
    init_read_record_idx(&info, session, table, 1, usable_index);
238
238
 
239
 
  thd_proc_info(thd, "updating");
 
239
  session->set_proc_info("updating");
240
240
 
241
241
  will_batch= !table->file->start_bulk_delete();
242
242
 
243
243
 
244
244
  table->mark_columns_needed_for_delete();
245
245
 
246
 
  while (!(error=info.read_record(&info)) && !thd->killed &&
247
 
         ! thd->is_error())
 
246
  while (!(error=info.read_record(&info)) && !session->killed &&
 
247
         ! session->is_error())
248
248
  {
249
 
    // thd->is_error() is tested to disallow delete row on error
250
 
    if (!(select && select->skip_record())&& ! thd->is_error() )
 
249
    // session->is_error() is tested to disallow delete row on error
 
250
    if (!(select && select->skip_record())&& ! session->is_error() )
251
251
    {
252
252
      if (!(error= table->file->ha_delete_row(table->record[0])))
253
253
      {
276
276
    else
277
277
      table->file->unlock_row();  // Row failed selection, release lock on it
278
278
  }
279
 
  killed_status= thd->killed;
280
 
  if (killed_status != THD::NOT_KILLED || thd->is_error())
 
279
  killed_status= session->killed;
 
280
  if (killed_status != Session::NOT_KILLED || session->is_error())
281
281
    error= 1;                                   // Aborted
282
282
  if (will_batch && (loc_error= table->file->end_bulk_delete()))
283
283
  {
285
285
      table->file->print_error(loc_error,MYF(0));
286
286
    error=1;
287
287
  }
288
 
  thd_proc_info(thd, "end");
 
288
  session->set_proc_info("end");
289
289
  end_read_record(&info);
290
290
  if (options & OPTION_QUICK)
291
291
    (void) table->file->extra(HA_EXTRA_NORMAL);
311
311
  transactional_table= table->file->has_transactions();
312
312
 
313
313
  if (!transactional_table && deleted > 0)
314
 
    thd->transaction.stmt.modified_non_trans_table= true;
315
 
  
 
314
    session->transaction.stmt.modified_non_trans_table= true;
 
315
 
316
316
  /* See similar binlogging code in sql_update.cc, for comments */
317
 
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
 
317
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
318
318
  {
319
 
    if (mysql_bin_log.is_open())
320
 
    {
321
 
      if (error < 0)
322
 
        thd->clear_error();
323
 
      /*
324
 
        [binlog]: If 'handler::delete_all_rows()' was called and the
325
 
        storage engine does not inject the rows itself, we replicate
326
 
        statement-based; otherwise, 'ha_delete_row()' was used to
327
 
        delete specific rows which we might log row-based.
328
 
      */
329
 
      int log_result= thd->binlog_query(THD::ROW_QUERY_TYPE,
330
 
                                        thd->query, thd->query_length,
331
 
                                        transactional_table, false, killed_status);
332
 
 
333
 
      if (log_result && transactional_table)
334
 
      {
335
 
        error=1;
336
 
      }
337
 
    }
338
 
    if (thd->transaction.stmt.modified_non_trans_table)
339
 
      thd->transaction.all.modified_non_trans_table= true;
 
319
    if (session->transaction.stmt.modified_non_trans_table)
 
320
      session->transaction.all.modified_non_trans_table= true;
340
321
  }
341
 
  assert(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
342
 
  free_underlaid_joins(thd, select_lex);
 
322
  assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
 
323
  free_underlaid_joins(session, select_lex);
343
324
 
344
325
  DRIZZLE_DELETE_END();
345
 
  if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
 
326
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
346
327
  {
347
 
    thd->row_count_func= deleted;
348
 
    my_ok(thd, (ha_rows) thd->row_count_func);
 
328
    session->row_count_func= deleted;
 
329
    my_ok(session, (ha_rows) session->row_count_func);
349
330
  }
350
 
  return(error >= 0 || thd->is_error());
 
331
  return(error >= 0 || session->is_error());
351
332
 
352
333
err:
353
334
  DRIZZLE_DELETE_END();
360
341
 
361
342
  SYNOPSIS
362
343
    mysql_prepare_delete()
363
 
    thd                 - thread handler
 
344
    session                     - thread handler
364
345
    table_list          - global/local table list
365
346
    conds               - conditions
366
347
 
368
349
    false OK
369
350
    true  error
370
351
*/
371
 
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
 
352
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
372
353
{
373
 
  SELECT_LEX *select_lex= &thd->lex->select_lex;
374
 
  
 
354
  SELECT_LEX *select_lex= &session->lex->select_lex;
 
355
 
375
356
  List<Item> all_fields;
376
357
 
377
 
  /*
378
 
    Statement-based replication of DELETE ... LIMIT is not safe as order of
379
 
    rows is not defined, so in mixed mode we go to row-based.
380
 
 
381
 
    Note that we may consider a statement as safe if ORDER BY primary_key
382
 
    is present. However it may confuse users to see very similiar statements
383
 
    replicated differently.
384
 
  */
385
 
  if (thd->lex->current_select->select_limit)
386
 
  {
387
 
    thd->lex->set_stmt_unsafe();
388
 
    thd->set_current_stmt_binlog_row_based_if_mixed();
389
 
  }
390
 
  thd->lex->allow_sum_func= 0;
391
 
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
392
 
                                    &thd->lex->select_lex.top_join_list,
393
 
                                    table_list, 
 
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,
 
361
                                    table_list,
394
362
                                    &select_lex->leaf_tables, false) ||
395
 
      setup_conds(thd, table_list, select_lex->leaf_tables, conds))
 
363
      setup_conds(session, table_list, select_lex->leaf_tables, conds))
396
364
    return(true);
397
365
  {
398
 
    TABLE_LIST *duplicate;
399
 
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
 
366
    TableList *duplicate;
 
367
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
400
368
    {
401
369
      update_non_unique_table_error(table_list, "DELETE", duplicate);
402
370
      return(true);
404
372
  }
405
373
 
406
374
  if (select_lex->inner_refs_list.elements &&
407
 
    fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
 
375
    fix_inner_refs(session, all_fields, select_lex, select_lex->ref_pointer_array))
408
376
    return(-1);
409
377
 
410
378
  return(false);
412
380
 
413
381
 
414
382
/***************************************************************************
415
 
  Delete multiple tables from join 
 
383
  Delete multiple tables from join
416
384
***************************************************************************/
417
385
 
418
 
#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
 
386
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
419
387
 
420
388
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
421
389
{
422
390
  handler *file= (handler*)arg;
423
 
  return file->cmp_ref((const uchar*)a, (const uchar*)b);
 
391
  return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
424
392
}
425
393
 
426
394
/*
428
396
 
429
397
  SYNOPSIS
430
398
    mysql_multi_delete_prepare()
431
 
    thd         thread handler
 
399
    session         thread handler
432
400
 
433
401
  RETURN
434
402
    false OK
435
403
    true  Error
436
404
*/
437
405
 
438
 
int mysql_multi_delete_prepare(THD *thd)
 
406
int mysql_multi_delete_prepare(Session *session)
439
407
{
440
 
  LEX *lex= thd->lex;
441
 
  TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
442
 
  TABLE_LIST *target_tbl;
443
 
  
 
408
  LEX *lex= session->lex;
 
409
  TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
 
410
  TableList *target_tbl;
 
411
 
444
412
 
445
413
  /*
446
414
    setup_tables() need for VIEWs. JOIN::prepare() will not do it second
448
416
 
449
417
    lex->query_tables also point on local list of DELETE SELECT_LEX
450
418
  */
451
 
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
452
 
                                    &thd->lex->select_lex.top_join_list,
 
419
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
420
                                    &session->lex->select_lex.top_join_list,
453
421
                                    lex->query_tables,
454
422
                                    &lex->select_lex.leaf_tables, false))
455
423
    return(true);
461
429
  */
462
430
  lex->select_lex.exclude_from_table_unique_test= true;
463
431
  /* Fix tables-to-be-deleted-from list to point at opened tables */
464
 
  for (target_tbl= (TABLE_LIST*) aux_tables;
 
432
  for (target_tbl= (TableList*) aux_tables;
465
433
       target_tbl;
466
434
       target_tbl= target_tbl->next_local)
467
435
  {
468
 
    if (!(target_tbl->table= target_tbl->correspondent_table->table))
469
 
    {
470
 
      assert(target_tbl->correspondent_table->merge_underlying_list &&
471
 
                  target_tbl->correspondent_table->merge_underlying_list->
472
 
                  next_local);
473
 
      my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
474
 
      return(true);
475
 
    }
 
436
    target_tbl->table= target_tbl->correspondent_table->table;
 
437
    assert(target_tbl->table);
476
438
 
477
439
    /*
478
440
      Check that table from which we delete is not used somewhere
479
441
      inside subqueries/view.
480
442
    */
481
443
    {
482
 
      TABLE_LIST *duplicate;
483
 
      if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
 
444
      TableList *duplicate;
 
445
      if ((duplicate= unique_table(session, target_tbl->correspondent_table,
484
446
                                   lex->query_tables, 0)))
485
447
      {
486
448
        update_non_unique_table_error(target_tbl->correspondent_table,
493
455
}
494
456
 
495
457
 
496
 
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
 
458
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
497
459
  : delete_tables(dt), deleted(0), found(0),
498
460
    num_of_tables(num_of_tables_arg), error(0),
499
461
    do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
503
465
 
504
466
 
505
467
int
506
 
multi_delete::prepare(List<Item> &values __attribute__((unused)),
507
 
                      SELECT_LEX_UNIT *u)
 
468
multi_delete::prepare(List<Item> &, SELECT_LEX_UNIT *u)
508
469
{
509
 
  
 
470
 
510
471
  unit= u;
511
472
  do_delete= 1;
512
 
  thd_proc_info(thd, "deleting from main table");
 
473
  session->set_proc_info("deleting from main table");
513
474
  return(0);
514
475
}
515
476
 
517
478
bool
518
479
multi_delete::initialize_tables(JOIN *join)
519
480
{
520
 
  TABLE_LIST *walk;
 
481
  TableList *walk;
521
482
  Unique **tempfiles_ptr;
522
 
  
523
 
 
524
 
  if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
 
483
 
 
484
 
 
485
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
525
486
    return(1);
526
487
 
527
488
  table_map tables_to_delete_from=0;
537
498
    if (tab->table->map & tables_to_delete_from)
538
499
    {
539
500
      /* We are going to delete from this table */
540
 
      TABLE *tbl=walk->table=tab->table;
 
501
      Table *tbl=walk->table=tab->table;
541
502
      walk= walk->next_local;
542
503
      /* Don't use KEYREAD optimization on this table */
543
504
      tbl->no_keyread=1;
571
532
  }
572
533
  for (;walk ;walk= walk->next_local)
573
534
  {
574
 
    TABLE *table=walk->table;
 
535
    Table *table=walk->table;
575
536
    *tempfiles_ptr++= new Unique (refpos_order_cmp,
576
537
                                  (void *) table->file,
577
538
                                  table->file->ref_length,
578
539
                                  MEM_STRIP_BUF_SIZE);
579
540
  }
580
 
  return(thd->is_fatal_error != 0);
 
541
  return(session->is_fatal_error != 0);
581
542
}
582
543
 
583
544
 
587
548
       table_being_deleted;
588
549
       table_being_deleted= table_being_deleted->next_local)
589
550
  {
590
 
    TABLE *table= table_being_deleted->table;
 
551
    Table *table= table_being_deleted->table;
591
552
    table->no_keyread=0;
592
553
  }
593
554
 
594
 
  for (uint counter= 0; counter < num_of_tables; counter++)
 
555
  for (uint32_t counter= 0; counter < num_of_tables; counter++)
595
556
  {
596
557
    if (tempfiles[counter])
597
558
      delete tempfiles[counter];
599
560
}
600
561
 
601
562
 
602
 
bool multi_delete::send_data(List<Item> &values __attribute__((unused)))
 
563
bool multi_delete::send_data(List<Item> &)
603
564
{
604
565
  int secure_counter= delete_while_scanning ? -1 : 0;
605
 
  TABLE_LIST *del_table;
606
 
  
 
566
  TableList *del_table;
 
567
 
607
568
 
608
569
  for (del_table= delete_tables;
609
570
       del_table;
610
571
       del_table= del_table->next_local, secure_counter++)
611
572
  {
612
 
    TABLE *table= del_table->table;
 
573
    Table *table= del_table->table;
613
574
 
614
575
    /* Check if we are using outer join and we didn't find the row */
615
576
    if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
627
588
      {
628
589
        deleted++;
629
590
        if (!table->file->has_transactions())
630
 
          thd->transaction.stmt.modified_non_trans_table= true;
 
591
          session->transaction.stmt.modified_non_trans_table= true;
631
592
      }
632
593
      else
633
594
      {
649
610
}
650
611
 
651
612
 
652
 
void multi_delete::send_error(uint errcode,const char *err)
 
613
void multi_delete::send_error(uint32_t errcode,const char *err)
653
614
{
654
 
  
 
615
 
655
616
 
656
617
  /* First send error what ever it is ... */
657
618
  my_message(errcode, err, MYF(0));
662
623
 
663
624
void multi_delete::abort()
664
625
{
665
 
  
 
626
 
666
627
 
667
628
  /* the error was handled or nothing deleted and no side effects return */
668
629
  if (error_handled ||
669
 
      (!thd->transaction.stmt.modified_non_trans_table && !deleted))
 
630
      (!session->transaction.stmt.modified_non_trans_table && !deleted))
670
631
    return;
671
632
 
672
633
  /*
688
649
    assert(error_handled);
689
650
    return;
690
651
  }
691
 
  
692
 
  if (thd->transaction.stmt.modified_non_trans_table)
 
652
 
 
653
  if (session->transaction.stmt.modified_non_trans_table)
693
654
  {
694
 
    /* 
695
 
       there is only side effects; to binlog with the error
696
 
    */
697
 
    if (mysql_bin_log.is_open())
698
 
    {
699
 
      thd->binlog_query(THD::ROW_QUERY_TYPE,
700
 
                        thd->query, thd->query_length,
701
 
                        transactional_tables, false);
702
 
    }
703
 
    thd->transaction.all.modified_non_trans_table= true;
 
655
    session->transaction.all.modified_non_trans_table= true;
704
656
  }
705
657
  return;
706
658
}
718
670
{
719
671
  int local_error= 0, counter= 0, tmp_error;
720
672
  bool will_batch;
721
 
  
 
673
 
722
674
  assert(do_delete);
723
675
 
724
676
  do_delete= 0;                                 // Mark called
727
679
 
728
680
  table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
729
681
                        delete_tables);
730
 
 
 
682
 
731
683
  for (; table_being_deleted;
732
684
       table_being_deleted= table_being_deleted->next_local, counter++)
733
 
  { 
 
685
  {
734
686
    ha_rows last_deleted= deleted;
735
 
    TABLE *table = table_being_deleted->table;
 
687
    Table *table = table_being_deleted->table;
736
688
    if (tempfiles[counter]->get(table))
737
689
    {
738
690
      local_error=1;
740
692
    }
741
693
 
742
694
    READ_RECORD info;
743
 
    init_read_record(&info,thd,table,NULL,0,1);
 
695
    init_read_record(&info,session,table,NULL,0,1);
744
696
    /*
745
697
      Ignore any rows not found in reference tables as they may already have
746
698
      been deleted by foreign key handling
747
699
    */
748
700
    info.ignore_not_found_rows= 1;
749
701
    will_batch= !table->file->start_bulk_delete();
750
 
    while (!(local_error=info.read_record(&info)) && !thd->killed)
 
702
    while (!(local_error=info.read_record(&info)) && !session->killed)
751
703
    {
752
704
      if ((local_error=table->file->ha_delete_row(table->record[0])))
753
705
      {
765
717
      }
766
718
    }
767
719
    if (last_deleted != deleted && !table->file->has_transactions())
768
 
      thd->transaction.stmt.modified_non_trans_table= true;
 
720
      session->transaction.stmt.modified_non_trans_table= true;
769
721
    end_read_record(&info);
770
 
    if (thd->killed && !local_error)
 
722
    if (session->killed && !local_error)
771
723
      local_error= 1;
772
724
    if (local_error == -1)                              // End of file
773
725
      local_error = 0;
785
737
 
786
738
bool multi_delete::send_eof()
787
739
{
788
 
  THD::killed_state killed_status= THD::NOT_KILLED;
789
 
  thd_proc_info(thd, "deleting from reference tables");
 
740
  Session::killed_state killed_status= Session::NOT_KILLED;
 
741
  session->set_proc_info("deleting from reference tables");
790
742
 
791
743
  /* Does deletes for the last n - 1 tables, returns 0 if ok */
792
744
  int local_error= do_deletes();                // returns 0 if success
793
745
 
794
746
  /* compute a total error to know if something failed */
795
747
  local_error= local_error || error;
796
 
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
 
748
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
797
749
  /* reset used flags */
798
 
  thd_proc_info(thd, "end");
 
750
  session->set_proc_info("end");
799
751
 
800
 
  if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
 
752
  if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
801
753
  {
802
 
    if (mysql_bin_log.is_open())
803
 
    {
804
 
      if (local_error == 0)
805
 
        thd->clear_error();
806
 
      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
807
 
                            thd->query, thd->query_length,
808
 
                            transactional_tables, false, killed_status) &&
809
 
          !normal_tables)
810
 
      {
811
 
        local_error=1;  // Log write failed: roll back the SQL statement
812
 
      }
813
 
    }
814
 
    if (thd->transaction.stmt.modified_non_trans_table)
815
 
      thd->transaction.all.modified_non_trans_table= true;
 
754
    if (session->transaction.stmt.modified_non_trans_table)
 
755
      session->transaction.all.modified_non_trans_table= true;
816
756
  }
817
757
  if (local_error != 0)
818
758
    error_handled= true; // to force early leave from ::send_error()
819
759
 
820
760
  if (!local_error)
821
761
  {
822
 
    thd->row_count_func= deleted;
823
 
    ::my_ok(thd, (ha_rows) thd->row_count_func);
 
762
    session->row_count_func= deleted;
 
763
    ::my_ok(session, (ha_rows) session->row_count_func);
824
764
  }
825
765
  return 0;
826
766
}
827
767
 
828
768
 
829
769
/***************************************************************************
830
 
  TRUNCATE TABLE
 
770
  TRUNCATE Table
831
771
****************************************************************************/
832
772
 
833
773
/*
842
782
  - If we want to have a name lock on the table on exit without errors.
843
783
*/
844
784
 
845
 
bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
 
785
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
846
786
{
847
787
  HA_CREATE_INFO create_info;
848
788
  char path[FN_REFLEN];
849
 
  TABLE *table;
 
789
  Table *table;
850
790
  bool error;
851
 
  uint path_length;
852
 
  
 
791
  uint32_t path_length;
 
792
 
853
793
 
854
794
  memset(&create_info, 0, sizeof(create_info));
855
795
  /* If it is a temporary table, close and regenerate it */
856
 
  if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
 
796
  if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
857
797
  {
858
798
    handlerton *table_type= table->s->db_type();
859
799
    TABLE_SHARE *share= table->s;
860
 
    bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
861
800
 
862
 
    if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
 
801
    if (!ha_check_storage_engine_flag(table_type, HTON_BIT_CAN_RECREATE))
863
802
      goto trunc_by_del;
864
803
 
865
804
    table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
866
 
    
867
 
    close_temporary_table(thd, table, 0, 0);    // Don't free share
868
 
    ha_create_table(thd, share->normalized_path.str,
 
805
 
 
806
    close_temporary_table(session, table, 0, 0);    // Don't free share
 
807
    ha_create_table(session, share->normalized_path.str,
869
808
                    share->db.str, share->table_name.str, &create_info, 1);
870
809
    // We don't need to call invalidate() because this table is not in cache
871
 
    if ((error= (int) !(open_temporary_table(thd, share->path.str,
 
810
    if ((error= (int) !(open_temporary_table(session, share->path.str,
872
811
                                             share->db.str,
873
812
                                             share->table_name.str, 1,
874
813
                                             OTM_OPEN))))
875
 
      (void) rm_temporary_table(table_type, path, frm_only);
 
814
      (void) rm_temporary_table(table_type, path);
876
815
    free_table_share(share);
877
 
    my_free((char*) table,MYF(0));
 
816
    free((char*) table);
878
817
    /*
879
818
      If we return here we will not have logged the truncation to the bin log
880
819
      and we will not my_ok() to the client.
886
825
                                    table_list->table_name, reg_ext, 0);
887
826
 
888
827
  if (!dont_send_ok)
889
 
  {
890
 
    enum legacy_db_type table_type;
891
 
    mysql_frm_type(thd, path, &table_type);
892
 
    if (table_type == DB_TYPE_UNKNOWN)
893
 
    {
894
 
      my_error(ER_NO_SUCH_TABLE, MYF(0),
895
 
               table_list->db, table_list->table_name);
896
 
      return(true);
897
 
    }
898
 
 
899
 
    if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type),
900
 
                                      HTON_CAN_RECREATE))
901
 
      goto trunc_by_del;
902
 
 
903
 
    if (lock_and_wait_for_table_name(thd, table_list))
904
 
      return(true);
905
 
  }
 
828
    goto trunc_by_del;
906
829
 
907
830
  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
908
831
  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
909
832
  // '\0';
910
833
  path[path_length - reg_ext_length] = 0;
911
 
  VOID(pthread_mutex_lock(&LOCK_open));
912
 
  error= ha_create_table(thd, path, table_list->db, table_list->table_name,
 
834
  pthread_mutex_lock(&LOCK_open);
 
835
  error= ha_create_table(session, path, table_list->db, table_list->table_name,
913
836
                         &create_info, 1);
914
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
837
  pthread_mutex_unlock(&LOCK_open);
915
838
 
916
839
end:
917
840
  if (!dont_send_ok)
922
845
        TRUNCATE must always be statement-based binlogged (not row-based) so
923
846
        we don't test current_stmt_binlog_row_based.
924
847
      */
925
 
      write_bin_log(thd, true, thd->query, thd->query_length);
926
 
      my_ok(thd);               // This should return record count
 
848
      write_bin_log(session, true, session->query, session->query_length);
 
849
      my_ok(session);           // This should return record count
927
850
    }
928
 
    VOID(pthread_mutex_lock(&LOCK_open));
929
 
    unlock_table_name(thd, table_list);
930
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
851
    pthread_mutex_lock(&LOCK_open);
 
852
    unlock_table_name(session, table_list);
 
853
    pthread_mutex_unlock(&LOCK_open);
931
854
  }
932
855
  else if (error)
933
856
  {
934
 
    VOID(pthread_mutex_lock(&LOCK_open));
935
 
    unlock_table_name(thd, table_list);
936
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
857
    pthread_mutex_lock(&LOCK_open);
 
858
    unlock_table_name(session, table_list);
 
859
    pthread_mutex_unlock(&LOCK_open);
937
860
  }
938
861
  return(error);
939
862
 
940
863
trunc_by_del:
941
864
  /* Probably InnoDB table */
942
 
  uint64_t save_options= thd->options;
 
865
  uint64_t save_options= session->options;
943
866
  table_list->lock_type= TL_WRITE;
944
 
  thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
945
 
  ha_enable_transaction(thd, false);
946
 
  mysql_init_select(thd->lex);
947
 
  bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
948
 
  thd->clear_current_stmt_binlog_row_based();
949
 
  error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
950
 
                      HA_POS_ERROR, 0LL, true);
951
 
  ha_enable_transaction(thd, true);
 
867
  session->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
 
868
  ha_enable_transaction(session, false);
 
869
  mysql_init_select(session->lex);
 
870
  error= mysql_delete(session, table_list, (COND*) 0, (SQL_LIST*) 0,
 
871
                      HA_POS_ERROR, 0L, true);
 
872
  ha_enable_transaction(session, true);
952
873
  /*
953
874
    Safety, in case the engine ignored ha_enable_transaction(false)
954
 
    above. Also clears thd->transaction.*.
 
875
    above. Also clears session->transaction.*.
955
876
  */
956
 
  error= ha_autocommit_or_rollback(thd, error);
957
 
  ha_commit(thd);
958
 
  thd->options= save_options;
959
 
  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
877
  error= ha_autocommit_or_rollback(session, error);
 
878
  ha_commit(session);
 
879
  session->options= save_options;
960
880
  return(error);
961
881
}