~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

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