~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

few updates and modifications to admin commands

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