~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

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