~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Monty Taylor
  • Date: 2009-09-30 07:01:32 UTC
  • mto: This revision was merged to the branch mainline in revision 1184.
  • Revision ID: mordred@inaugust.com-20090930070132-b1ol1xu1rpajdddy
Small namespace cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <drizzled/sql_select.h>
23
23
#include <drizzled/error.h>
24
24
#include <drizzled/probes.h>
 
25
#include <drizzled/sql_parse.h>
 
26
#include <drizzled/sql_base.h>
 
27
#include <drizzled/lock.h>
 
28
#include "drizzled/probes.h"
 
29
 
 
30
using namespace drizzled;
25
31
 
26
32
/**
27
33
  Implement DELETE SQL word.
45
51
  bool          const_cond_result;
46
52
  ha_rows       deleted= 0;
47
53
  uint32_t usable_index= MAX_KEY;
48
 
  SELECT_LEX   *select_lex= &session->lex->select_lex;
 
54
  Select_Lex   *select_lex= &session->lex->select_lex;
49
55
  Session::killed_state killed_status= Session::NOT_KILLED;
50
 
  
51
56
 
52
 
  if (open_and_lock_tables(session, table_list))
53
 
    return(true);
54
 
  /* TODO look at this error */
55
 
  if (!(table= table_list->table))
 
57
  if (session->openTablesLock(table_list))
56
58
  {
57
 
    my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
58
 
    return(true);
 
59
    DRIZZLE_DELETE_DONE(1, 0);
 
60
    return true;
59
61
  }
 
62
 
 
63
  table= table_list->table;
 
64
  assert(table);
 
65
 
60
66
  session->set_proc_info("init");
61
67
  table->map=1;
62
68
 
151
157
  /* Update the table->file->stats.records number */
152
158
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
153
159
 
154
 
  table->covering_keys.clear_all();
155
 
  table->quick_keys.clear_all();                // Can't use 'only index'
 
160
  table->covering_keys.reset();
 
161
  table->quick_keys.reset();            // Can't use 'only index'
156
162
  select=make_select(table, 0, 0, conds, 0, &error);
157
163
  if (error)
158
164
    goto err;
161
167
    delete select;
162
168
    free_underlaid_joins(session, select_lex);
163
169
    session->row_count_func= 0;
164
 
    DRIZZLE_DELETE_END();
165
 
    my_ok(session, (ha_rows) session->row_count_func);
 
170
    DRIZZLE_DELETE_DONE(0, 0);
 
171
    session->my_ok((ha_rows) session->row_count_func);
166
172
    /*
167
173
      We don't need to call reset_auto_increment in this case, because
168
174
      mysql_truncate always gives a NULL conds argument, hence we never
169
175
      get here.
170
176
    */
171
 
    return(0);                          // Nothing to delete
 
177
    return 0; // Nothing to delete
172
178
  }
173
179
 
174
180
  /* If running in safe sql mode, don't allow updates without keys */
175
 
  if (table->quick_keys.is_clear_all())
 
181
  if (table->quick_keys.none())
176
182
  {
177
183
    session->server_status|=SERVER_QUERY_NO_INDEX_USED;
178
184
    if (safe_update && !using_limit)
192
198
    uint32_t         length= 0;
193
199
    SORT_FIELD  *sortorder;
194
200
    ha_rows examined_rows;
195
 
    
196
 
    if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
 
201
 
 
202
    if ((!select || table->quick_keys.none()) && limit != HA_POS_ERROR)
197
203
      usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
198
204
 
199
205
    if (usable_index == MAX_KEY)
200
206
    {
201
 
      table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
202
 
                                                   MYF(MY_FAE | MY_ZEROFILL));
203
 
    
 
207
      table->sort.io_cache= new IO_CACHE;
 
208
      memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
 
209
 
 
210
 
204
211
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
205
212
                                             &length, NULL)) ||
206
213
          (table->sort.found_records = filesort(session, table, sortorder, length,
310
317
 
311
318
  if (!transactional_table && deleted > 0)
312
319
    session->transaction.stmt.modified_non_trans_table= true;
313
 
  
 
320
 
314
321
  /* See similar binlogging code in sql_update.cc, for comments */
315
322
  if ((error < 0) || session->transaction.stmt.modified_non_trans_table)
316
323
  {
317
 
    if (mysql_bin_log.is_open())
318
 
    {
319
 
      if (error < 0)
320
 
        session->clear_error();
321
 
      /*
322
 
        [binlog]: If 'handler::delete_all_rows()' was called and the
323
 
        storage engine does not inject the rows itself, we replicate
324
 
        statement-based; otherwise, 'ha_delete_row()' was used to
325
 
        delete specific rows which we might log row-based.
326
 
      */
327
 
      int log_result= session->binlog_query(Session::ROW_QUERY_TYPE,
328
 
                                        session->query, session->query_length,
329
 
                                        transactional_table, false, killed_status);
330
 
 
331
 
      if (log_result && transactional_table)
332
 
      {
333
 
        error=1;
334
 
      }
335
 
    }
336
324
    if (session->transaction.stmt.modified_non_trans_table)
337
325
      session->transaction.all.modified_non_trans_table= true;
338
326
  }
339
327
  assert(transactional_table || !deleted || session->transaction.stmt.modified_non_trans_table);
340
328
  free_underlaid_joins(session, select_lex);
341
329
 
342
 
  DRIZZLE_DELETE_END();
 
330
  DRIZZLE_DELETE_DONE((error >= 0 || session->is_error()), deleted);
343
331
  if (error < 0 || (session->lex->ignore && !session->is_fatal_error))
344
332
  {
345
333
    session->row_count_func= deleted;
346
 
    my_ok(session, (ha_rows) session->row_count_func);
 
334
    session->my_ok((ha_rows) session->row_count_func);
347
335
  }
348
 
  return(error >= 0 || session->is_error());
 
336
  return (error >= 0 || session->is_error());
349
337
 
350
338
err:
351
 
  DRIZZLE_DELETE_END();
352
 
  return(true);
 
339
  DRIZZLE_DELETE_DONE(1, 0);
 
340
  return true;
353
341
}
354
342
 
355
343
 
368
356
*/
369
357
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds)
370
358
{
371
 
  SELECT_LEX *select_lex= &session->lex->select_lex;
372
 
  
 
359
  Select_Lex *select_lex= &session->lex->select_lex;
 
360
 
373
361
  List<Item> all_fields;
374
362
 
375
 
  /*
376
 
    Statement-based replication of DELETE ... LIMIT is not safe as order of
377
 
    rows is not defined, so in mixed mode we go to row-based.
378
 
 
379
 
    Note that we may consider a statement as safe if ORDER BY primary_key
380
 
    is present. However it may confuse users to see very similiar statements
381
 
    replicated differently.
382
 
  */
383
 
  if (session->lex->current_select->select_limit)
384
 
  {
385
 
    session->lex->set_stmt_unsafe();
386
 
    session->set_current_stmt_binlog_row_based();
387
 
  }
388
363
  session->lex->allow_sum_func= 0;
389
364
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
390
365
                                    &session->lex->select_lex.top_join_list,
391
 
                                    table_list, 
 
366
                                    table_list,
392
367
                                    &select_lex->leaf_tables, false) ||
393
 
      setup_conds(session, table_list, select_lex->leaf_tables, conds))
 
368
      session->setup_conds(table_list, conds))
394
369
    return(true);
395
370
  {
396
371
    TableList *duplicate;
397
372
    if ((duplicate= unique_table(session, table_list, table_list->next_global, 0)))
398
373
    {
399
 
      update_non_unique_table_error(table_list, "DELETE", duplicate);
 
374
      my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->alias);
400
375
      return(true);
401
376
    }
402
377
  }
410
385
 
411
386
 
412
387
/***************************************************************************
413
 
  Delete multiple tables from join 
414
 
***************************************************************************/
415
 
 
416
 
#define MEM_STRIP_BUF_SIZE current_session->variables.sortbuff_size
417
 
 
418
 
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
419
 
{
420
 
  handler *file= (handler*)arg;
421
 
  return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
422
 
}
423
 
 
424
 
/*
425
 
  make delete specific preparation and checks after opening tables
426
 
 
427
 
  SYNOPSIS
428
 
    mysql_multi_delete_prepare()
429
 
    session         thread handler
430
 
 
431
 
  RETURN
432
 
    false OK
433
 
    true  Error
434
 
*/
435
 
 
436
 
int mysql_multi_delete_prepare(Session *session)
437
 
{
438
 
  LEX *lex= session->lex;
439
 
  TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
440
 
  TableList *target_tbl;
441
 
  
442
 
 
443
 
  /*
444
 
    setup_tables() need for VIEWs. JOIN::prepare() will not do it second
445
 
    time.
446
 
 
447
 
    lex->query_tables also point on local list of DELETE SELECT_LEX
448
 
  */
449
 
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
450
 
                                    &session->lex->select_lex.top_join_list,
451
 
                                    lex->query_tables,
452
 
                                    &lex->select_lex.leaf_tables, false))
453
 
    return(true);
454
 
 
455
 
 
456
 
  /*
457
 
    Multi-delete can't be constructed over-union => we always have
458
 
    single SELECT on top and have to check underlying SELECTs of it
459
 
  */
460
 
  lex->select_lex.exclude_from_table_unique_test= true;
461
 
  /* Fix tables-to-be-deleted-from list to point at opened tables */
462
 
  for (target_tbl= (TableList*) aux_tables;
463
 
       target_tbl;
464
 
       target_tbl= target_tbl->next_local)
465
 
  {
466
 
    if (!(target_tbl->table= target_tbl->correspondent_table->table))
467
 
    {
468
 
      assert(target_tbl->correspondent_table->merge_underlying_list &&
469
 
                  target_tbl->correspondent_table->merge_underlying_list->
470
 
                  next_local);
471
 
      my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0), "", "");
472
 
      return(true);
473
 
    }
474
 
 
475
 
    /*
476
 
      Check that table from which we delete is not used somewhere
477
 
      inside subqueries/view.
478
 
    */
479
 
    {
480
 
      TableList *duplicate;
481
 
      if ((duplicate= unique_table(session, target_tbl->correspondent_table,
482
 
                                   lex->query_tables, 0)))
483
 
      {
484
 
        update_non_unique_table_error(target_tbl->correspondent_table,
485
 
                                      "DELETE", duplicate);
486
 
        return(true);
487
 
      }
488
 
    }
489
 
  }
490
 
  return(false);
491
 
}
492
 
 
493
 
 
494
 
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
495
 
  : delete_tables(dt), deleted(0), found(0),
496
 
    num_of_tables(num_of_tables_arg), error(0),
497
 
    do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
498
 
{
499
 
  tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
500
 
}
501
 
 
502
 
 
503
 
int
504
 
multi_delete::prepare(List<Item> &, SELECT_LEX_UNIT *u)
505
 
{
506
 
  
507
 
  unit= u;
508
 
  do_delete= 1;
509
 
  session->set_proc_info("deleting from main table");
510
 
  return(0);
511
 
}
512
 
 
513
 
 
514
 
bool
515
 
multi_delete::initialize_tables(JOIN *join)
516
 
{
517
 
  TableList *walk;
518
 
  Unique **tempfiles_ptr;
519
 
  
520
 
 
521
 
  if ((session->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
522
 
    return(1);
523
 
 
524
 
  table_map tables_to_delete_from=0;
525
 
  for (walk= delete_tables; walk; walk= walk->next_local)
526
 
    tables_to_delete_from|= walk->table->map;
527
 
 
528
 
  walk= delete_tables;
529
 
  delete_while_scanning= 1;
530
 
  for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
531
 
       tab < end;
532
 
       tab++)
533
 
  {
534
 
    if (tab->table->map & tables_to_delete_from)
535
 
    {
536
 
      /* We are going to delete from this table */
537
 
      Table *tbl=walk->table=tab->table;
538
 
      walk= walk->next_local;
539
 
      /* Don't use KEYREAD optimization on this table */
540
 
      tbl->no_keyread=1;
541
 
      /* Don't use record cache */
542
 
      tbl->no_cache= 1;
543
 
      tbl->covering_keys.clear_all();
544
 
      if (tbl->file->has_transactions())
545
 
        transactional_tables= 1;
546
 
      else
547
 
        normal_tables= 1;
548
 
      tbl->prepare_for_position();
549
 
      tbl->mark_columns_needed_for_delete();
550
 
    }
551
 
    else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
552
 
             walk == delete_tables)
553
 
    {
554
 
      /*
555
 
        We are not deleting from the table we are scanning. In this
556
 
        case send_data() shouldn't delete any rows a we may touch
557
 
        the rows in the deleted table many times
558
 
      */
559
 
      delete_while_scanning= 0;
560
 
    }
561
 
  }
562
 
  walk= delete_tables;
563
 
  tempfiles_ptr= tempfiles;
564
 
  if (delete_while_scanning)
565
 
  {
566
 
    table_being_deleted= delete_tables;
567
 
    walk= walk->next_local;
568
 
  }
569
 
  for (;walk ;walk= walk->next_local)
570
 
  {
571
 
    Table *table=walk->table;
572
 
    *tempfiles_ptr++= new Unique (refpos_order_cmp,
573
 
                                  (void *) table->file,
574
 
                                  table->file->ref_length,
575
 
                                  MEM_STRIP_BUF_SIZE);
576
 
  }
577
 
  return(session->is_fatal_error != 0);
578
 
}
579
 
 
580
 
 
581
 
multi_delete::~multi_delete()
582
 
{
583
 
  for (table_being_deleted= delete_tables;
584
 
       table_being_deleted;
585
 
       table_being_deleted= table_being_deleted->next_local)
586
 
  {
587
 
    Table *table= table_being_deleted->table;
588
 
    table->no_keyread=0;
589
 
  }
590
 
 
591
 
  for (uint32_t counter= 0; counter < num_of_tables; counter++)
592
 
  {
593
 
    if (tempfiles[counter])
594
 
      delete tempfiles[counter];
595
 
  }
596
 
}
597
 
 
598
 
 
599
 
bool multi_delete::send_data(List<Item> &)
600
 
{
601
 
  int secure_counter= delete_while_scanning ? -1 : 0;
602
 
  TableList *del_table;
603
 
 
604
 
 
605
 
  for (del_table= delete_tables;
606
 
       del_table;
607
 
       del_table= del_table->next_local, secure_counter++)
608
 
  {
609
 
    Table *table= del_table->table;
610
 
 
611
 
    /* Check if we are using outer join and we didn't find the row */
612
 
    if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
613
 
      continue;
614
 
 
615
 
    table->file->position(table->record[0]);
616
 
    found++;
617
 
 
618
 
    if (secure_counter < 0)
619
 
    {
620
 
      /* We are scanning the current table */
621
 
      assert(del_table == table_being_deleted);
622
 
      table->status|= STATUS_DELETED;
623
 
      if (!(error=table->file->ha_delete_row(table->record[0])))
624
 
      {
625
 
        deleted++;
626
 
        if (!table->file->has_transactions())
627
 
          session->transaction.stmt.modified_non_trans_table= true;
628
 
      }
629
 
      else
630
 
      {
631
 
        table->file->print_error(error,MYF(0));
632
 
        return(1);
633
 
      }
634
 
    }
635
 
    else
636
 
    {
637
 
      error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
638
 
      if (error)
639
 
      {
640
 
        error= 1;                               // Fatal error
641
 
        return(1);
642
 
      }
643
 
    }
644
 
  }
645
 
  return(0);
646
 
}
647
 
 
648
 
 
649
 
void multi_delete::send_error(uint32_t errcode,const char *err)
650
 
{
651
 
  
652
 
 
653
 
  /* First send error what ever it is ... */
654
 
  my_message(errcode, err, MYF(0));
655
 
 
656
 
  return;
657
 
}
658
 
 
659
 
 
660
 
void multi_delete::abort()
661
 
{
662
 
  
663
 
 
664
 
  /* the error was handled or nothing deleted and no side effects return */
665
 
  if (error_handled ||
666
 
      (!session->transaction.stmt.modified_non_trans_table && !deleted))
667
 
    return;
668
 
 
669
 
  /*
670
 
    If rows from the first table only has been deleted and it is
671
 
    transactional, just do rollback.
672
 
    The same if all tables are transactional, regardless of where we are.
673
 
    In all other cases do attempt deletes ...
674
 
  */
675
 
  if (do_delete && normal_tables &&
676
 
      (table_being_deleted != delete_tables ||
677
 
       !table_being_deleted->table->file->has_transactions()))
678
 
  {
679
 
    /*
680
 
      We have to execute the recorded do_deletes() and write info into the
681
 
      error log
682
 
    */
683
 
    error= 1;
684
 
    send_eof();
685
 
    assert(error_handled);
686
 
    return;
687
 
  }
688
 
  
689
 
  if (session->transaction.stmt.modified_non_trans_table)
690
 
  {
691
 
    /* 
692
 
       there is only side effects; to binlog with the error
693
 
    */
694
 
    if (mysql_bin_log.is_open())
695
 
    {
696
 
      session->binlog_query(Session::ROW_QUERY_TYPE,
697
 
                        session->query, session->query_length,
698
 
                        transactional_tables, false);
699
 
    }
700
 
    session->transaction.all.modified_non_trans_table= true;
701
 
  }
702
 
  return;
703
 
}
704
 
 
705
 
 
706
 
 
707
 
/*
708
 
  Do delete from other tables.
709
 
  Returns values:
710
 
        0 ok
711
 
        1 error
712
 
*/
713
 
 
714
 
int multi_delete::do_deletes()
715
 
{
716
 
  int local_error= 0, counter= 0, tmp_error;
717
 
  bool will_batch;
718
 
  
719
 
  assert(do_delete);
720
 
 
721
 
  do_delete= 0;                                 // Mark called
722
 
  if (!found)
723
 
    return(0);
724
 
 
725
 
  table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
726
 
                        delete_tables);
727
 
 
728
 
  for (; table_being_deleted;
729
 
       table_being_deleted= table_being_deleted->next_local, counter++)
730
 
  { 
731
 
    ha_rows last_deleted= deleted;
732
 
    Table *table = table_being_deleted->table;
733
 
    if (tempfiles[counter]->get(table))
734
 
    {
735
 
      local_error=1;
736
 
      break;
737
 
    }
738
 
 
739
 
    READ_RECORD info;
740
 
    init_read_record(&info,session,table,NULL,0,1);
741
 
    /*
742
 
      Ignore any rows not found in reference tables as they may already have
743
 
      been deleted by foreign key handling
744
 
    */
745
 
    info.ignore_not_found_rows= 1;
746
 
    will_batch= !table->file->start_bulk_delete();
747
 
    while (!(local_error=info.read_record(&info)) && !session->killed)
748
 
    {
749
 
      if ((local_error=table->file->ha_delete_row(table->record[0])))
750
 
      {
751
 
        table->file->print_error(local_error,MYF(0));
752
 
        break;
753
 
      }
754
 
      deleted++;
755
 
    }
756
 
    if (will_batch && (tmp_error= table->file->end_bulk_delete()))
757
 
    {
758
 
      if (!local_error)
759
 
      {
760
 
        local_error= tmp_error;
761
 
        table->file->print_error(local_error,MYF(0));
762
 
      }
763
 
    }
764
 
    if (last_deleted != deleted && !table->file->has_transactions())
765
 
      session->transaction.stmt.modified_non_trans_table= true;
766
 
    end_read_record(&info);
767
 
    if (session->killed && !local_error)
768
 
      local_error= 1;
769
 
    if (local_error == -1)                              // End of file
770
 
      local_error = 0;
771
 
  }
772
 
  return(local_error);
773
 
}
774
 
 
775
 
 
776
 
/*
777
 
  Send ok to the client
778
 
 
779
 
  return:  0 sucess
780
 
           1 error
781
 
*/
782
 
 
783
 
bool multi_delete::send_eof()
784
 
{
785
 
  Session::killed_state killed_status= Session::NOT_KILLED;
786
 
  session->set_proc_info("deleting from reference tables");
787
 
 
788
 
  /* Does deletes for the last n - 1 tables, returns 0 if ok */
789
 
  int local_error= do_deletes();                // returns 0 if success
790
 
 
791
 
  /* compute a total error to know if something failed */
792
 
  local_error= local_error || error;
793
 
  killed_status= (local_error == 0)? Session::NOT_KILLED : session->killed;
794
 
  /* reset used flags */
795
 
  session->set_proc_info("end");
796
 
 
797
 
  if ((local_error == 0) || session->transaction.stmt.modified_non_trans_table)
798
 
  {
799
 
    if (mysql_bin_log.is_open())
800
 
    {
801
 
      if (local_error == 0)
802
 
        session->clear_error();
803
 
      if (session->binlog_query(Session::ROW_QUERY_TYPE,
804
 
                            session->query, session->query_length,
805
 
                            transactional_tables, false, killed_status) &&
806
 
          !normal_tables)
807
 
      {
808
 
        local_error=1;  // Log write failed: roll back the SQL statement
809
 
      }
810
 
    }
811
 
    if (session->transaction.stmt.modified_non_trans_table)
812
 
      session->transaction.all.modified_non_trans_table= true;
813
 
  }
814
 
  if (local_error != 0)
815
 
    error_handled= true; // to force early leave from ::send_error()
816
 
 
817
 
  if (!local_error)
818
 
  {
819
 
    session->row_count_func= deleted;
820
 
    ::my_ok(session, (ha_rows) session->row_count_func);
821
 
  }
822
 
  return 0;
823
 
}
824
 
 
825
 
 
826
 
/***************************************************************************
827
388
  TRUNCATE Table
828
389
****************************************************************************/
829
390
 
846
407
  Table *table;
847
408
  bool error;
848
409
  uint32_t path_length;
849
 
  
 
410
 
850
411
 
851
412
  memset(&create_info, 0, sizeof(create_info));
852
413
  /* If it is a temporary table, close and regenerate it */
853
 
  if (!dont_send_ok && (table= find_temporary_table(session, table_list)))
 
414
  if (!dont_send_ok && (table= session->find_temporary_table(table_list)))
854
415
  {
855
 
    handlerton *table_type= table->s->db_type();
856
 
    TABLE_SHARE *share= table->s;
857
 
    bool frm_only= (share->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
 
416
    plugin::StorageEngine *table_type= table->s->db_type();
 
417
    TableShare *share= table->s;
858
418
 
859
 
    if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
 
419
    if (!table_type->check_flag(HTON_BIT_CAN_RECREATE))
860
420
      goto trunc_by_del;
861
421
 
862
422
    table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
863
 
    
864
 
    close_temporary_table(session, table, 0, 0);    // Don't free share
865
 
    ha_create_table(session, share->normalized_path.str,
866
 
                    share->db.str, share->table_name.str, &create_info, 1);
 
423
 
 
424
    session->close_temporary_table(table, false, false);    // Don't free share
 
425
    plugin::StorageEngine::createTable(session, share->normalized_path.str,
 
426
                                       share->db.str, share->table_name.str,
 
427
                                       &create_info, 1, NULL);
867
428
    // We don't need to call invalidate() because this table is not in cache
868
 
    if ((error= (int) !(open_temporary_table(session, share->path.str,
869
 
                                             share->db.str,
870
 
                                             share->table_name.str, 1,
871
 
                                             OTM_OPEN))))
872
 
      (void) rm_temporary_table(table_type, path, frm_only);
873
 
    free_table_share(share);
 
429
    if ((error= (int) !(session->open_temporary_table(share->path.str,
 
430
                                                      share->db.str,
 
431
                                                      share->table_name.str, 1,
 
432
                                                      OTM_OPEN))))
 
433
      (void) session->rm_temporary_table(table_type, path);
 
434
    share->free_table_share();
874
435
    free((char*) table);
875
436
    /*
876
437
      If we return here we will not have logged the truncation to the bin log
880
441
  }
881
442
 
882
443
  path_length= build_table_filename(path, sizeof(path), table_list->db,
883
 
                                    table_list->table_name, reg_ext, 0);
 
444
                                    table_list->table_name, 0);
884
445
 
885
446
  if (!dont_send_ok)
886
447
    goto trunc_by_del;
887
448
 
888
 
  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
889
 
  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
890
 
  // '\0';
891
 
  path[path_length - reg_ext_length] = 0;
892
 
  pthread_mutex_lock(&LOCK_open);
893
 
  error= ha_create_table(session, path, table_list->db, table_list->table_name,
894
 
                         &create_info, 1);
 
449
  pthread_mutex_lock(&LOCK_open); /* Recreate table for truncate */
 
450
  error= plugin::StorageEngine::createTable(session, path, table_list->db,
 
451
                                            table_list->table_name,
 
452
                                            &create_info, 1, NULL);
895
453
  pthread_mutex_unlock(&LOCK_open);
896
454
 
897
455
end:
904
462
        we don't test current_stmt_binlog_row_based.
905
463
      */
906
464
      write_bin_log(session, true, session->query, session->query_length);
907
 
      my_ok(session);           // This should return record count
 
465
      session->my_ok();         // This should return record count
908
466
    }
909
 
    pthread_mutex_lock(&LOCK_open);
910
 
    unlock_table_name(session, table_list);
 
467
    pthread_mutex_lock(&LOCK_open); /* For truncate delete from hash when finished */
 
468
    unlock_table_name(table_list);
911
469
    pthread_mutex_unlock(&LOCK_open);
912
470
  }
913
471
  else if (error)
914
472
  {
915
 
    pthread_mutex_lock(&LOCK_open);
916
 
    unlock_table_name(session, table_list);
 
473
    pthread_mutex_lock(&LOCK_open); /* For truncate delete from hash when finished */
 
474
    unlock_table_name(table_list);
917
475
    pthread_mutex_unlock(&LOCK_open);
918
476
  }
919
477
  return(error);