~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

Extracted the LOAD command into its own class and implementation files.
Removed the corresponding case label from the switch statement.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <drizzled/unireg.h>
32
32
#include <drizzled/item/int.h>
33
33
#include <drizzled/item/empty_string.h>
34
 
#include <drizzled/replication_services.h>
35
 
#include <drizzled/table_proto.h>
 
34
#include <drizzled/transaction_services.h>
36
35
 
37
36
#include <algorithm>
38
37
 
39
38
using namespace std;
40
 
extern drizzled::ReplicationServices replication_services;
 
39
extern drizzled::TransactionServices transaction_services;
41
40
 
42
41
static const char hexchars[]= "0123456789abcdef";
43
42
bool is_primary_key(KEY *key_info)
344
343
void write_bin_log(Session *session, bool,
345
344
                   char const *query, size_t query_length)
346
345
{
347
 
  replication_services.rawStatement(session, query, query_length);
 
346
  transaction_services.rawStatement(session, query, query_length);
348
347
}
349
348
 
350
349
 
550
549
      path_length= build_table_filename(path, sizeof(path), db, table->table_name, table->internal_tmp_table);
551
550
    }
552
551
    if (drop_temporary ||
553
 
        ((table_type == NULL
554
 
          && (StorageEngine::getTableProto(path, NULL) != EEXIST))))
 
552
        ((table_type == NULL && (table_proto_exists(path)!=EEXIST))))
555
553
    {
556
554
      // Table was not found on disk and table can't be created from engine
557
555
      if (if_exists)
576
574
        /* the table is referenced by a foreign key constraint */
577
575
        foreign_key_error=1;
578
576
      }
579
 
      if (error == 0)
 
577
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
580
578
      {
 
579
        int new_error;
 
580
 
 
581
        if (!(new_error= delete_table_proto_file(path)))
 
582
        {
581
583
          some_tables_deleted=1;
 
584
          new_error= 0;
 
585
        }
 
586
        error|= new_error;
582
587
      }
583
588
    }
584
589
    if (error)
683
688
 
684
689
  build_table_filename(path, sizeof(path), db, table_name, is_tmp);
685
690
 
 
691
  error= delete_table_proto_file(path);
 
692
 
686
693
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
687
694
              error);
688
695
}
1049
1056
        */
1050
1057
        interval= sql_field->interval= typelib(session->mem_root,
1051
1058
                                               sql_field->interval_list);
1052
 
 
1053
 
        List_iterator<String> int_it(sql_field->interval_list);
1054
 
        String conv, *tmp;
 
1059
        String conv;
1055
1060
        char comma_buf[4];
1056
1061
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
1057
1062
                                          (unsigned char*) comma_buf +
1058
1063
                                          sizeof(comma_buf));
1059
1064
        assert(comma_length > 0);
1060
1065
 
1061
 
        for (uint32_t i= 0; (tmp= int_it++); i++)
 
1066
        vector<String*>::iterator int_it= sql_field->interval_list.begin();
 
1067
        for (uint32_t i= 0; int_it != sql_field->interval_list.end(); ++int_it, ++i)
1062
1068
        {
1063
 
          uint32_t lengthsp;
 
1069
          String *tmp= *int_it;
1064
1070
          if (String::needs_conversion(tmp->length(), tmp->charset(),
1065
1071
                                       cs, &dummy))
1066
1072
          {
1072
1078
          }
1073
1079
 
1074
1080
          // Strip trailing spaces.
1075
 
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1076
 
                                       interval->type_lengths[i]);
 
1081
          uint32_t lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
 
1082
                                                interval->type_lengths[i]);
1077
1083
          interval->type_lengths[i]= lengthsp;
1078
1084
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
1079
1085
        }
1789
1795
  pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1790
1796
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1791
1797
  {
1792
 
    if (StorageEngine::getTableProto(path, NULL)==EEXIST)
 
1798
    if (table_proto_exists(path)==EEXIST)
1793
1799
    {
1794
1800
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1795
1801
      {
1832
1838
  {
1833
1839
    bool create_if_not_exists =
1834
1840
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1835
 
 
1836
 
    char table_path[FN_REFLEN];
1837
 
    uint32_t          table_path_length;
1838
 
 
1839
 
    table_path_length= build_table_filename(table_path, sizeof(table_path),
1840
 
                                            db, table_name, false);
1841
 
 
1842
 
    int retcode= StorageEngine::getTableProto(table_path, NULL);
 
1841
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1843
1842
    switch (retcode)
1844
1843
    {
1845
 
      case ENOENT:
 
1844
      case HA_ERR_NO_SUCH_TABLE:
1846
1845
        /* Normal case, no table exists. we can go and create it */
1847
1846
        break;
1848
 
      case EEXIST:
 
1847
      case HA_ERR_TABLE_EXIST:
1849
1848
        if (create_if_not_exists)
1850
1849
        {
1851
1850
          error= false;
1894
1893
  if (rea_create_table(session, path, db, table_name,
1895
1894
                       table_proto,
1896
1895
                       create_info, alter_info->create_list,
1897
 
                       key_count, key_info_buffer))
 
1896
                       key_count, key_info_buffer, false))
1898
1897
    goto unlock_and_end;
1899
1898
 
1900
1899
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1901
1900
  {
1902
1901
    /* Open table and put in temporary table list */
1903
 
    if (!(session->open_temporary_table(path, db, table_name, 1, OTM_OPEN)))
 
1902
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1904
1903
    {
1905
 
      (void) session->rm_temporary_table(create_info->db_type, path);
 
1904
      (void) rm_temporary_table(create_info->db_type, path);
1906
1905
      goto unlock_and_end;
1907
1906
    }
1908
1907
  }
2073
2072
  if (!(error=base->renameTable(session, from_base, to_base)))
2074
2073
  {
2075
2074
    if(!(flags & NO_FRM_RENAME)
2076
 
       && base->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == 0
2077
2075
       && rename_table_proto_file(from_base, to_base))
2078
2076
    {
2079
2077
      error= my_errno;
2229
2227
      lex->query_tables_own_last= 0;
2230
2228
      session->no_warnings_for_error= no_warnings_for_error;
2231
2229
 
2232
 
      session->openTablesLock(table);
 
2230
      session->open_and_lock_tables(table);
2233
2231
      session->no_warnings_for_error= 0;
2234
2232
      table->next_global= save_next_global;
2235
2233
      table->next_local= save_next_local;
2419
2417
      session->close_thread_tables();
2420
2418
      if (!result_code) // recreation went ok
2421
2419
      {
2422
 
        if ((table->table= session->openTableLock(table, lock_type)) &&
 
2420
        if ((table->table= session->open_ltable(table, lock_type)) &&
2423
2421
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2424
2422
          result_code= 0; // analyze went ok
2425
2423
      }
2521
2519
                           &handler::ha_optimize));
2522
2520
}
2523
2521
 
 
2522
 
 
2523
/*
 
2524
  Assigned specified indexes for a table into key cache
 
2525
 
 
2526
  SYNOPSIS
 
2527
    mysql_assign_to_keycache()
 
2528
    session             Thread object
 
2529
    tables      Table list (one table only)
 
2530
 
 
2531
  RETURN VALUES
 
2532
   false ok
 
2533
   true  error
 
2534
*/
 
2535
 
 
2536
bool mysql_assign_to_keycache(Session* session, TableList* tables,
 
2537
                             LEX_STRING *key_cache_name)
 
2538
{
 
2539
  HA_CHECK_OPT check_opt;
 
2540
  KEY_CACHE *key_cache;
 
2541
 
 
2542
  check_opt.init();
 
2543
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2544
  if (!(key_cache= get_key_cache(key_cache_name)))
 
2545
  {
 
2546
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
2547
    my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
 
2548
    return(true);
 
2549
  }
 
2550
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2551
  check_opt.key_cache= key_cache;
 
2552
  return(mysql_admin_table(session, tables, &check_opt,
 
2553
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
 
2554
                                0, 0, &handler::assign_to_keycache));
 
2555
}
 
2556
 
 
2557
 
 
2558
/*
 
2559
  Reassign all tables assigned to a key cache to another key cache
 
2560
 
 
2561
  SYNOPSIS
 
2562
    reassign_keycache_tables()
 
2563
    session             Thread object
 
2564
    src_cache   Reference to the key cache to clean up
 
2565
    dest_cache  New key cache
 
2566
 
 
2567
  NOTES
 
2568
    This is called when one sets a key cache size to zero, in which
 
2569
    case we have to move the tables associated to this key cache to
 
2570
    the "default" one.
 
2571
 
 
2572
    One has to ensure that one never calls this function while
 
2573
    some other thread is changing the key cache. This is assured by
 
2574
    the caller setting src_cache->in_init before calling this function.
 
2575
 
 
2576
    We don't delete the old key cache as there may still be pointers pointing
 
2577
    to it for a while after this function returns.
 
2578
 
 
2579
 RETURN VALUES
 
2580
    0     ok
 
2581
*/
 
2582
 
 
2583
int reassign_keycache_tables(Session *,
 
2584
                             KEY_CACHE *src_cache,
 
2585
                             KEY_CACHE *dst_cache)
 
2586
{
 
2587
  assert(src_cache != dst_cache);
 
2588
  assert(src_cache->in_init);
 
2589
  src_cache->param_buff_size= 0;                // Free key cache
 
2590
  ha_resize_key_cache(src_cache);
 
2591
  ha_change_key_cache(src_cache, dst_cache);
 
2592
  return 0;
 
2593
}
 
2594
 
 
2595
/**
 
2596
  @brief          Create frm file based on I_S table
 
2597
 
 
2598
  @param[in]      session                      thread handler
 
2599
  @param[in]      schema_table             I_S table
 
2600
  @param[in]      dst_path                 path where frm should be created
 
2601
  @param[in]      create_info              Create info
 
2602
 
 
2603
  @return         Operation status
 
2604
    @retval       0                        success
 
2605
    @retval       1                        error
 
2606
*/
2524
2607
static bool mysql_create_like_schema_frm(Session* session,
2525
2608
                                         TableList* schema_table,
2526
 
                                         HA_CREATE_INFO *create_info,
2527
 
                                         drizzled::message::Table* table_proto)
 
2609
                                         char *dst_path,
 
2610
                                         HA_CREATE_INFO *create_info)
2528
2611
{
2529
2612
  HA_CREATE_INFO local_create_info;
2530
2613
  Alter_info alter_info;
2550
2633
    return true;
2551
2634
 
2552
2635
  local_create_info.max_rows= 0;
2553
 
 
2554
 
  table_proto->set_name("system_stupid_i_s_fix_nonsense");
 
2636
  drizzled::message::Table table_proto;
 
2637
  table_proto.set_name("system_stupid_i_s_fix_nonsense");
2555
2638
  if(tmp_table)
2556
 
    table_proto->set_type(drizzled::message::Table::TEMPORARY);
 
2639
    table_proto.set_type(drizzled::message::Table::TEMPORARY);
2557
2640
  else
2558
 
    table_proto->set_type(drizzled::message::Table::STANDARD);
 
2641
    table_proto.set_type(drizzled::message::Table::STANDARD);
2559
2642
 
2560
2643
  {
2561
2644
    drizzled::message::Table::StorageEngine *protoengine;
2562
 
    protoengine= table_proto->mutable_engine();
 
2645
    protoengine= table_proto.mutable_engine();
2563
2646
 
2564
2647
    StorageEngine *engine= local_create_info.db_type;
2565
2648
 
2566
2649
    protoengine->set_name(engine->getName());
2567
2650
  }
2568
2651
 
2569
 
  if (fill_table_proto(table_proto, "system_stupid_i_s_fix_nonsense",
2570
 
                       alter_info.create_list, &local_create_info,
2571
 
                       keys, schema_table->table->s->key_info))
 
2652
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
 
2653
                       &table_proto,
 
2654
                       &local_create_info, alter_info.create_list,
 
2655
                       keys, schema_table->table->s->key_info,
 
2656
                       true))
2572
2657
    return true;
2573
2658
 
2574
2659
  return false;
2600
2685
  int  err;
2601
2686
  bool res= true;
2602
2687
  uint32_t not_used;
2603
 
  drizzled::message::Table src_proto;
2604
2688
 
2605
2689
  /*
2606
2690
    By opening source table we guarantee that it exists and no concurrent
2611
2695
    we ensure that our statement is properly isolated from all concurrent
2612
2696
    operations which matter.
2613
2697
  */
2614
 
  if (session->open_tables_from_list(&src_table, &not_used))
 
2698
  if (session->open_tables_from_list(&src_table, &not_used, 0))
2615
2699
    return true;
2616
2700
 
2617
2701
  strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
2635
2719
      goto table_exists;
2636
2720
    dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
2637
2721
                                          db, table_name, false);
2638
 
    if (StorageEngine::getTableProto(dst_path, NULL)==EEXIST)
 
2722
    if (table_proto_exists(dst_path)==EEXIST)
2639
2723
      goto table_exists;
2640
2724
  }
2641
2725
 
2653
2737
    during the call to ha_create_table(). See bug #28614 for more info.
2654
2738
  */
2655
2739
  pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2656
 
 
2657
 
  {
2658
 
    int protoerr= EEXIST;
2659
 
 
2660
 
    if (src_table->schema_table)
2661
 
    {
2662
 
      if (mysql_create_like_schema_frm(session, src_table, create_info,
2663
 
                                     &src_proto))
2664
 
      {
2665
 
        pthread_mutex_unlock(&LOCK_open);
2666
 
        goto err;
2667
 
      }
2668
 
    }
2669
 
    else
2670
 
    {
2671
 
      protoerr= StorageEngine::getTableProto(src_path, &src_proto);
2672
 
    }
2673
 
 
2674
 
    string dst_proto_path(dst_path);
2675
 
    string file_ext = ".dfe";
2676
 
 
2677
 
    dst_proto_path.append(file_ext);
2678
 
 
2679
 
    if (protoerr == EEXIST)
2680
 
    {
2681
 
      StorageEngine* engine= ha_resolve_by_name(session,
2682
 
                                                src_proto.engine().name());
2683
 
 
2684
 
      if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2685
 
        protoerr= drizzle_write_proto_file(dst_proto_path.c_str(), &src_proto);
2686
 
      else
2687
 
        protoerr= 0;
2688
 
    }
2689
 
 
2690
 
    if (protoerr)
 
2740
  if (src_table->schema_table)
 
2741
  {
 
2742
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
 
2743
    {
 
2744
      pthread_mutex_unlock(&LOCK_open);
 
2745
      goto err;
 
2746
    }
 
2747
  }
 
2748
  else
 
2749
  {
 
2750
    int dfecopyr= copy_table_proto_file(src_path, dst_path);
 
2751
 
 
2752
    if(dfecopyr)
2691
2753
    {
2692
2754
      if (my_errno == ENOENT)
2693
 
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
2755
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
2694
2756
      else
2695
 
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
 
2757
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2696
2758
      pthread_mutex_unlock(&LOCK_open);
2697
2759
      goto err;
2698
2760
    }
2704
2766
    and temporary tables).
2705
2767
  */
2706
2768
 
2707
 
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1,
2708
 
                       &src_proto);
 
2769
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
2709
2770
  pthread_mutex_unlock(&LOCK_open);
2710
2771
 
2711
2772
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2712
2773
  {
2713
 
    if (err || !session->open_temporary_table(dst_path, db, table_name, 1, OTM_OPEN))
 
2774
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
 
2775
                                     OTM_OPEN))
2714
2776
    {
2715
 
      (void) session->rm_temporary_table(create_info->db_type, dst_path);
 
2777
      (void) rm_temporary_table(create_info->db_type,
 
2778
                                dst_path);
2716
2779
      goto err;     /* purecov: inspected */
2717
2780
    }
2718
2781
  }
2848
2911
   not complain when we lock the table
2849
2912
 */
2850
2913
  session->tablespace_op= true;
2851
 
  if (!(table= session->openTableLock(table_list, TL_WRITE)))
 
2914
  if (!(table= session->open_ltable(table_list, TL_WRITE)))
2852
2915
  {
2853
2916
    session->tablespace_op= false;
2854
2917
    return -1;
3456
3519
    true   Error
3457
3520
*/
3458
3521
 
3459
 
bool mysql_alter_table(Session *session, 
3460
 
                       char *new_db, 
3461
 
                       char *new_name,
 
3522
bool mysql_alter_table(Session *session, char *new_db, char *new_name,
3462
3523
                       HA_CREATE_INFO *create_info,
3463
3524
                       TableList *table_list,
3464
3525
                       Alter_info *alter_info,
3465
 
                       uint32_t order_num, 
3466
 
                       order_st *order, 
3467
 
                       bool ignore)
 
3526
                       uint32_t order_num, order_st *order, bool ignore)
3468
3527
{
3469
 
  Table *table;
3470
 
  Table *new_table= NULL;
3471
 
  Table *name_lock= NULL;
 
3528
  Table *table, *new_table=0, *name_lock= 0;;
3472
3529
  string new_name_str;
3473
3530
  int error= 0;
3474
 
  char tmp_name[80];
3475
 
  char old_name[32];
3476
 
  char new_name_buff[FN_REFLEN];
3477
 
  char new_alias_buff[FN_REFLEN];
3478
 
  char *table_name;
3479
 
  char *db;
 
3531
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
 
3532
  char new_alias_buff[FN_REFLEN], *table_name, *db;
3480
3533
  const char *new_alias;
3481
3534
  char path[FN_REFLEN];
3482
 
  ha_rows copied= 0;
3483
 
  ha_rows deleted= 0;
3484
 
  StorageEngine *old_db_type;
3485
 
  StorageEngine *new_db_type;
3486
 
  StorageEngine *save_old_db_type;
 
3535
  ha_rows copied= 0,deleted= 0;
 
3536
  StorageEngine *old_db_type, *new_db_type, *save_old_db_type;
3487
3537
  bitset<32> tmp;
3488
3538
 
3489
3539
  new_name_buff[0]= '\0';
3494
3544
    return true;
3495
3545
  }
3496
3546
 
3497
 
  session->set_proc_info("init");
3498
 
 
3499
3547
  /*
3500
3548
    Assign variables table_name, new_name, db, new_db, path
3501
3549
    to simplify further comparisons: we want to see if it's a RENAME
3502
3550
    later just by comparing the pointers, avoiding the need for strcmp.
3503
3551
  */
 
3552
  session->set_proc_info("init");
3504
3553
  table_name= table_list->table_name;
3505
 
  db= table_list->db;
3506
 
  if (! new_db || ! my_strcasecmp(table_alias_charset, new_db, db))
 
3554
  db=table_list->db;
 
3555
  if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
3507
3556
    new_db= db;
 
3557
  build_table_filename(path, sizeof(path), db, table_name, false);
3508
3558
 
 
3559
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
3509
3560
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
3510
 
  {
3511
 
    /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
3512
 
    return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
3513
 
  }
3514
 
 
3515
 
  build_table_filename(path, sizeof(path), db, table_name, false);
3516
 
 
 
3561
    /* Conditionally writes to binlog. */
 
3562
    return(mysql_discard_or_import_tablespace(session,table_list,
 
3563
                                              alter_info->tablespace_op));
3517
3564
  ostringstream oss;
3518
3565
  oss << drizzle_data_home << "/" << db << "/" << table_name;
3519
3566
 
3520
3567
  (void) unpack_filename(new_name_buff, oss.str().c_str());
3521
 
 
3522
3568
  /*
3523
3569
    If this is just a rename of a view, short cut to the
3524
3570
    following scenario: 1) lock LOCK_open 2) do a RENAME
3527
3573
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
3528
3574
    as an independent branch in mysql_execute_command. The need
3529
3575
    for a copy-paste arose because the main code flow of ALTER Table
3530
 
    ... RENAME tries to use openTableLock, which does not work for views
3531
 
    (openTableLock was never modified to merge table lists of child tables
 
3576
    ... RENAME tries to use open_ltable, which does not work for views
 
3577
    (open_ltable was never modified to merge table lists of child tables
3532
3578
    into the main table list, like open_tables does).
3533
3579
    This code is wrong and will be removed, please do not copy.
3534
3580
  */
3535
3581
 
3536
 
  if (!(table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
 
3582
  if (!(table= session->open_ltable(table_list, TL_WRITE_ALLOW_READ)))
3537
3583
    return true;
3538
 
  
3539
3584
  table->use_all_columns();
3540
3585
 
3541
3586
  /* Check that we are not trying to rename to an existing table */
3546
3591
    new_alias= new_alias_buff;
3547
3592
 
3548
3593
    my_casedn_str(files_charset_info, new_name_buff);
3549
 
    new_alias= new_name; // Create lower case table name
 
3594
    new_alias= new_name;                        // Create lower case table name
3550
3595
    my_casedn_str(files_charset_info, new_name);
3551
3596
 
3552
3597
    if (new_db == db &&
3553
 
        ! my_strcasecmp(table_alias_charset, new_name_buff, table_name))
 
3598
        !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
3554
3599
    {
3555
3600
      /*
3556
 
        Source and destination table names are equal: make later check
3557
 
        easier.
 
3601
        Source and destination table names are equal: make later check
 
3602
        easier.
3558
3603
      */
3559
3604
      new_alias= new_name= table_name;
3560
3605
    }
3562
3607
    {
3563
3608
      if (table->s->tmp_table != NO_TMP_TABLE)
3564
3609
      {
3565
 
        if (session->find_temporary_table(new_db, new_name_buff))
3566
 
        {
3567
 
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
3568
 
          return true;
3569
 
        }
 
3610
        if (session->find_temporary_table(new_db, new_name_buff))
 
3611
        {
 
3612
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
 
3613
          return true;
 
3614
        }
3570
3615
      }
3571
3616
      else
3572
3617
      {
3573
3618
        if (session->lock_table_name_if_not_cached(new_db, new_name, &name_lock))
3574
3619
          return true;
3575
3620
 
3576
 
        if (! name_lock)
3577
 
        {
3578
 
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
3579
 
          return true;
3580
 
        }
3581
 
 
3582
 
        build_table_filename(new_name_buff, sizeof(new_name_buff), new_db, new_name_buff, false);
3583
 
 
3584
 
        if (StorageEngine::getTableProto(new_name_buff, NULL) == EEXIST)
3585
 
        {
3586
 
          /* Table will be closed by Session::executeCommand() */
3587
 
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
3588
 
          goto err;
3589
 
        }
 
3621
        if (!name_lock)
 
3622
        {
 
3623
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
 
3624
          return true;
 
3625
        }
 
3626
 
 
3627
        build_table_filename(new_name_buff, sizeof(new_name_buff),
 
3628
                             new_db, new_name_buff, false);
 
3629
        if (table_proto_exists(new_name_buff)==EEXIST)
 
3630
        {
 
3631
          /* Table will be closed by Session::executeCommand() */
 
3632
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
 
3633
          goto err;
 
3634
        }
3590
3635
      }
3591
3636
    }
3592
3637
  }
3597
3642
  }
3598
3643
 
3599
3644
  old_db_type= table->s->db_type();
3600
 
  if (! create_info->db_type)
 
3645
  if (!create_info->db_type)
3601
3646
  {
3602
3647
    create_info->db_type= old_db_type;
3603
3648
  }
3604
3649
 
3605
 
  if (table->s->tmp_table != NO_TMP_TABLE)
 
3650
  if(table->s->tmp_table != NO_TMP_TABLE)
3606
3651
    create_info->options|= HA_LEX_CREATE_TMP_TABLE;
3607
3652
 
3608
3653
  if (check_engine(session, new_name, create_info))
3609
3654
    goto err;
3610
 
 
3611
3655
  new_db_type= create_info->db_type;
3612
3656
 
3613
3657
  if (new_db_type != old_db_type &&
3629
3673
  }
3630
3674
 
3631
3675
  session->set_proc_info("setup");
3632
 
  
3633
3676
  /*
3634
3677
   * test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
3635
3678
   */
3640
3683
  if (! (tmp.any()) &&
3641
3684
      ! table->s->tmp_table) // no need to touch frm
3642
3685
  {
3643
 
    switch (alter_info->keys_onoff)
3644
 
    {
 
3686
    switch (alter_info->keys_onoff) {
3645
3687
    case LEAVE_AS_IS:
3646
3688
      break;
3647
3689
    case ENABLE:
3672
3714
      error= 0;
3673
3715
      break;
3674
3716
    }
3675
 
 
3676
3717
    if (error == HA_ERR_WRONG_COMMAND)
3677
3718
    {
3678
3719
      error= 0;
3691
3732
      access() and mysql_rename_table() calls.
3692
3733
    */
3693
3734
 
3694
 
    if (error == 0 && 
3695
 
        (new_name != table_name || new_db != db))
 
3735
    if (!error && (new_name != table_name || new_db != db))
3696
3736
    {
3697
3737
      session->set_proc_info("rename");
3698
3738
      /*
3708
3748
        we don't take this name-lock and where this order really matters.
3709
3749
        TODO: Investigate if we need this access() check at all.
3710
3750
      */
3711
 
      if (StorageEngine::getTableProto(new_name, NULL) == EEXIST)
 
3751
      if (table_proto_exists(new_name)==EEXIST)
3712
3752
      {
3713
3753
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
3714
3754
        error= -1;
3715
3755
      }
3716
3756
      else
3717
3757
      {
3718
 
        *fn_ext(new_name)= 0;
 
3758
        *fn_ext(new_name)=0;
3719
3759
        if (mysql_rename_table(old_db_type, db, table_name, new_db, new_alias, 0))
3720
3760
          error= -1;
 
3761
        else if (0)
 
3762
        {
 
3763
          mysql_rename_table(old_db_type, new_db, new_alias, db,
 
3764
                             table_name, 0);
 
3765
          error= -1;
 
3766
        }
3721
3767
      }
3722
3768
    }
3723
3769
 
3729
3775
                          table->alias);
3730
3776
    }
3731
3777
 
3732
 
    if (error == 0)
 
3778
    if (!error)
3733
3779
    {
3734
3780
      write_bin_log(session, true, session->query, session->query_length);
3735
3781
      session->my_ok();
3736
 
    }
 
3782
  }
3737
3783
    else if (error > 0)
3738
 
    {
 
3784
  {
3739
3785
      table->file->print_error(error, MYF(0));
3740
3786
      error= -1;
3741
3787
    }
3742
 
 
3743
3788
    if (name_lock)
3744
3789
      session->unlink_open_table(name_lock);
3745
 
 
3746
3790
    pthread_mutex_unlock(&LOCK_open);
3747
 
    table_list->table= NULL;
3748
 
    return error;
 
3791
    table_list->table= NULL;                    // For query cache
 
3792
    return(error);
3749
3793
  }
3750
3794
 
3751
3795
  /* We have to do full alter table. */
3752
3796
 
3753
 
  /*
 
3797
    /*
3754
3798
    If the old table had partitions and we are doing ALTER Table ...
3755
3799
    engine= <new_engine>, the new table must preserve the original
3756
3800
    partitioning. That means that the new engine is still the
3764
3808
  new_db_type= create_info->db_type;
3765
3809
 
3766
3810
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
3767
 
    goto err;
 
3811
      goto err;
3768
3812
 
3769
3813
  set_table_default_charset(create_info, db);
3770
3814
 
3771
3815
  alter_info->build_method= HA_BUILD_OFFLINE;
3772
3816
 
3773
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
3774
 
  
 
3817
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
3818
           (unsigned long)current_pid, session->thread_id);
3775
3819
  /* Safety fix for innodb */
3776
3820
  my_casedn_str(files_charset_info, tmp_name);
3777
3821
 
 
3822
 
3778
3823
  /* Create a temporary table with the new format */
3779
 
  error= create_temporary_table(session, table, new_db, tmp_name, create_info, alter_info, ! strcmp(db, new_db));
3780
 
 
3781
 
  if (error != 0)
 
3824
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
3825
                                     create_info, alter_info,
 
3826
                                     !strcmp(db, new_db))))
 
3827
  {
3782
3828
    goto err;
 
3829
  }
3783
3830
 
3784
3831
  /* Open the table so we need to copy the data to it. */
3785
3832
  if (table->s->tmp_table)
3790
3837
    tbl.table_name= tmp_name;
3791
3838
 
3792
3839
    /* Table is in session->temporary_tables */
3793
 
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
3840
    new_table= session->open_table(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
3794
3841
  }
3795
3842
  else
3796
3843
  {
3798
3845
    /* table is a normal table: Create temporary table in same directory */
3799
3846
    build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, true);
3800
3847
    /* Open our intermediate table */
3801
 
    new_table= session->open_temporary_table(tmp_path, new_db, tmp_name, 0, OTM_OPEN);
 
3848
    new_table= open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
3802
3849
  }
3803
3850
 
3804
3851
  if (new_table == NULL)
3806
3853
 
3807
3854
  /* Copy the data if necessary. */
3808
3855
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
3809
 
  session->cuted_fields= 0L;
 
3856
  session->cuted_fields=0L;
3810
3857
  session->set_proc_info("copy to tmp table");
3811
3858
  copied= deleted= 0;
3812
3859
 
3814
3861
 
3815
3862
  /* We don't want update TIMESTAMP fields during ALTER Table. */
3816
3863
  new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
3817
 
  new_table->next_number_field= new_table->found_next_number_field;
3818
 
  error= copy_data_between_tables(table, 
3819
 
                                  new_table,
3820
 
                                  alter_info->create_list, 
3821
 
                                  ignore,
3822
 
                                  order_num, 
3823
 
                                  order, 
3824
 
                                  &copied, 
3825
 
                                  &deleted,
 
3864
  new_table->next_number_field=new_table->found_next_number_field;
 
3865
  error= copy_data_between_tables(table, new_table,
 
3866
                                  alter_info->create_list, ignore,
 
3867
                                  order_num, order, &copied, &deleted,
3826
3868
                                  alter_info->keys_onoff,
3827
3869
                                  alter_info->error_if_not_empty);
3828
3870
 
3829
 
  /* We must not ignore bad input! */
 
3871
  /* We must not ignore bad input! */;
3830
3872
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
3831
3873
 
3832
3874
  if (table->s->tmp_table != NO_TMP_TABLE)
3834
3876
    /* We changed a temporary table */
3835
3877
    if (error)
3836
3878
      goto err1;
3837
 
 
3838
3879
    /* Close lock if this is a transactional table */
3839
3880
    if (session->lock)
3840
3881
    {
3841
3882
      mysql_unlock_tables(session, session->lock);
3842
 
      session->lock= 0;
 
3883
      session->lock=0;
3843
3884
    }
3844
 
 
3845
3885
    /* Remove link to old table and rename the new one */
3846
3886
    session->close_temporary_table(table, true, true);
3847
 
 
3848
3887
    /* Should pass the 'new_name' as we store table name in the cache */
3849
 
    if (new_table->rename_temporary_table(new_db, new_name))
 
3888
    if (rename_temporary_table(new_table, new_db, new_name))
3850
3889
      goto err1;
3851
 
    
3852
3890
    goto end_temporary;
3853
3891
  }
3854
3892
 
3858
3896
      Close the intermediate table that will be the new table.
3859
3897
      Note that MERGE tables do not have their children attached here.
3860
3898
    */
3861
 
    new_table->intern_close_table();
 
3899
    intern_close_table(new_table);
3862
3900
    free(new_table);
3863
3901
  }
3864
 
 
3865
3902
  pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
3866
 
  
3867
3903
  if (error)
3868
3904
  {
3869
3905
    quick_rm_table(new_db_type, new_db, tmp_name, true);
3888
3924
  */
3889
3925
 
3890
3926
  session->set_proc_info("rename result table");
3891
 
 
3892
 
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
3893
 
 
 
3927
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
3928
           (unsigned long)current_pid, session->thread_id);
3894
3929
  my_casedn_str(files_charset_info, old_name);
3895
3930
 
3896
3931
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
3897
3932
  session->close_data_files_and_morph_locks(db, table_name);
3898
3933
 
3899
 
  error= 0;
 
3934
  error=0;
3900
3935
  save_old_db_type= old_db_type;
3901
3936
 
3902
3937
  /*
3912
3947
    table is renamed and the SE is also changed, then an intermediate table
3913
3948
    is created and the additional call will not take place.
3914
3949
  */
3915
 
  if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP))
3916
 
  {
 
3950
  if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
 
3951
                         FN_TO_IS_TMP))
 
3952
  {
 
3953
    error=1;
 
3954
    quick_rm_table(new_db_type, new_db, tmp_name, true);
 
3955
  }
 
3956
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
 
3957
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
 
3958
  {
 
3959
    /* Try to get everything back. */
3917
3960
    error= 1;
 
3961
    quick_rm_table(new_db_type, new_db, new_alias, false);
3918
3962
    quick_rm_table(new_db_type, new_db, tmp_name, true);
3919
 
  }
3920
 
  else
3921
 
  {
3922
 
    if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) != 0)
3923
 
    {
3924
 
      /* Try to get everything back. */
3925
 
      error= 1;
3926
 
      quick_rm_table(new_db_type, new_db, new_alias, false);
3927
 
      quick_rm_table(new_db_type, new_db, tmp_name, true);
3928
 
      mysql_rename_table(old_db_type, db, old_name, db, table_name, FN_FROM_IS_TMP);
3929
 
    }
 
3963
    mysql_rename_table(old_db_type, db, old_name, db, table_name,
 
3964
                       FN_FROM_IS_TMP);
3930
3965
  }
3931
3966
 
3932
3967
  if (error)
3953
3988
    char table_path[FN_REFLEN];
3954
3989
    Table *t_table;
3955
3990
    build_table_filename(table_path, sizeof(table_path), new_db, table_name, false);
3956
 
    t_table= session->open_temporary_table(table_path, new_db, tmp_name, false, OTM_OPEN);
 
3991
    t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
3957
3992
    if (t_table)
3958
3993
    {
3959
 
      t_table->intern_close_table();
 
3994
      intern_close_table(t_table);
3960
3995
      free(t_table);
3961
3996
    }
3962
3997
    else
3963
 
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not open table %s.%s after rename\n"), new_db, table_name);
3964
 
 
 
3998
      errmsg_printf(ERRMSG_LVL_WARN,
 
3999
                    _("Could not open table %s.%s after rename\n"),
 
4000
                    new_db,table_name);
3965
4001
    ha_flush_logs(old_db_type);
3966
4002
  }
3967
 
  table_list->table= NULL;
 
4003
  table_list->table=0;                          // For query cache
3968
4004
 
3969
4005
end_temporary:
3970
4006
  /*
4046
4082
  if (name_lock)
4047
4083
    session->unlink_open_table(name_lock);
4048
4084
  pthread_mutex_unlock(&LOCK_open);
4049
 
  return true;
 
4085
  return(true);
4050
4086
}
4051
4087
/* mysql_alter_table */
4052
4088
 
4222
4258
      found_count++;
4223
4259
  }
4224
4260
  end_read_record(&info);
4225
 
  from->free_io_cache();
 
4261
  free_io_cache(from);
4226
4262
  delete [] copy;                               // This is never 0
4227
4263
 
4228
4264
  if (to->file->ha_end_bulk_insert() && error <= 0)
4250
4286
 err:
4251
4287
  session->variables.sql_mode= save_sql_mode;
4252
4288
  session->abort_on_warning= 0;
4253
 
  from->free_io_cache();
 
4289
  free_io_cache(from);
4254
4290
  *copied= found_count;
4255
4291
  *deleted=delete_count;
4256
4292
  to->file->ha_release_auto_increment();
4320
4356
 
4321
4357
    sprintf(table_name,"%s.%s",table->db,table->table_name);
4322
4358
 
4323
 
    t= table->table= session->openTableLock(table, TL_READ);
 
4359
    t= table->table= session->open_ltable(table, TL_READ);
4324
4360
    session->clear_error();                     // these errors shouldn't get client
4325
4361
 
4326
4362
    protocol->prepareForResend();