~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2010-12-25 00:28:49 UTC
  • mto: This revision was merged to the branch mainline in revision 2031.
  • Revision ID: brian@tangent.org-20101225002849-g73mg6ihulajis0o
First pass in refactoring of the name of my_decimal.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
#include "drizzled/statement/alter_table.h"
48
48
#include "drizzled/sql_table.h"
49
49
#include "drizzled/pthread_globals.h"
50
 
#include "drizzled/plugin/storage_engine.h"
51
50
 
52
51
#include <algorithm>
53
52
#include <sstream>
59
58
namespace drizzled
60
59
{
61
60
 
 
61
extern pid_t current_pid;
 
62
 
62
63
bool is_primary_key(KeyInfo *key_info)
63
64
{
64
65
  static const char * primary_key_name="PRIMARY";
86
87
    let's fetch the database default character set and
87
88
    apply it to the table.
88
89
  */
89
 
  identifier::Schema identifier(db);
 
90
  SchemaIdentifier identifier(db);
90
91
  if (create_info->default_table_charset == NULL)
91
92
    create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(identifier);
92
93
}
109
110
void write_bin_log(Session *session, const std::string &query)
110
111
{
111
112
  TransactionServices &transaction_services= TransactionServices::singleton();
112
 
  transaction_services.rawStatement(*session, query);
 
113
  transaction_services.rawStatement(session, query);
113
114
}
114
115
 
115
116
/*
140
141
*/
141
142
 
142
143
int rm_table_part2(Session *session, TableList *tables, bool if_exists,
143
 
                   bool drop_temporary)
 
144
                         bool drop_temporary)
144
145
{
145
146
  TableList *table;
146
147
  String wrong_tables;
147
148
  int error= 0;
148
149
  bool foreign_key_error= false;
149
150
 
150
 
  do
151
151
  {
152
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
 
152
    table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
153
153
 
154
154
    if (not drop_temporary && session->lock_table_names_exclusively(tables))
155
155
    {
 
156
      table::Cache::singleton().mutex().unlock();
156
157
      return 1;
157
158
    }
158
159
 
161
162
 
162
163
    for (table= tables; table; table= table->next_local)
163
164
    {
164
 
      identifier::Table tmp_identifier(table->getSchemaName(), table->getTableName());
 
165
      TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
165
166
 
166
167
      error= session->drop_temporary_table(tmp_identifier);
167
168
 
171
172
        continue;
172
173
      case -1:
173
174
        error= 1;
174
 
        break;
 
175
        goto err_with_placeholders;
175
176
      default:
176
177
        // temporary table not found
177
178
        error= 0;
194
195
        if (session->getKilled())
195
196
        {
196
197
          error= -1;
197
 
          break;
 
198
          goto err_with_placeholders;
198
199
        }
199
200
      }
200
 
      identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
 
201
      TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
201
202
 
202
203
      if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
203
204
      {
207
208
                              ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
208
209
                              table->getTableName());
209
210
        else
210
 
        {
211
211
          error= 1;
212
 
        }
213
212
      }
214
213
      else
215
214
      {
216
 
        drizzled::error_t local_error;
 
215
        error= plugin::StorageEngine::dropTable(*session, identifier);
217
216
 
218
217
        /* Generate transaction event ONLY when we successfully drop */ 
219
 
        if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
 
218
        if (error == 0)
220
219
        {
221
220
          TransactionServices &transaction_services= TransactionServices::singleton();
222
 
          transaction_services.dropTable(*session, identifier, if_exists);
223
 
        }
224
 
        else
225
 
        {
226
 
          if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists)
227
 
          {
228
 
            error= 0;
229
 
            session->clear_error();
230
 
          }
231
 
 
232
 
          if (local_error == HA_ERR_ROW_IS_REFERENCED)
233
 
          {
234
 
            /* the table is referenced by a foreign key constraint */
235
 
            foreign_key_error= true;
236
 
          }
237
 
          error= local_error;
 
221
          transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()));
 
222
        }
 
223
 
 
224
        if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
 
225
        {
 
226
          error= 0;
 
227
          session->clear_error();
 
228
        }
 
229
 
 
230
        if (error == HA_ERR_ROW_IS_REFERENCED)
 
231
        {
 
232
          /* the table is referenced by a foreign key constraint */
 
233
          foreign_key_error= true;
238
234
        }
239
235
      }
240
236
 
245
241
        wrong_tables.append(String(table->getTableName(), system_charset_info));
246
242
      }
247
243
    }
248
 
 
249
 
    tables->unlock_table_names();
250
 
 
251
 
  } while (0);
 
244
    /*
 
245
      It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
 
246
      on the table name.
 
247
    */
 
248
    table::Cache::singleton().mutex().unlock();
 
249
  }
 
250
  error= 0;
252
251
 
253
252
  if (wrong_tables.length())
254
253
  {
264
263
    error= 1;
265
264
  }
266
265
 
 
266
  table::Cache::singleton().mutex().lock(); /* final bit in rm table lock */
 
267
 
 
268
err_with_placeholders:
 
269
  tables->unlock_table_names();
 
270
  table::Cache::singleton().mutex().unlock();
267
271
  session->no_warnings_for_error= 0;
268
272
 
269
273
  return error;
468
472
    sql_field->length= 8; // Unireg field length
469
473
    (*blob_columns)++;
470
474
    break;
471
 
 
 
475
  case DRIZZLE_TYPE_VARCHAR:
 
476
    break;
472
477
  case DRIZZLE_TYPE_ENUM:
473
 
    {
474
 
      if (check_duplicates_in_interval("ENUM",
475
 
                                       sql_field->field_name,
476
 
                                       sql_field->interval,
477
 
                                       sql_field->charset,
478
 
                                       &dup_val_count))
479
 
      {
480
 
        return 1;
481
 
      }
482
 
    }
483
 
    break;
484
 
 
485
 
  case DRIZZLE_TYPE_MICROTIME:
 
478
    if (check_duplicates_in_interval("ENUM",
 
479
                                     sql_field->field_name,
 
480
                                     sql_field->interval,
 
481
                                     sql_field->charset,
 
482
                                     &dup_val_count))
 
483
      return 1;
 
484
    break;
 
485
  case DRIZZLE_TYPE_DATE:  // Rest of string types
 
486
  case DRIZZLE_TYPE_TIME:
 
487
  case DRIZZLE_TYPE_DATETIME:
 
488
  case DRIZZLE_TYPE_NULL:
 
489
    break;
 
490
  case DRIZZLE_TYPE_DECIMAL:
 
491
    break;
486
492
  case DRIZZLE_TYPE_TIMESTAMP:
487
493
    /* We should replace old TIMESTAMP fields with their newer analogs */
488
494
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
498
504
      }
499
505
    }
500
506
    else if (sql_field->unireg_check != Field::NONE)
501
 
    {
502
507
      (*timestamps_with_niladic)++;
503
 
    }
504
508
 
505
509
    (*timestamps)++;
506
 
 
507
 
    break;
508
 
 
509
 
  case DRIZZLE_TYPE_BOOLEAN:
510
 
  case DRIZZLE_TYPE_DATE:  // Rest of string types
511
 
  case DRIZZLE_TYPE_DATETIME:
512
 
  case DRIZZLE_TYPE_DECIMAL:
513
 
  case DRIZZLE_TYPE_DOUBLE:
514
 
  case DRIZZLE_TYPE_LONG:
515
 
  case DRIZZLE_TYPE_LONGLONG:
516
 
  case DRIZZLE_TYPE_NULL:
517
 
  case DRIZZLE_TYPE_TIME:
518
 
  case DRIZZLE_TYPE_UUID:
519
 
  case DRIZZLE_TYPE_VARCHAR:
 
510
    /* fall-through */
 
511
  default:
520
512
    break;
521
513
  }
522
514
 
524
516
}
525
517
 
526
518
static int prepare_create_table(Session *session,
527
 
                                HA_CREATE_INFO *create_info,
528
 
                                message::Table &create_proto,
529
 
                                AlterInfo *alter_info,
530
 
                                bool tmp_table,
531
 
                                uint32_t *db_options,
532
 
                                KeyInfo **key_info_buffer,
533
 
                                uint32_t *key_count,
534
 
                                int select_field_count)
 
519
                                      HA_CREATE_INFO *create_info,
 
520
                                      message::Table &create_proto,
 
521
                                      AlterInfo *alter_info,
 
522
                                      bool tmp_table,
 
523
                                      uint32_t *db_options,
 
524
                                      KeyInfo **key_info_buffer,
 
525
                                      uint32_t *key_count,
 
526
                                      int select_field_count)
535
527
{
536
528
  const char    *key_name;
537
529
  CreateField   *sql_field,*dup_field;
540
532
  KeyInfo               *key_info;
541
533
  KeyPartInfo *key_part_info;
542
534
  int           timestamps= 0, timestamps_with_niladic= 0;
543
 
  int           dup_no;
 
535
  int           field_no,dup_no;
544
536
  int           select_field_pos,auto_increment=0;
545
537
  List_iterator<CreateField> it(alter_info->create_list);
546
538
  List_iterator<CreateField> it2(alter_info->create_list);
552
544
  null_fields=blob_columns=0;
553
545
  max_key_length= engine->max_key_length();
554
546
 
555
 
  for (int32_t field_no=0; (sql_field=it++) ; field_no++)
 
547
  for (field_no=0; (sql_field=it++) ; field_no++)
556
548
  {
557
549
    const CHARSET_INFO *save_cs;
558
550
 
562
554
      executing a prepared statement for the second time.
563
555
    */
564
556
    sql_field->length= sql_field->char_length;
565
 
 
566
557
    if (!sql_field->charset)
567
558
      sql_field->charset= create_info->default_table_charset;
568
 
 
569
559
    /*
570
560
      table_charset is set in ALTER Table if we want change character set
571
561
      for all varchar/char columns.
763
753
    if (not create_proto.engine().name().compare("MyISAM") &&
764
754
        ((sql_field->flags & BLOB_FLAG) ||
765
755
         (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)))
766
 
    {
767
756
      (*db_options)|= HA_OPTION_PACK_RECORD;
768
 
    }
769
 
 
770
757
    it2.rewind();
771
758
  }
772
759
 
990
977
             my_strcasecmp(system_charset_info,
991
978
                           column->field_name.str,
992
979
                           sql_field->field_name))
993
 
      {
994
980
        field++;
995
 
      }
996
 
 
997
981
      if (!sql_field)
998
982
      {
999
983
        my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
1000
984
        return(true);
1001
985
      }
1002
 
 
1003
986
      while ((dup_column= cols2++) != column)
1004
987
      {
1005
988
        if (!my_strcasecmp(system_charset_info,
1032
1015
            return true;
1033
1016
          }
1034
1017
        }
1035
 
 
1036
1018
        if (! (sql_field->flags & NOT_NULL_FLAG))
1037
1019
        {
1038
1020
          if (key->type == Key::PRIMARY)
1045
1027
            {
1046
1028
              message::Table::Field::FieldConstraints *constraints;
1047
1029
              constraints= protofield->mutable_constraints();
1048
 
              constraints->set_is_notnull(true);
 
1030
              constraints->set_is_nullable(false);
1049
1031
            }
1050
1032
 
1051
1033
          }
1059
1041
            }
1060
1042
          }
1061
1043
        }
1062
 
 
1063
1044
        if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1064
1045
        {
1065
1046
          if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1184
1165
        key_info->name=(char*) key_name;
1185
1166
      }
1186
1167
    }
1187
 
 
1188
1168
    if (!key_info->name || check_column_name(key_info->name))
1189
1169
    {
1190
1170
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1191
1171
      return(true);
1192
1172
    }
1193
 
 
1194
1173
    if (!(key_info->flags & HA_NULL_PART_KEY))
1195
 
    {
1196
1174
      unique_key=1;
1197
 
    }
1198
 
 
1199
1175
    key_info->key_length=(uint16_t) key_length;
1200
 
 
1201
1176
    if (key_length > max_key_length)
1202
1177
    {
1203
1178
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1204
1179
      return(true);
1205
1180
    }
1206
 
 
1207
1181
    key_info++;
1208
1182
  }
1209
 
 
1210
1183
  if (!unique_key && !primary_key &&
1211
1184
      (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1212
1185
  {
1213
1186
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1214
1187
    return(true);
1215
1188
  }
1216
 
 
1217
1189
  if (auto_increment > 0)
1218
1190
  {
1219
1191
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1295
1267
}
1296
1268
 
1297
1269
static bool locked_create_event(Session *session,
1298
 
                                const identifier::Table &identifier,
 
1270
                                const TableIdentifier &identifier,
1299
1271
                                HA_CREATE_INFO *create_info,
1300
1272
                                message::Table &table_proto,
1301
1273
                                AlterInfo *alter_info,
1330
1302
        return error;
1331
1303
      }
1332
1304
 
1333
 
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1305
      std::string path;
 
1306
      identifier.getSQLPath(path);
 
1307
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1334
1308
 
1335
1309
      return error;
1336
1310
    }
1350
1324
      */
1351
1325
      if (definition::Cache::singleton().find(identifier.getKey()))
1352
1326
      {
1353
 
        my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1327
        std::string path;
 
1328
        identifier.getSQLPath(path);
 
1329
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1354
1330
 
1355
1331
        return error;
1356
1332
      }
1389
1365
  if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1390
1366
  {
1391
1367
    TransactionServices &transaction_services= TransactionServices::singleton();
1392
 
    transaction_services.createTable(*session, table_proto);
 
1368
    transaction_services.createTable(session, table_proto);
1393
1369
  }
1394
1370
 
1395
1371
  return false;
1427
1403
*/
1428
1404
 
1429
1405
bool create_table_no_lock(Session *session,
1430
 
                                const identifier::Table &identifier,
 
1406
                                const TableIdentifier &identifier,
1431
1407
                                HA_CREATE_INFO *create_info,
1432
1408
                                message::Table &table_proto,
1433
1409
                                AlterInfo *alter_info,
1453
1429
 
1454
1430
  /* Build a Table object to pass down to the engine, and the do the actual create. */
1455
1431
  if (not prepare_create_table(session, create_info, table_proto, alter_info,
1456
 
                               internal_tmp_table,
1457
 
                               &db_options,
1458
 
                               &key_info_buffer, &key_count,
1459
 
                               select_field_count))
 
1432
                                     internal_tmp_table,
 
1433
                                     &db_options,
 
1434
                                     &key_info_buffer, &key_count,
 
1435
                                     select_field_count))
1460
1436
  {
1461
1437
    boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1462
1438
    error= locked_create_event(session,
1479
1455
  @note the following two methods implement create [temporary] table.
1480
1456
*/
1481
1457
static bool drizzle_create_table(Session *session,
1482
 
                                 const identifier::Table &identifier,
 
1458
                                 const TableIdentifier &identifier,
1483
1459
                                 HA_CREATE_INFO *create_info,
1484
1460
                                 message::Table &table_proto,
1485
1461
                                 AlterInfo *alter_info,
1506
1482
    }
1507
1483
    else
1508
1484
    {
1509
 
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1485
      std::string path;
 
1486
      identifier.getSQLPath(path);
 
1487
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1510
1488
      result= true;
1511
1489
    }
1512
1490
  }
1536
1514
  Database locking aware wrapper for create_table_no_lock(),
1537
1515
*/
1538
1516
bool create_table(Session *session,
1539
 
                        const identifier::Table &identifier,
 
1517
                        const TableIdentifier &identifier,
1540
1518
                        HA_CREATE_INFO *create_info,
1541
1519
                        message::Table &table_proto,
1542
1520
                        AlterInfo *alter_info,
1632
1610
bool
1633
1611
rename_table(Session &session,
1634
1612
                   plugin::StorageEngine *base,
1635
 
                   const identifier::Table &from,
1636
 
                   const identifier::Table &to)
 
1613
                   const TableIdentifier &from,
 
1614
                   const TableIdentifier &to)
1637
1615
{
1638
1616
  int error= 0;
1639
1617
 
1699
1677
  session->abortLock(table);    /* end threads waiting on lock */
1700
1678
 
1701
1679
  /* Wait until all there are no other threads that has this table open */
1702
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
 
1680
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1703
1681
  table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1704
1682
}
1705
1683
 
1833
1811
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1834
1812
                       table_name);
1835
1813
      session->getClient()->store(buff, length);
1836
 
      transaction_services.autocommitOrRollback(*session, false);
 
1814
      transaction_services.autocommitOrRollback(session, false);
1837
1815
      session->endTransaction(COMMIT);
1838
1816
      session->close_thread_tables();
1839
1817
      lex->reset_query_tables_list(false);
1850
1828
      const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1851
1829
                                                  "Waiting to get writelock");
1852
1830
      session->abortLock(table->table);
1853
 
      identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1831
      TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1854
1832
      table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1855
1833
      session->exit_cond(old_message);
1856
1834
      if (session->getKilled())
1952
1930
        else
1953
1931
        {
1954
1932
          boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1955
 
          identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1933
          TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1956
1934
          table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1957
1935
        }
1958
1936
      }
1959
1937
    }
1960
 
    transaction_services.autocommitOrRollback(*session, false);
 
1938
    transaction_services.autocommitOrRollback(session, false);
1961
1939
    session->endTransaction(COMMIT);
1962
1940
    session->close_thread_tables();
1963
1941
    table->table=0;                             // For query cache
1969
1947
  return(false);
1970
1948
 
1971
1949
err:
1972
 
  transaction_services.autocommitOrRollback(*session, true);
 
1950
  transaction_services.autocommitOrRollback(session, true);
1973
1951
  session->endTransaction(ROLLBACK);
1974
1952
  session->close_thread_tables();                       // Shouldn't be needed
1975
1953
  if (table)
1992
1970
    during the call to plugin::StorageEngine::createTable().
1993
1971
    See bug #28614 for more info.
1994
1972
  */
1995
 
static bool create_table_wrapper(Session &session,
1996
 
                                 const message::Table& create_table_proto,
1997
 
                                 identifier::Table::const_reference destination_identifier,
1998
 
                                 identifier::Table::const_reference source_identifier,
 
1973
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
 
1974
                                 const TableIdentifier &destination_identifier,
 
1975
                                 const TableIdentifier &src_table,
1999
1976
                                 bool is_engine_set)
2000
1977
{
2001
 
  // We require an additional table message because during parsing we used
2002
 
  // a "new" message and it will not have all of the information that the
2003
 
  // source table message would have.
2004
 
  message::Table new_table_message;
2005
 
  drizzled::error_t error;
2006
 
 
2007
 
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier, error);
2008
 
 
2009
 
  if (not source_table_message)
2010
 
  {
2011
 
    my_error(ER_TABLE_UNKNOWN, source_identifier);
2012
 
    return false;
2013
 
  }
2014
 
 
2015
 
  new_table_message.CopyFrom(*source_table_message);
 
1978
  int protoerr= EEXIST;
 
1979
  message::Table new_proto;
 
1980
  message::table::shared_ptr src_proto;
 
1981
 
 
1982
  protoerr= plugin::StorageEngine::getTableDefinition(session,
 
1983
                                                      src_table,
 
1984
                                                      src_proto);
 
1985
  new_proto.CopyFrom(*src_proto);
2016
1986
 
2017
1987
  if (destination_identifier.isTmp())
2018
1988
  {
2019
 
    new_table_message.set_type(message::Table::TEMPORARY);
 
1989
    new_proto.set_type(message::Table::TEMPORARY);
2020
1990
  }
2021
1991
  else
2022
1992
  {
2023
 
    new_table_message.set_type(message::Table::STANDARD);
 
1993
    new_proto.set_type(message::Table::STANDARD);
2024
1994
  }
2025
1995
 
2026
1996
  if (is_engine_set)
2027
1997
  {
2028
 
    new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
 
1998
    new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
2029
1999
  }
2030
2000
 
2031
2001
  { // We now do a selective copy of elements on to the new table.
2032
 
    new_table_message.set_name(create_table_proto.name());
2033
 
    new_table_message.set_schema(create_table_proto.schema());
2034
 
    new_table_message.set_catalog(create_table_proto.catalog());
 
2002
    new_proto.set_name(create_table_proto.name());
 
2003
    new_proto.set_schema(create_table_proto.schema());
 
2004
    new_proto.set_catalog(create_table_proto.catalog());
2035
2005
  }
2036
2006
 
2037
 
  /* Fix names of foreign keys being added */
2038
 
  for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
 
2007
  if (protoerr && protoerr != EEXIST)
2039
2008
  {
2040
 
    if (new_table_message.fk_constraint(j).has_name())
2041
 
    {
2042
 
      std::string name(new_table_message.name());
2043
 
      char number[20];
2044
 
 
2045
 
      name.append("_ibfk_");
2046
 
      snprintf(number, sizeof(number), "%d", j+1);
2047
 
      name.append(number);
2048
 
 
2049
 
      message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
2050
 
      pfkey->set_name(name);
2051
 
    }
 
2009
    if (errno == ENOENT)
 
2010
      my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
 
2011
    else
 
2012
      my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
 
2013
 
 
2014
    return false;
2052
2015
  }
2053
2016
 
2054
2017
  /*
2055
2018
    As mysql_truncate don't work on a new table at this stage of
2056
 
    creation, instead create the table directly (for both normal and temporary tables).
 
2019
    creation, instead create the table directly (for both normal
 
2020
    and temporary tables).
2057
2021
  */
2058
 
  bool success= plugin::StorageEngine::createTable(session,
2059
 
                                                   destination_identifier,
2060
 
                                                   new_table_message);
 
2022
  int err= plugin::StorageEngine::createTable(session,
 
2023
                                              destination_identifier,
 
2024
                                              new_proto);
2061
2025
 
2062
 
  if (success && not destination_identifier.isTmp())
 
2026
  if (err == false && not destination_identifier.isTmp())
2063
2027
  {
2064
2028
    TransactionServices &transaction_services= TransactionServices::singleton();
2065
 
    transaction_services.createTable(session, new_table_message);
 
2029
    transaction_services.createTable(&session, new_proto);
2066
2030
  }
2067
2031
 
2068
 
  return success;
 
2032
  return err ? false : true;
2069
2033
}
2070
2034
 
2071
2035
/*
2084
2048
*/
2085
2049
 
2086
2050
bool create_like_table(Session* session,
2087
 
                       identifier::Table::const_reference destination_identifier,
2088
 
                       identifier::Table::const_reference source_identifier,
2089
 
                       message::Table &create_table_proto,
2090
 
                       bool is_if_not_exists,
2091
 
                       bool is_engine_set)
 
2051
                             const TableIdentifier &destination_identifier,
 
2052
                             TableList* table, TableList* src_table,
 
2053
                             message::Table &create_table_proto,
 
2054
                             bool is_if_not_exists,
 
2055
                             bool is_engine_set)
2092
2056
{
2093
2057
  bool res= true;
2094
 
  bool table_exists= false;
 
2058
  uint32_t not_used;
 
2059
 
 
2060
  /*
 
2061
    By opening source table we guarantee that it exists and no concurrent
 
2062
    DDL operation will mess with it. Later we also take an exclusive
 
2063
    name-lock on target table name, which makes copying of .frm cursor,
 
2064
    call to plugin::StorageEngine::createTable() and binlogging atomic
 
2065
    against concurrent DML and DDL operations on target table.
 
2066
    Thus by holding both these "locks" we ensure that our statement is
 
2067
    properly isolated from all concurrent operations which matter.
 
2068
  */
 
2069
  if (session->open_tables_from_list(&src_table, &not_used))
 
2070
    return true;
 
2071
 
 
2072
  TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
 
2073
                                 src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
 
2074
 
 
2075
 
2095
2076
 
2096
2077
  /*
2097
2078
    Check that destination tables does not exist. Note that its name
2099
2080
 
2100
2081
    For temporary tables we don't aim to grab locks.
2101
2082
  */
 
2083
  bool table_exists= false;
2102
2084
  if (destination_identifier.isTmp())
2103
2085
  {
2104
2086
    if (session->find_temporary_table(destination_identifier))
2107
2089
    }
2108
2090
    else
2109
2091
    {
2110
 
      bool was_created= create_table_wrapper(*session,
2111
 
                                             create_table_proto,
2112
 
                                             destination_identifier,
2113
 
                                             source_identifier,
2114
 
                                             is_engine_set);
 
2092
      bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
 
2093
                                             src_identifier, is_engine_set);
2115
2094
      if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2116
2095
      {
2117
2096
        (void) session->rm_temporary_table(destination_identifier, true);
2156
2135
      {
2157
2136
        boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2158
2137
        was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2159
 
                                          source_identifier, is_engine_set);
 
2138
                                               src_identifier, is_engine_set);
2160
2139
      }
2161
2140
 
2162
2141
      // So we blew the creation of the table, and we scramble to clean up
2184
2163
    {
2185
2164
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
2186
2165
      snprintf(warn_buff, sizeof(warn_buff),
2187
 
               ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
 
2166
               ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2188
2167
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2189
 
                   ER_TABLE_EXISTS_ERROR, warn_buff);
2190
 
      return false;
2191
 
    }
2192
 
 
2193
 
    my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2194
 
 
2195
 
    return true;
 
2168
                   ER_TABLE_EXISTS_ERROR,warn_buff);
 
2169
      res= false;
 
2170
    }
 
2171
    else
 
2172
    {
 
2173
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
 
2174
    }
2196
2175
  }
2197
2176
 
2198
 
  return res;
 
2177
  return(res);
2199
2178
}
2200
2179
 
2201
2180