~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Monty Taylor
  • Date: 2009-03-04 02:16:28 UTC
  • mto: (917.1.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 912.
  • Revision ID: mordred@inaugust.com-20090304021628-rfq0b16uoi09g8tx
Fix to make VPATH builds work again.

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, TableList *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
{
44
48
  bool          const_cond_result;
45
49
  ha_rows       deleted= 0;
46
50
  uint32_t 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");
 
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 */
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
      if (select_lex->setup_ref_array(session, order->elements) ||
 
79
          setup_order(session, select_lex->ref_pointer_array, &tables,
78
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
 
      (thd->lex->sql_command == SQLCOM_TRUNCATE ||
125
 
       (!thd->current_stmt_binlog_row_based)))
 
125
  if (!using_limit && const_cond_result)
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(thd, conds, &result);
 
147
    conds= remove_eq_conds(session, 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(thd, safe_update, limit)) || !limit)
 
160
  if ((select && select->check_quick(session, safe_update, limit)) || !limit)
161
161
  {
162
162
    delete select;
163
 
    free_underlaid_joins(thd, select_lex);
164
 
    thd->row_count_func= 0;
 
163
    free_underlaid_joins(session, select_lex);
 
164
    session->row_count_func= 0;
165
165
    DRIZZLE_DELETE_END();
166
 
    my_ok(thd, (ha_rows) thd->row_count_func);
 
166
    session->my_ok((ha_rows) session->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
 
    thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
 
178
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
179
179
    if (safe_update && !using_limit)
180
180
    {
181
181
      delete select;
182
 
      free_underlaid_joins(thd, select_lex);
 
182
      free_underlaid_joins(session, 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= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
203
 
                                                   MYF(MY_FAE | MY_ZEROFILL));
204
 
    
 
202
      table->sort.io_cache= new IO_CACHE;
 
203
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
 
204
 
 
205
 
205
206
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
206
207
                                             &length, NULL)) ||
207
 
          (table->sort.found_records = filesort(thd, table, sortorder, length,
 
208
          (table->sort.found_records = filesort(session, table, sortorder, length,
208
209
                                                select, HA_POS_ERROR, 1,
209
210
                                                &examined_rows))
210
211
          == HA_POS_ERROR)
211
212
      {
212
213
        delete select;
213
 
        free_underlaid_joins(thd, &thd->lex->select_lex);
 
214
        free_underlaid_joins(session, &session->lex->select_lex);
214
215
        goto err;
215
216
      }
216
217
      /*
218
219
        so we don't need the where clause
219
220
      */
220
221
      delete select;
221
 
      free_underlaid_joins(thd, select_lex);
 
222
      free_underlaid_joins(session, select_lex);
222
223
      select= 0;
223
224
    }
224
225
  }
227
228
  if (select && select->quick && select->quick->reset())
228
229
  {
229
230
    delete select;
230
 
    free_underlaid_joins(thd, select_lex);
 
231
    free_underlaid_joins(session, select_lex);
231
232
    goto err;
232
233
  }
233
234
  if (usable_index==MAX_KEY)
234
 
    init_read_record(&info,thd,table,select,1,1);
 
235
    init_read_record(&info,session,table,select,1,1);
235
236
  else
236
 
    init_read_record_idx(&info, thd, table, 1, usable_index);
 
237
    init_read_record_idx(&info, session, table, 1, usable_index);
237
238
 
238
 
  thd_proc_info(thd, "updating");
 
239
  session->set_proc_info("updating");
239
240
 
240
241
  will_batch= !table->file->start_bulk_delete();
241
242
 
242
243
 
243
244
  table->mark_columns_needed_for_delete();
244
245
 
245
 
  while (!(error=info.read_record(&info)) && !thd->killed &&
246
 
         ! thd->is_error())
 
246
  while (!(error=info.read_record(&info)) && !session->killed &&
 
247
         ! session->is_error())
247
248
  {
248
 
    // thd->is_error() is tested to disallow delete row on error
249
 
    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() )
250
251
    {
251
252
      if (!(error= table->file->ha_delete_row(table->record[0])))
252
253
      {
275
276
    else
276
277
      table->file->unlock_row();  // Row failed selection, release lock on it
277
278
  }
278
 
  killed_status= thd->killed;
279
 
  if (killed_status != THD::NOT_KILLED || thd->is_error())
 
279
  killed_status= session->killed;
 
280
  if (killed_status != Session::NOT_KILLED || session->is_error())
280
281
    error= 1;                                   // Aborted
281
282
  if (will_batch && (loc_error= table->file->end_bulk_delete()))
282
283
  {
284
285
      table->file->print_error(loc_error,MYF(0));
285
286
    error=1;
286
287
  }
287
 
  thd_proc_info(thd, "end");
 
288
  session->set_proc_info("end");
288
289
  end_read_record(&info);
289
290
  if (options & OPTION_QUICK)
290
291
    (void) table->file->extra(HA_EXTRA_NORMAL);
310
311
  transactional_table= table->file->has_transactions();
311
312
 
312
313
  if (!transactional_table && deleted > 0)
313
 
    thd->transaction.stmt.modified_non_trans_table= true;
314
 
  
 
314
    session->transaction.stmt.modified_non_trans_table= true;
 
315
 
315
316
  /* See similar binlogging code in sql_update.cc, for comments */
316
 
  if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
 
317
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
317
318
  {
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;
 
319
    if (session->transaction.stmt.modified_non_trans_table)
 
320
      session->transaction.all.modified_non_trans_table= true;
339
321
  }
340
 
  assert(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
341
 
  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);
342
324
 
343
325
  DRIZZLE_DELETE_END();
344
 
  if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
 
326
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
345
327
  {
346
 
    thd->row_count_func= deleted;
347
 
    my_ok(thd, (ha_rows) thd->row_count_func);
 
328
    session->row_count_func= deleted;
 
329
    session->my_ok((ha_rows) session->row_count_func);
348
330
  }
349
 
  return(error >= 0 || thd->is_error());
 
331
  return(error >= 0 || session->is_error());
350
332
 
351
333
err:
352
334
  DRIZZLE_DELETE_END();
359
341
 
360
342
  SYNOPSIS
361
343
    mysql_prepare_delete()
362
 
    thd                 - thread handler
 
344
    session                     - thread handler
363
345
    table_list          - global/local table list
364
346
    conds               - conditions
365
347
 
367
349
    false OK
368
350
    true  error
369
351
*/
370
 
int mysql_prepare_delete(THD *thd, TableList *table_list, Item **conds)
 
352
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
371
353
{
372
 
  SELECT_LEX *select_lex= &thd->lex->select_lex;
373
 
  
 
354
  Select_Lex *select_lex= &session->lex->select_lex;
 
355
 
374
356
  List<Item> all_fields;
375
357
 
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, 
 
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,
393
362
                                    &select_lex->leaf_tables, false) ||
394
 
      setup_conds(thd, table_list, select_lex->leaf_tables, conds))
 
363
      setup_conds(session, table_list, select_lex->leaf_tables, conds))
395
364
    return(true);
396
365
  {
397
366
    TableList *duplicate;
398
 
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
 
367
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
399
368
    {
400
369
      update_non_unique_table_error(table_list, "DELETE", duplicate);
401
370
      return(true);
403
372
  }
404
373
 
405
374
  if (select_lex->inner_refs_list.elements &&
406
 
    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))
407
376
    return(-1);
408
377
 
409
378
  return(false);
411
380
 
412
381
 
413
382
/***************************************************************************
414
 
  Delete multiple tables from join 
 
383
  Delete multiple tables from join
415
384
***************************************************************************/
416
385
 
417
 
#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
 
386
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
418
387
 
419
388
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
420
389
{
427
396
 
428
397
  SYNOPSIS
429
398
    mysql_multi_delete_prepare()
430
 
    thd         thread handler
 
399
    session         thread handler
431
400
 
432
401
  RETURN
433
402
    false OK
434
403
    true  Error
435
404
*/
436
405
 
437
 
int mysql_multi_delete_prepare(THD *thd)
 
406
int mysql_multi_delete_prepare(Session *session)
438
407
{
439
 
  LEX *lex= thd->lex;
 
408
  LEX *lex= session->lex;
440
409
  TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
441
410
  TableList *target_tbl;
442
 
  
 
411
 
443
412
 
444
413
  /*
445
414
    setup_tables() need for VIEWs. JOIN::prepare() will not do it second
446
415
    time.
447
416
 
448
 
    lex->query_tables also point on local list of DELETE SELECT_LEX
 
417
    lex->query_tables also point on local list of DELETE Select_Lex
449
418
  */
450
 
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
451
 
                                    &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,
452
421
                                    lex->query_tables,
453
422
                                    &lex->select_lex.leaf_tables, false))
454
423
    return(true);
464
433
       target_tbl;
465
434
       target_tbl= target_tbl->next_local)
466
435
  {
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
 
    }
 
436
    target_tbl->table= target_tbl->correspondent_table->table;
 
437
    assert(target_tbl->table);
475
438
 
476
439
    /*
477
440
      Check that table from which we delete is not used somewhere
479
442
    */
480
443
    {
481
444
      TableList *duplicate;
482
 
      if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
 
445
      if ((duplicate= unique_table(session, target_tbl->correspondent_table,
483
446
                                   lex->query_tables, 0)))
484
447
      {
485
448
        update_non_unique_table_error(target_tbl->correspondent_table,
502
465
 
503
466
 
504
467
int
505
 
multi_delete::prepare(List<Item> &values __attribute__((unused)),
506
 
                      SELECT_LEX_UNIT *u)
 
468
multi_delete::prepare(List<Item> &, Select_Lex_Unit *u)
507
469
{
508
 
  
 
470
 
509
471
  unit= u;
510
472
  do_delete= 1;
511
 
  thd_proc_info(thd, "deleting from main table");
 
473
  session->set_proc_info("deleting from main table");
512
474
  return(0);
513
475
}
514
476
 
518
480
{
519
481
  TableList *walk;
520
482
  Unique **tempfiles_ptr;
521
 
  
522
 
 
523
 
  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))
524
486
    return(1);
525
487
 
526
488
  table_map tables_to_delete_from=0;
576
538
                                  table->file->ref_length,
577
539
                                  MEM_STRIP_BUF_SIZE);
578
540
  }
579
 
  return(thd->is_fatal_error != 0);
 
541
  return(session->is_fatal_error != 0);
580
542
}
581
543
 
582
544
 
598
560
}
599
561
 
600
562
 
601
 
bool multi_delete::send_data(List<Item> &values __attribute__((unused)))
 
563
bool multi_delete::send_data(List<Item> &)
602
564
{
603
565
  int secure_counter= delete_while_scanning ? -1 : 0;
604
566
  TableList *del_table;
605
 
  
 
567
 
606
568
 
607
569
  for (del_table= delete_tables;
608
570
       del_table;
626
588
      {
627
589
        deleted++;
628
590
        if (!table->file->has_transactions())
629
 
          thd->transaction.stmt.modified_non_trans_table= true;
 
591
          session->transaction.stmt.modified_non_trans_table= true;
630
592
      }
631
593
      else
632
594
      {
650
612
 
651
613
void multi_delete::send_error(uint32_t errcode,const char *err)
652
614
{
653
 
  
 
615
 
654
616
 
655
617
  /* First send error what ever it is ... */
656
618
  my_message(errcode, err, MYF(0));
661
623
 
662
624
void multi_delete::abort()
663
625
{
664
 
  
 
626
 
665
627
 
666
628
  /* the error was handled or nothing deleted and no side effects return */
667
629
  if (error_handled ||
668
 
      (!thd->transaction.stmt.modified_non_trans_table && !deleted))
 
630
      (!session->transaction.stmt.modified_non_trans_table && !deleted))
669
631
    return;
670
632
 
671
633
  /*
687
649
    assert(error_handled);
688
650
    return;
689
651
  }
690
 
  
691
 
  if (thd->transaction.stmt.modified_non_trans_table)
 
652
 
 
653
  if (session->transaction.stmt.modified_non_trans_table)
692
654
  {
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;
 
655
    session->transaction.all.modified_non_trans_table= true;
703
656
  }
704
657
  return;
705
658
}
717
670
{
718
671
  int local_error= 0, counter= 0, tmp_error;
719
672
  bool will_batch;
720
 
  
 
673
 
721
674
  assert(do_delete);
722
675
 
723
676
  do_delete= 0;                                 // Mark called
726
679
 
727
680
  table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
728
681
                        delete_tables);
729
 
 
 
682
 
730
683
  for (; table_being_deleted;
731
684
       table_being_deleted= table_being_deleted->next_local, counter++)
732
 
  { 
 
685
  {
733
686
    ha_rows last_deleted= deleted;
734
687
    Table *table = table_being_deleted->table;
735
688
    if (tempfiles[counter]->get(table))
739
692
    }
740
693
 
741
694
    READ_RECORD info;
742
 
    init_read_record(&info,thd,table,NULL,0,1);
 
695
    init_read_record(&info,session,table,NULL,0,1);
743
696
    /*
744
697
      Ignore any rows not found in reference tables as they may already have
745
698
      been deleted by foreign key handling
746
699
    */
747
700
    info.ignore_not_found_rows= 1;
748
701
    will_batch= !table->file->start_bulk_delete();
749
 
    while (!(local_error=info.read_record(&info)) && !thd->killed)
 
702
    while (!(local_error=info.read_record(&info)) && !session->killed)
750
703
    {
751
704
      if ((local_error=table->file->ha_delete_row(table->record[0])))
752
705
      {
764
717
      }
765
718
    }
766
719
    if (last_deleted != deleted && !table->file->has_transactions())
767
 
      thd->transaction.stmt.modified_non_trans_table= true;
 
720
      session->transaction.stmt.modified_non_trans_table= true;
768
721
    end_read_record(&info);
769
 
    if (thd->killed && !local_error)
 
722
    if (session->killed && !local_error)
770
723
      local_error= 1;
771
724
    if (local_error == -1)                              // End of file
772
725
      local_error = 0;
784
737
 
785
738
bool multi_delete::send_eof()
786
739
{
787
 
  THD::killed_state killed_status= THD::NOT_KILLED;
788
 
  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");
789
742
 
790
743
  /* Does deletes for the last n - 1 tables, returns 0 if ok */
791
744
  int local_error= do_deletes();                // returns 0 if success
792
745
 
793
746
  /* compute a total error to know if something failed */
794
747
  local_error= local_error || error;
795
 
  killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
 
748
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
796
749
  /* reset used flags */
797
 
  thd_proc_info(thd, "end");
 
750
  session->set_proc_info("end");
798
751
 
799
 
  if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
 
752
  if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
800
753
  {
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;
 
754
    if (session->transaction.stmt.modified_non_trans_table)
 
755
      session->transaction.all.modified_non_trans_table= true;
815
756
  }
816
757
  if (local_error != 0)
817
758
    error_handled= true; // to force early leave from ::send_error()
818
759
 
819
760
  if (!local_error)
820
761
  {
821
 
    thd->row_count_func= deleted;
822
 
    ::my_ok(thd, (ha_rows) thd->row_count_func);
 
762
    session->row_count_func= deleted;
 
763
    session->my_ok((ha_rows) session->row_count_func);
823
764
  }
824
765
  return 0;
825
766
}
841
782
  - If we want to have a name lock on the table on exit without errors.
842
783
*/
843
784
 
844
 
bool mysql_truncate(THD *thd, TableList *table_list, bool dont_send_ok)
 
785
bool mysql_truncate(Session *session, TableList *table_list, bool dont_send_ok)
845
786
{
846
787
  HA_CREATE_INFO create_info;
847
788
  char path[FN_REFLEN];
848
789
  Table *table;
849
790
  bool error;
850
791
  uint32_t path_length;
851
 
  
 
792
 
852
793
 
853
794
  memset(&create_info, 0, sizeof(create_info));
854
795
  /* If it is a temporary table, close and regenerate it */
855
 
  if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
 
796
  if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
856
797
  {
857
798
    handlerton *table_type= table->s->db_type();
858
799
    TABLE_SHARE *share= table->s;
859
 
    bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
860
800
 
861
 
    if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
 
801
    if (!ha_check_storage_engine_flag(table_type, HTON_BIT_CAN_RECREATE))
862
802
      goto trunc_by_del;
863
803
 
864
804
    table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
865
 
    
866
 
    close_temporary_table(thd, table, 0, 0);    // Don't free share
867
 
    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,
868
808
                    share->db.str, share->table_name.str, &create_info, 1);
869
809
    // We don't need to call invalidate() because this table is not in cache
870
 
    if ((error= (int) !(open_temporary_table(thd, share->path.str,
 
810
    if ((error= (int) !(open_temporary_table(session, share->path.str,
871
811
                                             share->db.str,
872
812
                                             share->table_name.str, 1,
873
813
                                             OTM_OPEN))))
874
 
      (void) rm_temporary_table(table_type, path, frm_only);
 
814
      (void) rm_temporary_table(table_type, path);
875
815
    free_table_share(share);
876
816
    free((char*) table);
877
817
    /*
892
832
  // '\0';
893
833
  path[path_length - reg_ext_length] = 0;
894
834
  pthread_mutex_lock(&LOCK_open);
895
 
  error= ha_create_table(thd, path, table_list->db, table_list->table_name,
 
835
  error= ha_create_table(session, path, table_list->db, table_list->table_name,
896
836
                         &create_info, 1);
897
837
  pthread_mutex_unlock(&LOCK_open);
898
838
 
905
845
        TRUNCATE must always be statement-based binlogged (not row-based) so
906
846
        we don't test current_stmt_binlog_row_based.
907
847
      */
908
 
      write_bin_log(thd, true, thd->query, thd->query_length);
909
 
      my_ok(thd);               // This should return record count
 
848
      write_bin_log(session, true, session->query, session->query_length);
 
849
      session->my_ok();         // This should return record count
910
850
    }
911
851
    pthread_mutex_lock(&LOCK_open);
912
 
    unlock_table_name(thd, table_list);
 
852
    unlock_table_name(session, table_list);
913
853
    pthread_mutex_unlock(&LOCK_open);
914
854
  }
915
855
  else if (error)
916
856
  {
917
857
    pthread_mutex_lock(&LOCK_open);
918
 
    unlock_table_name(thd, table_list);
 
858
    unlock_table_name(session, table_list);
919
859
    pthread_mutex_unlock(&LOCK_open);
920
860
  }
921
861
  return(error);
922
862
 
923
863
trunc_by_del:
924
864
  /* Probably InnoDB table */
925
 
  uint64_t save_options= thd->options;
 
865
  uint64_t save_options= session->options;
926
866
  table_list->lock_type= TL_WRITE;
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
  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,
933
871
                      HA_POS_ERROR, 0L, true);
934
 
  ha_enable_transaction(thd, true);
 
872
  ha_enable_transaction(session, true);
935
873
  /*
936
874
    Safety, in case the engine ignored ha_enable_transaction(false)
937
 
    above. Also clears thd->transaction.*.
 
875
    above. Also clears session->transaction.*.
938
876
  */
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;
 
877
  error= ha_autocommit_or_rollback(session, error);
 
878
  ha_commit(session);
 
879
  session->options= save_options;
943
880
  return(error);
944
881
}