~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

Adds support for '.' in option:: names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include "config.h"
 
18
#include <config.h>
19
19
#include <plugin/myisam/myisam.h>
20
20
#include <drizzled/show.h>
21
21
#include <drizzled/error.h>
26
26
#include <drizzled/sql_lex.h>
27
27
#include <drizzled/session.h>
28
28
#include <drizzled/sql_base.h>
29
 
#include "drizzled/strfunc.h"
30
 
#include <drizzled/db.h>
31
29
#include <drizzled/lock.h>
32
30
#include <drizzled/unireg.h>
33
31
#include <drizzled/item/int.h>
34
32
#include <drizzled/item/empty_string.h>
35
33
#include <drizzled/transaction_services.h>
36
 
#include "drizzled/transaction_services.h"
 
34
#include <drizzled/transaction_services.h>
37
35
#include <drizzled/table_proto.h>
38
36
#include <drizzled/plugin/client.h>
39
37
#include <drizzled/identifier.h>
40
 
#include "drizzled/internal/m_string.h"
41
 
#include "drizzled/global_charset_info.h"
42
 
#include "drizzled/charset.h"
43
 
 
44
 
#include "drizzled/definition/cache.h"
45
 
 
46
 
 
47
 
#include "drizzled/statement/alter_table.h"
48
 
#include "drizzled/sql_table.h"
49
 
#include "drizzled/pthread_globals.h"
 
38
#include <drizzled/internal/m_string.h>
 
39
#include <drizzled/global_charset_info.h>
 
40
#include <drizzled/charset.h>
 
41
 
 
42
#include <drizzled/definition/cache.h>
 
43
 
 
44
#include <drizzled/statement/alter_table.h>
 
45
#include <drizzled/sql_table.h>
 
46
#include <drizzled/pthread_globals.h>
 
47
#include <drizzled/typelib.h>
 
48
#include <drizzled/plugin/storage_engine.h>
50
49
 
51
50
#include <algorithm>
52
51
#include <sstream>
58
57
namespace drizzled
59
58
{
60
59
 
61
 
extern pid_t current_pid;
62
 
 
63
60
bool is_primary_key(KeyInfo *key_info)
64
61
{
65
62
  static const char * primary_key_name="PRIMARY";
87
84
    let's fetch the database default character set and
88
85
    apply it to the table.
89
86
  */
90
 
  SchemaIdentifier identifier(db);
 
87
  identifier::Schema identifier(db);
91
88
  if (create_info->default_table_charset == NULL)
92
89
    create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(identifier);
93
90
}
110
107
void write_bin_log(Session *session, const std::string &query)
111
108
{
112
109
  TransactionServices &transaction_services= TransactionServices::singleton();
113
 
  transaction_services.rawStatement(session, query);
 
110
  transaction_services.rawStatement(*session, query);
114
111
}
115
112
 
116
113
/*
117
114
  Execute the drop of a normal or temporary table
118
115
 
119
116
  SYNOPSIS
120
 
    mysql_rm_table_part2()
 
117
    rm_table_part2()
121
118
    session                     Thread Cursor
122
119
    tables              Tables to drop
123
120
    if_exists           If set, don't give an error if table doesn't exists.
140
137
   -1   Thread was killed
141
138
*/
142
139
 
143
 
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
144
 
                         bool drop_temporary)
 
140
int rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
141
                   bool drop_temporary)
145
142
{
146
143
  TableList *table;
147
 
  String wrong_tables;
 
144
  util::string::vector wrong_tables;
148
145
  int error= 0;
149
146
  bool foreign_key_error= false;
150
147
 
 
148
  do
151
149
  {
152
 
    table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
 
150
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
153
151
 
154
152
    if (not drop_temporary && session->lock_table_names_exclusively(tables))
155
153
    {
156
 
      table::Cache::singleton().mutex().unlock();
157
154
      return 1;
158
155
    }
159
156
 
162
159
 
163
160
    for (table= tables; table; table= table->next_local)
164
161
    {
165
 
      TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
 
162
      identifier::Table tmp_identifier(table->getSchemaName(), table->getTableName());
166
163
 
167
164
      error= session->drop_temporary_table(tmp_identifier);
168
165
 
172
169
        continue;
173
170
      case -1:
174
171
        error= 1;
175
 
        goto err_with_placeholders;
 
172
        break;
176
173
      default:
177
174
        // temporary table not found
178
175
        error= 0;
195
192
        if (session->getKilled())
196
193
        {
197
194
          error= -1;
198
 
          goto err_with_placeholders;
 
195
          break;
199
196
        }
200
197
      }
201
 
      TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
 
198
      identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
 
199
 
 
200
      message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier, true);
202
201
 
203
202
      if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
203
      {
205
204
        // Table was not found on disk and table can't be created from engine
206
205
        if (if_exists)
 
206
        {
207
207
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
208
                              ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
209
                              table->getTableName());
 
210
        }
210
211
        else
 
212
        {
211
213
          error= 1;
 
214
        }
212
215
      }
213
216
      else
214
217
      {
215
 
        error= plugin::StorageEngine::dropTable(*session, identifier);
216
 
 
217
 
        if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
218
 
        {
219
 
          error= 0;
220
 
          session->clear_error();
221
 
        }
222
 
 
223
 
        if (error == HA_ERR_ROW_IS_REFERENCED)
224
 
        {
225
 
          /* the table is referenced by a foreign key constraint */
226
 
          foreign_key_error= true;
227
 
        }
228
 
      }
229
 
 
230
 
      if (error == 0 || (if_exists && foreign_key_error == false))
231
 
      {
232
 
        TransactionServices &transaction_services= TransactionServices::singleton();
233
 
        transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
 
218
        drizzled::error_t local_error;
 
219
 
 
220
        /* Generate transaction event ONLY when we successfully drop */ 
 
221
        if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
 
222
        {
 
223
          if (message) // If we have no definition, we don't know if the table should have been replicated
 
224
          {
 
225
            TransactionServices &transaction_services= TransactionServices::singleton();
 
226
            transaction_services.dropTable(*session, identifier, *message, if_exists);
 
227
          }
 
228
        }
 
229
        else
 
230
        {
 
231
          if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists)
 
232
          {
 
233
            error= 0;
 
234
            session->clear_error();
 
235
          }
 
236
 
 
237
          if (local_error == HA_ERR_ROW_IS_REFERENCED)
 
238
          {
 
239
            /* the table is referenced by a foreign key constraint */
 
240
            foreign_key_error= true;
 
241
          }
 
242
          error= local_error;
 
243
        }
234
244
      }
235
245
 
236
246
      if (error)
237
247
      {
238
 
        if (wrong_tables.length())
239
 
          wrong_tables.append(',');
240
 
        wrong_tables.append(String(table->getTableName(), system_charset_info));
 
248
        wrong_tables.push_back(table->getTableName());
241
249
      }
242
250
    }
243
 
    /*
244
 
      It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
245
 
      on the table name.
246
 
    */
247
 
    table::Cache::singleton().mutex().unlock();
248
 
  }
249
 
  error= 0;
250
 
 
251
 
  if (wrong_tables.length())
 
251
 
 
252
    tables->unlock_table_names();
 
253
 
 
254
  } while (0);
 
255
 
 
256
  if (wrong_tables.size())
252
257
  {
253
258
    if (not foreign_key_error)
254
259
    {
 
260
      std::string table_error;
 
261
 
 
262
      for (util::string::vector::iterator iter= wrong_tables.begin();
 
263
           iter != wrong_tables.end();
 
264
           iter++)
 
265
      {
 
266
        table_error+= *iter;
 
267
        table_error+= ',';
 
268
      }
 
269
      table_error.resize(table_error.size() -1);
 
270
 
255
271
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
256
 
                      wrong_tables.c_ptr());
 
272
                      table_error.c_str());
257
273
    }
258
274
    else
259
275
    {
262
278
    error= 1;
263
279
  }
264
280
 
265
 
  table::Cache::singleton().mutex().lock(); /* final bit in rm table lock */
266
 
 
267
 
err_with_placeholders:
268
 
  tables->unlock_table_names();
269
 
  table::Cache::singleton().mutex().unlock();
270
281
  session->no_warnings_for_error= 0;
271
282
 
272
283
  return error;
471
482
    sql_field->length= 8; // Unireg field length
472
483
    (*blob_columns)++;
473
484
    break;
474
 
  case DRIZZLE_TYPE_VARCHAR:
475
 
    break;
 
485
 
476
486
  case DRIZZLE_TYPE_ENUM:
477
 
    if (check_duplicates_in_interval("ENUM",
478
 
                                     sql_field->field_name,
479
 
                                     sql_field->interval,
480
 
                                     sql_field->charset,
481
 
                                     &dup_val_count))
482
 
      return 1;
483
 
    break;
484
 
  case DRIZZLE_TYPE_DATE:  // Rest of string types
485
 
  case DRIZZLE_TYPE_DATETIME:
486
 
  case DRIZZLE_TYPE_NULL:
487
 
    break;
488
 
  case DRIZZLE_TYPE_DECIMAL:
489
 
    break;
 
487
    {
 
488
      if (check_duplicates_in_interval("ENUM",
 
489
                                       sql_field->field_name,
 
490
                                       sql_field->interval,
 
491
                                       sql_field->charset,
 
492
                                       &dup_val_count))
 
493
      {
 
494
        return 1;
 
495
      }
 
496
    }
 
497
    break;
 
498
 
 
499
  case DRIZZLE_TYPE_MICROTIME:
490
500
  case DRIZZLE_TYPE_TIMESTAMP:
491
501
    /* We should replace old TIMESTAMP fields with their newer analogs */
492
502
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
502
512
      }
503
513
    }
504
514
    else if (sql_field->unireg_check != Field::NONE)
 
515
    {
505
516
      (*timestamps_with_niladic)++;
 
517
    }
506
518
 
507
519
    (*timestamps)++;
508
 
    /* fall-through */
509
 
  default:
 
520
 
 
521
    break;
 
522
 
 
523
  case DRIZZLE_TYPE_BOOLEAN:
 
524
  case DRIZZLE_TYPE_DATE:  // Rest of string types
 
525
  case DRIZZLE_TYPE_DATETIME:
 
526
  case DRIZZLE_TYPE_DECIMAL:
 
527
  case DRIZZLE_TYPE_DOUBLE:
 
528
  case DRIZZLE_TYPE_LONG:
 
529
  case DRIZZLE_TYPE_LONGLONG:
 
530
  case DRIZZLE_TYPE_NULL:
 
531
  case DRIZZLE_TYPE_TIME:
 
532
  case DRIZZLE_TYPE_UUID:
 
533
  case DRIZZLE_TYPE_VARCHAR:
510
534
    break;
511
535
  }
512
536
 
513
537
  return 0;
514
538
}
515
539
 
516
 
static int mysql_prepare_create_table(Session *session,
517
 
                                      HA_CREATE_INFO *create_info,
518
 
                                      message::Table &create_proto,
519
 
                                      AlterInfo *alter_info,
520
 
                                      bool tmp_table,
521
 
                                      uint32_t *db_options,
522
 
                                      KeyInfo **key_info_buffer,
523
 
                                      uint32_t *key_count,
524
 
                                      int select_field_count)
 
540
static int prepare_create_table(Session *session,
 
541
                                HA_CREATE_INFO *create_info,
 
542
                                message::Table &create_proto,
 
543
                                AlterInfo *alter_info,
 
544
                                bool tmp_table,
 
545
                                uint32_t *db_options,
 
546
                                KeyInfo **key_info_buffer,
 
547
                                uint32_t *key_count,
 
548
                                int select_field_count)
525
549
{
526
550
  const char    *key_name;
527
551
  CreateField   *sql_field,*dup_field;
530
554
  KeyInfo               *key_info;
531
555
  KeyPartInfo *key_part_info;
532
556
  int           timestamps= 0, timestamps_with_niladic= 0;
533
 
  int           field_no,dup_no;
 
557
  int           dup_no;
534
558
  int           select_field_pos,auto_increment=0;
535
 
  List_iterator<CreateField> it(alter_info->create_list);
536
 
  List_iterator<CreateField> it2(alter_info->create_list);
 
559
  List<CreateField>::iterator it(alter_info->create_list.begin());
 
560
  List<CreateField>::iterator it2(alter_info->create_list.begin());
537
561
  uint32_t total_uneven_bit_length= 0;
538
562
 
539
563
  plugin::StorageEngine *engine= plugin::StorageEngine::findByName(create_proto.engine().name());
540
564
 
541
 
  select_field_pos= alter_info->create_list.elements - select_field_count;
 
565
  select_field_pos= alter_info->create_list.size() - select_field_count;
542
566
  null_fields=blob_columns=0;
543
567
  max_key_length= engine->max_key_length();
544
568
 
545
 
  for (field_no=0; (sql_field=it++) ; field_no++)
 
569
  for (int32_t field_no=0; (sql_field=it++) ; field_no++)
546
570
  {
547
571
    const CHARSET_INFO *save_cs;
548
572
 
552
576
      executing a prepared statement for the second time.
553
577
    */
554
578
    sql_field->length= sql_field->char_length;
 
579
 
555
580
    if (!sql_field->charset)
556
581
      sql_field->charset= create_info->default_table_charset;
 
582
 
557
583
    /*
558
584
      table_charset is set in ALTER Table if we want change character set
559
585
      for all varchar/char columns.
625
651
        interval= sql_field->interval= typelib(session->mem_root,
626
652
                                               sql_field->interval_list);
627
653
 
628
 
        List_iterator<String> int_it(sql_field->interval_list);
 
654
        List<String>::iterator int_it(sql_field->interval_list.begin());
629
655
        String conv, *tmp;
630
656
        char comma_buf[4];
631
657
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
651
677
          interval->type_lengths[i]= lengthsp;
652
678
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
653
679
        }
654
 
        sql_field->interval_list.empty(); // Don't need interval_list anymore
 
680
        sql_field->interval_list.clear(); // Don't need interval_list anymore
655
681
      }
656
682
 
657
683
      /* DRIZZLE_TYPE_ENUM */
674
700
          else /* not NULL */
675
701
          {
676
702
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
677
 
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
 
703
            if (interval->find_type2(def->ptr(), def->length(), cs) == 0) /* not found */
678
704
            {
679
705
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
680
706
              return(true);
751
777
    if (not create_proto.engine().name().compare("MyISAM") &&
752
778
        ((sql_field->flags & BLOB_FLAG) ||
753
779
         (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)))
 
780
    {
754
781
      (*db_options)|= HA_OPTION_PACK_RECORD;
755
 
    it2.rewind();
 
782
    }
 
783
 
 
784
    it2= alter_info->create_list.begin();
756
785
  }
757
786
 
758
787
  /* record_offset will be increased with 'length-of-null-bits' later */
759
788
  record_offset= 0;
760
789
  null_fields+= total_uneven_bit_length;
761
790
 
762
 
  it.rewind();
 
791
  it= alter_info->create_list.begin();
763
792
  while ((sql_field=it++))
764
793
  {
765
794
    assert(sql_field->charset != 0);
799
828
 
800
829
  /* Create keys */
801
830
 
802
 
  List_iterator<Key> key_iterator(alter_info->key_list);
803
 
  List_iterator<Key> key_iterator2(alter_info->key_list);
 
831
  List<Key>::iterator key_iterator(alter_info->key_list.begin());
 
832
  List<Key>::iterator key_iterator2(alter_info->key_list.begin());
804
833
  uint32_t key_parts=0, fk_key_count=0;
805
834
  bool primary_key=0,unique_key=0;
806
835
  Key *key, *key2;
830
859
                                       fk_key->update_opt,
831
860
                                       fk_key->match_opt);
832
861
 
833
 
      if (fk_key->ref_columns.elements &&
834
 
          fk_key->ref_columns.elements != fk_key->columns.elements)
 
862
      if (fk_key->ref_columns.size() &&
 
863
          fk_key->ref_columns.size() != fk_key->columns.size())
835
864
      {
836
865
        my_error(ER_WRONG_FK_DEF, MYF(0),
837
866
                 (fk_key->name.str ? fk_key->name.str :
843
872
    }
844
873
    (*key_count)++;
845
874
    tmp= engine->max_key_parts();
846
 
    if (key->columns.elements > tmp)
 
875
    if (key->columns.size() > tmp)
847
876
    {
848
877
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
849
878
      return(true);
850
879
    }
851
880
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
852
881
      return(true);
853
 
    key_iterator2.rewind ();
 
882
    key_iterator2= alter_info->key_list.begin();
854
883
    if (key->type != Key::FOREIGN_KEY)
855
884
    {
856
885
      while ((key2 = key_iterator2++) != key)
867
896
          /* @todo issue warning message */
868
897
          /* mark that the generated key should be ignored */
869
898
          if (!key2->generated ||
870
 
              (key->generated && key->columns.elements <
871
 
               key2->columns.elements))
 
899
              (key->generated && key->columns.size() <
 
900
               key2->columns.size()))
872
901
            key->name.str= ignore_key;
873
902
          else
874
903
          {
875
904
            key2->name.str= ignore_key;
876
 
            key_parts-= key2->columns.elements;
 
905
            key_parts-= key2->columns.size();
877
906
            (*key_count)--;
878
907
          }
879
908
          break;
881
910
      }
882
911
    }
883
912
    if (key->name.str != ignore_key)
884
 
      key_parts+=key->columns.elements;
 
913
      key_parts+=key->columns.size();
885
914
    else
886
915
      (*key_count)--;
887
916
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
903
932
  if (!*key_info_buffer || ! key_part_info)
904
933
    return(true);                               // Out of memory
905
934
 
906
 
  key_iterator.rewind();
 
935
  key_iterator= alter_info->key_list.begin();
907
936
  key_number=0;
908
937
  for (; (key=key_iterator++) ; key_number++)
909
938
  {
934
963
    if (key->generated)
935
964
      key_info->flags|= HA_GENERATED_KEY;
936
965
 
937
 
    key_info->key_parts=(uint8_t) key->columns.elements;
 
966
    key_info->key_parts=(uint8_t) key->columns.size();
938
967
    key_info->key_part=key_part_info;
939
968
    key_info->usable_key_parts= key_number;
940
969
    key_info->algorithm= key->key_create_info.algorithm;
962
991
 
963
992
    message::Table::Field *protofield= NULL;
964
993
 
965
 
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
 
994
    List<Key_part_spec>::iterator cols(key->columns.begin());
 
995
    List<Key_part_spec>::iterator cols2(key->columns.begin());
966
996
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
967
997
    {
968
998
      uint32_t length;
969
999
      Key_part_spec *dup_column;
970
1000
      int proto_field_nr= 0;
971
1001
 
972
 
      it.rewind();
 
1002
      it= alter_info->create_list.begin();
973
1003
      field=0;
974
1004
      while ((sql_field=it++) && ++proto_field_nr &&
975
1005
             my_strcasecmp(system_charset_info,
976
1006
                           column->field_name.str,
977
1007
                           sql_field->field_name))
 
1008
      {
978
1009
        field++;
 
1010
      }
 
1011
 
979
1012
      if (!sql_field)
980
1013
      {
981
1014
        my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
982
1015
        return(true);
983
1016
      }
 
1017
 
984
1018
      while ((dup_column= cols2++) != column)
985
1019
      {
986
1020
        if (!my_strcasecmp(system_charset_info,
992
1026
          return(true);
993
1027
        }
994
1028
      }
995
 
      cols2.rewind();
 
1029
      cols2= key->columns.begin();
996
1030
 
997
1031
      if (create_proto.field_size() > 0)
998
1032
        protofield= create_proto.mutable_field(proto_field_nr - 1);
1013
1047
            return true;
1014
1048
          }
1015
1049
        }
 
1050
 
1016
1051
        if (! (sql_field->flags & NOT_NULL_FLAG))
1017
1052
        {
1018
1053
          if (key->type == Key::PRIMARY)
1025
1060
            {
1026
1061
              message::Table::Field::FieldConstraints *constraints;
1027
1062
              constraints= protofield->mutable_constraints();
1028
 
              constraints->set_is_nullable(false);
 
1063
              constraints->set_is_notnull(true);
1029
1064
            }
1030
1065
 
1031
1066
          }
1039
1074
            }
1040
1075
          }
1041
1076
        }
 
1077
 
1042
1078
        if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1043
1079
        {
1044
1080
          if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1163
1199
        key_info->name=(char*) key_name;
1164
1200
      }
1165
1201
    }
 
1202
 
1166
1203
    if (!key_info->name || check_column_name(key_info->name))
1167
1204
    {
1168
1205
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1169
1206
      return(true);
1170
1207
    }
 
1208
 
1171
1209
    if (!(key_info->flags & HA_NULL_PART_KEY))
 
1210
    {
1172
1211
      unique_key=1;
 
1212
    }
 
1213
 
1173
1214
    key_info->key_length=(uint16_t) key_length;
 
1215
 
1174
1216
    if (key_length > max_key_length)
1175
1217
    {
1176
1218
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1177
1219
      return(true);
1178
1220
    }
 
1221
 
1179
1222
    key_info++;
1180
1223
  }
 
1224
 
1181
1225
  if (!unique_key && !primary_key &&
1182
1226
      (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1183
1227
  {
1184
1228
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1185
1229
    return(true);
1186
1230
  }
 
1231
 
1187
1232
  if (auto_increment > 0)
1188
1233
  {
1189
1234
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1194
1239
                     (qsort_cmp) sort_keys);
1195
1240
 
1196
1241
  /* Check fields. */
1197
 
  it.rewind();
 
1242
  it= alter_info->create_list.begin();
1198
1243
  while ((sql_field=it++))
1199
1244
  {
1200
1245
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1201
1246
 
1202
1247
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1203
1248
        !sql_field->def &&
1204
 
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
 
1249
        (sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP  or sql_field->sql_type == DRIZZLE_TYPE_MICROTIME) &&
1205
1250
        (sql_field->flags & NOT_NULL_FLAG) &&
1206
1251
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1207
1252
    {
1265
1310
}
1266
1311
 
1267
1312
static bool locked_create_event(Session *session,
1268
 
                                const TableIdentifier &identifier,
 
1313
                                const identifier::Table &identifier,
1269
1314
                                HA_CREATE_INFO *create_info,
1270
1315
                                message::Table &table_proto,
1271
1316
                                AlterInfo *alter_info,
1300
1345
        return error;
1301
1346
      }
1302
1347
 
1303
 
      std::string path;
1304
 
      identifier.getSQLPath(path);
1305
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
1348
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
1306
1349
 
1307
1350
      return error;
1308
1351
    }
1322
1365
      */
1323
1366
      if (definition::Cache::singleton().find(identifier.getKey()))
1324
1367
      {
1325
 
        std::string path;
1326
 
        identifier.getSQLPath(path);
1327
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
1368
        my_error(ER_TABLE_EXISTS_ERROR, identifier);
1328
1369
 
1329
1370
        return error;
1330
1371
      }
1363
1404
  if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1364
1405
  {
1365
1406
    TransactionServices &transaction_services= TransactionServices::singleton();
1366
 
    transaction_services.createTable(session, table_proto);
 
1407
    transaction_services.createTable(*session, table_proto);
1367
1408
  }
1368
1409
 
1369
1410
  return false;
1376
1417
  Create a table
1377
1418
 
1378
1419
  SYNOPSIS
1379
 
    mysql_create_table_no_lock()
 
1420
    create_table_no_lock()
1380
1421
    session                     Thread object
1381
1422
    db                  Database
1382
1423
    table_name          Table name
1392
1433
 
1393
1434
    Note that this function assumes that caller already have taken
1394
1435
    name-lock on table being created or used some other way to ensure
1395
 
    that concurrent operations won't intervene. mysql_create_table()
 
1436
    that concurrent operations won't intervene. create_table()
1396
1437
    is a wrapper that can be used for this.
1397
1438
 
1398
1439
  RETURN VALUES
1400
1441
    true  error
1401
1442
*/
1402
1443
 
1403
 
bool mysql_create_table_no_lock(Session *session,
1404
 
                                const TableIdentifier &identifier,
 
1444
bool create_table_no_lock(Session *session,
 
1445
                                const identifier::Table &identifier,
1405
1446
                                HA_CREATE_INFO *create_info,
1406
1447
                                message::Table &table_proto,
1407
1448
                                AlterInfo *alter_info,
1414
1455
  bool          error= true;
1415
1456
 
1416
1457
  /* Check for duplicate fields and check type of table to create */
1417
 
  if (not alter_info->create_list.elements)
 
1458
  if (not alter_info->create_list.size())
1418
1459
  {
1419
1460
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1420
1461
               MYF(0));
1426
1467
  set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1427
1468
 
1428
1469
  /* Build a Table object to pass down to the engine, and the do the actual create. */
1429
 
  if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1430
 
                                     internal_tmp_table,
1431
 
                                     &db_options,
1432
 
                                     &key_info_buffer, &key_count,
1433
 
                                     select_field_count))
 
1470
  if (not prepare_create_table(session, create_info, table_proto, alter_info,
 
1471
                               internal_tmp_table,
 
1472
                               &db_options,
 
1473
                               &key_info_buffer, &key_count,
 
1474
                               select_field_count))
1434
1475
  {
1435
1476
    boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1436
1477
    error= locked_create_event(session,
1453
1494
  @note the following two methods implement create [temporary] table.
1454
1495
*/
1455
1496
static bool drizzle_create_table(Session *session,
1456
 
                                 const TableIdentifier &identifier,
 
1497
                                 const identifier::Table &identifier,
1457
1498
                                 HA_CREATE_INFO *create_info,
1458
1499
                                 message::Table &table_proto,
1459
1500
                                 AlterInfo *alter_info,
1480
1521
    }
1481
1522
    else
1482
1523
    {
1483
 
      std::string path;
1484
 
      identifier.getSQLPath(path);
1485
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
1524
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
1486
1525
      result= true;
1487
1526
    }
1488
1527
  }
1489
1528
  else
1490
1529
  {
1491
 
    result= mysql_create_table_no_lock(session,
 
1530
    result= create_table_no_lock(session,
1492
1531
                                       identifier,
1493
1532
                                       create_info,
1494
1533
                                       table_proto,
1509
1548
 
1510
1549
 
1511
1550
/*
1512
 
  Database locking aware wrapper for mysql_create_table_no_lock(),
 
1551
  Database locking aware wrapper for create_table_no_lock(),
1513
1552
*/
1514
 
bool mysql_create_table(Session *session,
1515
 
                        const TableIdentifier &identifier,
 
1553
bool create_table(Session *session,
 
1554
                        const identifier::Table &identifier,
1516
1555
                        HA_CREATE_INFO *create_info,
1517
1556
                        message::Table &table_proto,
1518
1557
                        AlterInfo *alter_info,
1522
1561
{
1523
1562
  if (identifier.isTmp())
1524
1563
  {
1525
 
    return mysql_create_table_no_lock(session,
 
1564
    return create_table_no_lock(session,
1526
1565
                                      identifier,
1527
1566
                                      create_info,
1528
1567
                                      table_proto,
1592
1631
  Rename a table.
1593
1632
 
1594
1633
  SYNOPSIS
1595
 
    mysql_rename_table()
 
1634
    rename_table()
1596
1635
      session
1597
1636
      base                      The plugin::StorageEngine handle.
1598
1637
      old_db                    The old database name.
1606
1645
*/
1607
1646
 
1608
1647
bool
1609
 
mysql_rename_table(Session &session,
 
1648
rename_table(Session &session,
1610
1649
                   plugin::StorageEngine *base,
1611
 
                   const TableIdentifier &from,
1612
 
                   const TableIdentifier &to)
 
1650
                   const identifier::Table &from,
 
1651
                   const identifier::Table &to)
1613
1652
{
1614
1653
  int error= 0;
1615
1654
 
1675
1714
  session->abortLock(table);    /* end threads waiting on lock */
1676
1715
 
1677
1716
  /* Wait until all there are no other threads that has this table open */
1678
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
 
1717
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1679
1718
  table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1680
1719
}
1681
1720
 
1719
1758
    true  Message should be sent by caller
1720
1759
          (admin operation or network communication failed)
1721
1760
*/
1722
 
static bool mysql_admin_table(Session* session, TableList* tables,
 
1761
static bool admin_table(Session* session, TableList* tables,
1723
1762
                              HA_CHECK_OPT* check_opt,
1724
1763
                              const char *operator_name,
1725
1764
                              thr_lock_type lock_type,
1728
1767
                                                            HA_CHECK_OPT *))
1729
1768
{
1730
1769
  TableList *table;
1731
 
  Select_Lex *select= &session->lex->select_lex;
 
1770
  Select_Lex *select= &session->getLex()->select_lex;
1732
1771
  List<Item> field_list;
1733
1772
  Item *item;
1734
 
  LEX *lex= session->lex;
1735
1773
  int result_code= 0;
1736
1774
  TransactionServices &transaction_services= TransactionServices::singleton();
1737
1775
  const CHARSET_INFO * const cs= system_charset_info;
1738
1776
 
1739
1777
  if (! session->endActiveTransaction())
1740
1778
    return 1;
 
1779
 
1741
1780
  field_list.push_back(item = new Item_empty_string("Table",
1742
1781
                                                    NAME_CHAR_LEN * 2,
1743
1782
                                                    cs));
1748
1787
  item->maybe_null = 1;
1749
1788
  field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
1750
1789
  item->maybe_null = 1;
1751
 
  if (session->client->sendFields(&field_list))
 
1790
  if (session->getClient()->sendFields(&field_list))
1752
1791
    return true;
1753
1792
 
1754
1793
  for (table= tables; table; table= table->next_local)
1755
1794
  {
1756
 
    char table_name[NAME_LEN*2+2];
 
1795
    identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
 
1796
    std::string table_name;
1757
1797
    bool fatal_error=0;
1758
1798
 
1759
 
    snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
 
1799
    table_identifier.getSQLPath(table_name);
 
1800
 
1760
1801
    table->lock_type= lock_type;
1761
1802
    /* open only one table from local list of command */
1762
1803
    {
1771
1812
        so it have to be prepared.
1772
1813
        @todo Investigate if we can put extra tables into argument instead of using lex->query_tables
1773
1814
      */
1774
 
      lex->query_tables= table;
1775
 
      lex->query_tables_last= &table->next_global;
1776
 
      lex->query_tables_own_last= 0;
 
1815
      session->getLex()->query_tables= table;
 
1816
      session->getLex()->query_tables_last= &table->next_global;
 
1817
      session->getLex()->query_tables_own_last= 0;
1777
1818
      session->no_warnings_for_error= 0;
1778
1819
 
1779
1820
      session->openTablesLock(table);
1792
1833
    */
1793
1834
    if (!table->table)
1794
1835
    {
1795
 
      if (!session->warn_list.elements)
 
1836
      if (!session->warn_list.size())
1796
1837
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1797
1838
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
1798
1839
      result_code= HA_ADMIN_CORRUPT;
1803
1844
    {
1804
1845
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1805
1846
      uint32_t length;
1806
 
      session->client->store(table_name);
1807
 
      session->client->store(operator_name);
1808
 
      session->client->store(STRING_WITH_LEN("error"));
 
1847
      session->getClient()->store(table_name.c_str());
 
1848
      session->getClient()->store(operator_name);
 
1849
      session->getClient()->store(STRING_WITH_LEN("error"));
1809
1850
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1810
 
                       table_name);
1811
 
      session->client->store(buff, length);
1812
 
      transaction_services.autocommitOrRollback(session, false);
 
1851
                       table_name.c_str());
 
1852
      session->getClient()->store(buff, length);
 
1853
      transaction_services.autocommitOrRollback(*session, false);
1813
1854
      session->endTransaction(COMMIT);
1814
1855
      session->close_thread_tables();
1815
 
      lex->reset_query_tables_list(false);
 
1856
      session->getLex()->reset_query_tables_list(false);
1816
1857
      table->table=0;                           // For query cache
1817
 
      if (session->client->flush())
 
1858
      if (session->getClient()->flush())
1818
1859
        goto err;
1819
1860
      continue;
1820
1861
    }
1826
1867
      const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1827
1868
                                                  "Waiting to get writelock");
1828
1869
      session->abortLock(table->table);
1829
 
      TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1870
      identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1830
1871
      table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1831
1872
      session->exit_cond(old_message);
1832
1873
      if (session->getKilled())
1838
1879
 
1839
1880
send_result:
1840
1881
 
1841
 
    lex->cleanup_after_one_table_open();
 
1882
    session->getLex()->cleanup_after_one_table_open();
1842
1883
    session->clear_error();  // these errors shouldn't get client
1843
1884
    {
1844
 
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
 
1885
      List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
1845
1886
      DRIZZLE_ERROR *err;
1846
1887
      while ((err= it++))
1847
1888
      {
1848
 
        session->client->store(table_name);
1849
 
        session->client->store(operator_name);
1850
 
        session->client->store(warning_level_names[err->level].str,
 
1889
        session->getClient()->store(table_name.c_str());
 
1890
        session->getClient()->store(operator_name);
 
1891
        session->getClient()->store(warning_level_names[err->level].str,
1851
1892
                               warning_level_names[err->level].length);
1852
 
        session->client->store(err->msg);
1853
 
        if (session->client->flush())
 
1893
        session->getClient()->store(err->msg);
 
1894
        if (session->getClient()->flush())
1854
1895
          goto err;
1855
1896
      }
1856
1897
      drizzle_reset_errors(session, true);
1857
1898
    }
1858
 
    session->client->store(table_name);
1859
 
    session->client->store(operator_name);
 
1899
    session->getClient()->store(table_name.c_str());
 
1900
    session->getClient()->store(operator_name);
1860
1901
 
1861
1902
    switch (result_code) {
1862
1903
    case HA_ADMIN_NOT_IMPLEMENTED:
1864
1905
        char buf[ERRMSGSIZE+20];
1865
1906
        uint32_t length=snprintf(buf, ERRMSGSIZE,
1866
1907
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
1867
 
        session->client->store(STRING_WITH_LEN("note"));
1868
 
        session->client->store(buf, length);
 
1908
        session->getClient()->store(STRING_WITH_LEN("note"));
 
1909
        session->getClient()->store(buf, length);
1869
1910
      }
1870
1911
      break;
1871
1912
 
1872
1913
    case HA_ADMIN_OK:
1873
 
      session->client->store(STRING_WITH_LEN("status"));
1874
 
      session->client->store(STRING_WITH_LEN("OK"));
 
1914
      session->getClient()->store(STRING_WITH_LEN("status"));
 
1915
      session->getClient()->store(STRING_WITH_LEN("OK"));
1875
1916
      break;
1876
1917
 
1877
1918
    case HA_ADMIN_FAILED:
1878
 
      session->client->store(STRING_WITH_LEN("status"));
1879
 
      session->client->store(STRING_WITH_LEN("Operation failed"));
 
1919
      session->getClient()->store(STRING_WITH_LEN("status"));
 
1920
      session->getClient()->store(STRING_WITH_LEN("Operation failed"));
1880
1921
      break;
1881
1922
 
1882
1923
    case HA_ADMIN_REJECT:
1883
 
      session->client->store(STRING_WITH_LEN("status"));
1884
 
      session->client->store(STRING_WITH_LEN("Operation need committed state"));
 
1924
      session->getClient()->store(STRING_WITH_LEN("status"));
 
1925
      session->getClient()->store(STRING_WITH_LEN("Operation need committed state"));
1885
1926
      open_for_modify= false;
1886
1927
      break;
1887
1928
 
1888
1929
    case HA_ADMIN_ALREADY_DONE:
1889
 
      session->client->store(STRING_WITH_LEN("status"));
1890
 
      session->client->store(STRING_WITH_LEN("Table is already up to date"));
 
1930
      session->getClient()->store(STRING_WITH_LEN("status"));
 
1931
      session->getClient()->store(STRING_WITH_LEN("Table is already up to date"));
1891
1932
      break;
1892
1933
 
1893
1934
    case HA_ADMIN_CORRUPT:
1894
 
      session->client->store(STRING_WITH_LEN("error"));
1895
 
      session->client->store(STRING_WITH_LEN("Corrupt"));
 
1935
      session->getClient()->store(STRING_WITH_LEN("error"));
 
1936
      session->getClient()->store(STRING_WITH_LEN("Corrupt"));
1896
1937
      fatal_error=1;
1897
1938
      break;
1898
1939
 
1899
1940
    case HA_ADMIN_INVALID:
1900
 
      session->client->store(STRING_WITH_LEN("error"));
1901
 
      session->client->store(STRING_WITH_LEN("Invalid argument"));
 
1941
      session->getClient()->store(STRING_WITH_LEN("error"));
 
1942
      session->getClient()->store(STRING_WITH_LEN("Invalid argument"));
1902
1943
      break;
1903
1944
 
1904
1945
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
1907
1948
        uint32_t length=snprintf(buf, ERRMSGSIZE,
1908
1949
                             _("Unknown - internal error %d during operation"),
1909
1950
                             result_code);
1910
 
        session->client->store(STRING_WITH_LEN("error"));
1911
 
        session->client->store(buf, length);
 
1951
        session->getClient()->store(STRING_WITH_LEN("error"));
 
1952
        session->getClient()->store(buf, length);
1912
1953
        fatal_error=1;
1913
1954
        break;
1914
1955
      }
1928
1969
        else
1929
1970
        {
1930
1971
          boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1931
 
          TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1972
          identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1932
1973
          table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1933
1974
        }
1934
1975
      }
1935
1976
    }
1936
 
    transaction_services.autocommitOrRollback(session, false);
 
1977
    transaction_services.autocommitOrRollback(*session, false);
1937
1978
    session->endTransaction(COMMIT);
1938
1979
    session->close_thread_tables();
1939
1980
    table->table=0;                             // For query cache
1940
 
    if (session->client->flush())
 
1981
    if (session->getClient()->flush())
1941
1982
      goto err;
1942
1983
  }
1943
1984
 
1945
1986
  return(false);
1946
1987
 
1947
1988
err:
1948
 
  transaction_services.autocommitOrRollback(session, true);
 
1989
  transaction_services.autocommitOrRollback(*session, true);
1949
1990
  session->endTransaction(ROLLBACK);
1950
1991
  session->close_thread_tables();                       // Shouldn't be needed
1951
1992
  if (table)
1968
2009
    during the call to plugin::StorageEngine::createTable().
1969
2010
    See bug #28614 for more info.
1970
2011
  */
1971
 
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
 
                                 const TableIdentifier &destination_identifier,
1973
 
                                 const TableIdentifier &src_table,
 
2012
static bool create_table_wrapper(Session &session,
 
2013
                                 const message::Table& create_table_proto,
 
2014
                                 identifier::Table::const_reference destination_identifier,
 
2015
                                 identifier::Table::const_reference source_identifier,
1974
2016
                                 bool is_engine_set)
1975
2017
{
1976
 
  int protoerr= EEXIST;
1977
 
  message::Table new_proto;
1978
 
  message::table::shared_ptr src_proto;
1979
 
 
1980
 
  protoerr= plugin::StorageEngine::getTableDefinition(session,
1981
 
                                                      src_table,
1982
 
                                                      src_proto);
1983
 
  new_proto.CopyFrom(*src_proto);
 
2018
  // We require an additional table message because during parsing we used
 
2019
  // a "new" message and it will not have all of the information that the
 
2020
  // source table message would have.
 
2021
  message::Table new_table_message;
 
2022
 
 
2023
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
 
2024
 
 
2025
  if (not source_table_message)
 
2026
  {
 
2027
    my_error(ER_TABLE_UNKNOWN, source_identifier);
 
2028
    return false;
 
2029
  }
 
2030
 
 
2031
  new_table_message.CopyFrom(*source_table_message);
1984
2032
 
1985
2033
  if (destination_identifier.isTmp())
1986
2034
  {
1987
 
    new_proto.set_type(message::Table::TEMPORARY);
 
2035
    new_table_message.set_type(message::Table::TEMPORARY);
1988
2036
  }
1989
2037
  else
1990
2038
  {
1991
 
    new_proto.set_type(message::Table::STANDARD);
 
2039
    new_table_message.set_type(message::Table::STANDARD);
1992
2040
  }
1993
2041
 
1994
2042
  if (is_engine_set)
1995
2043
  {
1996
 
    new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
 
2044
    new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
1997
2045
  }
1998
2046
 
1999
2047
  { // We now do a selective copy of elements on to the new table.
2000
 
    new_proto.set_name(create_table_proto.name());
2001
 
    new_proto.set_schema(create_table_proto.schema());
2002
 
    new_proto.set_catalog(create_table_proto.catalog());
 
2048
    new_table_message.set_name(create_table_proto.name());
 
2049
    new_table_message.set_schema(create_table_proto.schema());
 
2050
    new_table_message.set_catalog(create_table_proto.catalog());
2003
2051
  }
2004
2052
 
2005
 
  if (protoerr && protoerr != EEXIST)
 
2053
  /* Fix names of foreign keys being added */
 
2054
  for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
2006
2055
  {
2007
 
    if (errno == ENOENT)
2008
 
      my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
2009
 
    else
2010
 
      my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
2011
 
 
2012
 
    return false;
 
2056
    if (new_table_message.fk_constraint(j).has_name())
 
2057
    {
 
2058
      std::string name(new_table_message.name());
 
2059
      char number[20];
 
2060
 
 
2061
      name.append("_ibfk_");
 
2062
      snprintf(number, sizeof(number), "%d", j+1);
 
2063
      name.append(number);
 
2064
 
 
2065
      message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
 
2066
      pfkey->set_name(name);
 
2067
    }
2013
2068
  }
2014
2069
 
2015
2070
  /*
2016
2071
    As mysql_truncate don't work on a new table at this stage of
2017
 
    creation, instead create the table directly (for both normal
2018
 
    and temporary tables).
 
2072
    creation, instead create the table directly (for both normal and temporary tables).
2019
2073
  */
2020
 
  int err= plugin::StorageEngine::createTable(session,
2021
 
                                              destination_identifier,
2022
 
                                              new_proto);
 
2074
  bool success= plugin::StorageEngine::createTable(session,
 
2075
                                                   destination_identifier,
 
2076
                                                   new_table_message);
2023
2077
 
2024
 
  if (err == false && not destination_identifier.isTmp())
 
2078
  if (success && not destination_identifier.isTmp())
2025
2079
  {
2026
2080
    TransactionServices &transaction_services= TransactionServices::singleton();
2027
 
    transaction_services.createTable(&session, new_proto);
 
2081
    transaction_services.createTable(session, new_table_message);
2028
2082
  }
2029
2083
 
2030
 
  return err ? false : true;
 
2084
  return success;
2031
2085
}
2032
2086
 
2033
2087
/*
2034
2088
  Create a table identical to the specified table
2035
2089
 
2036
2090
  SYNOPSIS
2037
 
    mysql_create_like_table()
 
2091
    create_like_table()
2038
2092
    session             Thread object
2039
2093
    table       Table list element for target table
2040
2094
    src_table   Table list element for source table
2045
2099
    true  error
2046
2100
*/
2047
2101
 
2048
 
bool mysql_create_like_table(Session* session,
2049
 
                             const TableIdentifier &destination_identifier,
2050
 
                             TableList* table, TableList* src_table,
2051
 
                             message::Table &create_table_proto,
2052
 
                             bool is_if_not_exists,
2053
 
                             bool is_engine_set)
 
2102
bool create_like_table(Session* session,
 
2103
                       identifier::Table::const_reference destination_identifier,
 
2104
                       identifier::Table::const_reference source_identifier,
 
2105
                       message::Table &create_table_proto,
 
2106
                       bool is_if_not_exists,
 
2107
                       bool is_engine_set)
2054
2108
{
2055
2109
  bool res= true;
2056
 
  uint32_t not_used;
2057
 
 
2058
 
  /*
2059
 
    By opening source table we guarantee that it exists and no concurrent
2060
 
    DDL operation will mess with it. Later we also take an exclusive
2061
 
    name-lock on target table name, which makes copying of .frm cursor,
2062
 
    call to plugin::StorageEngine::createTable() and binlogging atomic
2063
 
    against concurrent DML and DDL operations on target table.
2064
 
    Thus by holding both these "locks" we ensure that our statement is
2065
 
    properly isolated from all concurrent operations which matter.
2066
 
  */
2067
 
  if (session->open_tables_from_list(&src_table, &not_used))
2068
 
    return true;
2069
 
 
2070
 
  TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2071
 
                                 src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2072
 
 
2073
 
 
 
2110
  bool table_exists= false;
2074
2111
 
2075
2112
  /*
2076
2113
    Check that destination tables does not exist. Note that its name
2078
2115
 
2079
2116
    For temporary tables we don't aim to grab locks.
2080
2117
  */
2081
 
  bool table_exists= false;
2082
2118
  if (destination_identifier.isTmp())
2083
2119
  {
2084
2120
    if (session->find_temporary_table(destination_identifier))
2087
2123
    }
2088
2124
    else
2089
2125
    {
2090
 
      bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2091
 
                                             src_identifier, is_engine_set);
 
2126
      bool was_created= create_table_wrapper(*session,
 
2127
                                             create_table_proto,
 
2128
                                             destination_identifier,
 
2129
                                             source_identifier,
 
2130
                                             is_engine_set);
2092
2131
      if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2093
2132
      {
2094
2133
        (void) session->rm_temporary_table(destination_identifier, true);
2133
2172
      {
2134
2173
        boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2135
2174
        was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2136
 
                                               src_identifier, is_engine_set);
 
2175
                                          source_identifier, is_engine_set);
2137
2176
      }
2138
2177
 
2139
2178
      // So we blew the creation of the table, and we scramble to clean up
2161
2200
    {
2162
2201
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
2163
2202
      snprintf(warn_buff, sizeof(warn_buff),
2164
 
               ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
 
2203
               ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2165
2204
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2166
 
                   ER_TABLE_EXISTS_ERROR,warn_buff);
2167
 
      res= false;
2168
 
    }
2169
 
    else
2170
 
    {
2171
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2172
 
    }
 
2205
                   ER_TABLE_EXISTS_ERROR, warn_buff);
 
2206
      return false;
 
2207
    }
 
2208
 
 
2209
    my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
 
2210
 
 
2211
    return true;
2173
2212
  }
2174
2213
 
2175
 
  return(res);
 
2214
  return res;
2176
2215
}
2177
2216
 
2178
2217
 
2179
 
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
 
2218
bool analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2180
2219
{
2181
2220
  thr_lock_type lock_type = TL_READ_NO_INSERT;
2182
2221
 
2183
 
  return(mysql_admin_table(session, tables, check_opt,
 
2222
  return(admin_table(session, tables, check_opt,
2184
2223
                                "analyze", lock_type, true,
2185
2224
                                &Cursor::ha_analyze));
2186
2225
}
2187
2226
 
2188
2227
 
2189
 
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
 
2228
bool check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2190
2229
{
2191
2230
  thr_lock_type lock_type = TL_READ_NO_INSERT;
2192
2231
 
2193
 
  return(mysql_admin_table(session, tables, check_opt,
 
2232
  return(admin_table(session, tables, check_opt,
2194
2233
                                "check", lock_type,
2195
2234
                                false,
2196
2235
                                &Cursor::ha_check));