~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2010-10-07 20:00:40 UTC
  • mto: (1822.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1823.
  • Revision ID: brian@tangent.org-20101007200040-st5l46s5i445vxoz
We no longer needed to look at the share when removing tables.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include "drizzled/global_charset_info.h"
42
42
#include "drizzled/charset.h"
43
43
 
44
 
#include "drizzled/definition/cache.h"
45
 
 
46
44
 
47
45
#include "drizzled/statement/alter_table.h"
48
46
#include "drizzled/sql_table.h"
107
105
    cursor
108
106
*/
109
107
 
110
 
void write_bin_log(Session *session, const std::string &query)
 
108
void write_bin_log(Session *session,
 
109
                   char const *query)
111
110
{
112
111
  TransactionServices &transaction_services= TransactionServices::singleton();
113
112
  transaction_services.rawStatement(session, query);
148
147
  int error= 0;
149
148
  bool foreign_key_error= false;
150
149
 
151
 
  {
152
 
    table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
153
 
 
154
 
    if (not drop_temporary && session->lock_table_names_exclusively(tables))
155
 
    {
156
 
      table::Cache::singleton().mutex().unlock();
157
 
      return 1;
158
 
    }
159
 
 
160
 
    /* Don't give warnings for not found errors, as we already generate notes */
161
 
    session->no_warnings_for_error= 1;
162
 
 
163
 
    for (table= tables; table; table= table->next_local)
164
 
    {
165
 
      TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
166
 
 
167
 
      error= session->drop_temporary_table(tmp_identifier);
168
 
 
169
 
      switch (error) {
170
 
      case  0:
171
 
        // removed temporary table
172
 
        continue;
173
 
      case -1:
 
150
  LOCK_open.lock(); /* Part 2 of rm a table */
 
151
 
 
152
  if (not drop_temporary && lock_table_names_exclusively(session, tables))
 
153
  {
 
154
    LOCK_open.unlock();
 
155
    return 1;
 
156
  }
 
157
 
 
158
  /* Don't give warnings for not found errors, as we already generate notes */
 
159
  session->no_warnings_for_error= 1;
 
160
 
 
161
  for (table= tables; table; table= table->next_local)
 
162
  {
 
163
    char *db=table->db;
 
164
 
 
165
    error= session->drop_temporary_table(table);
 
166
 
 
167
    switch (error) {
 
168
    case  0:
 
169
      // removed temporary table
 
170
      continue;
 
171
    case -1:
 
172
      error= 1;
 
173
      goto err_with_placeholders;
 
174
    default:
 
175
      // temporary table not found
 
176
      error= 0;
 
177
    }
 
178
 
 
179
    if (drop_temporary == false)
 
180
    {
 
181
      Table *locked_table;
 
182
      TableIdentifier identifier(db, table->table_name);
 
183
      abort_locked_tables(session, identifier);
 
184
      remove_table_from_cache(session, identifier,
 
185
                              RTFC_WAIT_OTHER_THREAD_FLAG |
 
186
                              RTFC_CHECK_KILLED_FLAG);
 
187
      /*
 
188
        If the table was used in lock tables, remember it so that
 
189
        unlock_table_names can free it
 
190
      */
 
191
      if ((locked_table= drop_locked_tables(session, identifier)))
 
192
        table->table= locked_table;
 
193
 
 
194
      if (session->killed)
 
195
      {
 
196
        error= -1;
 
197
        goto err_with_placeholders;
 
198
      }
 
199
    }
 
200
    TableIdentifier identifier(db, table->table_name, table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
 
201
 
 
202
    if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
 
203
    {
 
204
      // Table was not found on disk and table can't be created from engine
 
205
      if (if_exists)
 
206
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
207
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 
208
                            table->table_name);
 
209
      else
174
210
        error= 1;
175
 
        goto err_with_placeholders;
176
 
      default:
177
 
        // temporary table not found
 
211
    }
 
212
    else
 
213
    {
 
214
      error= plugin::StorageEngine::dropTable(*session, identifier);
 
215
 
 
216
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
 
217
      {
178
218
        error= 0;
179
 
      }
180
 
 
181
 
      if (drop_temporary == false)
182
 
      {
183
 
        Table *locked_table;
184
 
        abort_locked_tables(session, tmp_identifier);
185
 
        table::Cache::singleton().removeTable(session, tmp_identifier,
186
 
                                              RTFC_WAIT_OTHER_THREAD_FLAG |
187
 
                                              RTFC_CHECK_KILLED_FLAG);
188
 
        /*
189
 
          If the table was used in lock tables, remember it so that
190
 
          unlock_table_names can free it
191
 
        */
192
 
        if ((locked_table= drop_locked_tables(session, tmp_identifier)))
193
 
          table->table= locked_table;
194
 
 
195
 
        if (session->getKilled())
196
 
        {
197
 
          error= -1;
198
 
          goto err_with_placeholders;
199
 
        }
200
 
      }
201
 
      TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
202
 
 
203
 
      if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
 
      {
205
 
        // Table was not found on disk and table can't be created from engine
206
 
        if (if_exists)
207
 
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
 
                              ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
 
                              table->getTableName());
210
 
        else
211
 
          error= 1;
212
 
      }
213
 
      else
214
 
      {
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);
234
 
      }
235
 
 
236
 
      if (error)
237
 
      {
238
 
        if (wrong_tables.length())
239
 
          wrong_tables.append(',');
240
 
        wrong_tables.append(String(table->getTableName(), system_charset_info));
241
 
      }
242
 
    }
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();
 
219
        session->clear_error();
 
220
      }
 
221
 
 
222
      if (error == HA_ERR_ROW_IS_REFERENCED)
 
223
      {
 
224
        /* the table is referenced by a foreign key constraint */
 
225
        foreign_key_error= true;
 
226
      }
 
227
    }
 
228
 
 
229
    if (error == 0 || (if_exists && foreign_key_error == false))
 
230
    {
 
231
      TransactionServices &transaction_services= TransactionServices::singleton();
 
232
      transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
 
233
    }
 
234
 
 
235
    if (error)
 
236
    {
 
237
      if (wrong_tables.length())
 
238
        wrong_tables.append(',');
 
239
      wrong_tables.append(String(table->table_name,system_charset_info));
 
240
    }
248
241
  }
 
242
  /*
 
243
    It's safe to unlock LOCK_open: we have an exclusive lock
 
244
    on the table name.
 
245
  */
 
246
  LOCK_open.unlock();
249
247
  error= 0;
250
248
 
251
249
  if (wrong_tables.length())
262
260
    error= 1;
263
261
  }
264
262
 
265
 
  table::Cache::singleton().mutex().lock(); /* final bit in rm table lock */
 
263
  LOCK_open.lock(); /* final bit in rm table lock */
266
264
 
267
265
err_with_placeholders:
268
 
  tables->unlock_table_names();
269
 
  table::Cache::singleton().mutex().unlock();
 
266
  unlock_table_names(tables, NULL);
 
267
  LOCK_open.unlock();
270
268
  session->no_warnings_for_error= 0;
271
269
 
272
270
  return error;
273
271
}
274
272
 
 
273
 
 
274
/*
 
275
  Quickly remove a table.
 
276
 
 
277
  SYNOPSIS
 
278
    quick_rm_table()
 
279
      base                      The plugin::StorageEngine handle.
 
280
      db                        The database name.
 
281
      table_name                The table name.
 
282
      is_tmp                    If the table is temp.
 
283
 
 
284
  RETURN
 
285
    0           OK
 
286
    != 0        Error
 
287
*/
 
288
bool quick_rm_table(Session& session,
 
289
                    TableIdentifier &identifier)
 
290
{
 
291
  return (plugin::StorageEngine::dropTable(session, identifier));
 
292
}
 
293
 
275
294
/*
276
295
  Sort keys in the following order:
277
296
  - PRIMARY KEY
606
625
 
607
626
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
608
627
    {
609
 
      size_t dummy;
 
628
      uint32_t dummy;
610
629
      const CHARSET_INFO * const cs= sql_field->charset;
611
630
      TYPELIB *interval= sql_field->interval;
612
631
 
639
658
          if (String::needs_conversion(tmp->length(), tmp->charset(),
640
659
                                       cs, &dummy))
641
660
          {
642
 
            size_t cnv_errs;
 
661
            uint32_t cnv_errs;
643
662
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
644
663
            interval->type_names[i]= session->mem_root->strmake_root(conv.ptr(), conv.length());
645
664
            interval->type_lengths[i]= conv.length();
681
700
            }
682
701
          }
683
702
        }
684
 
        uint32_t new_dummy;
685
 
        calculate_interval_lengths(cs, interval, &field_length, &new_dummy);
 
703
        calculate_interval_lengths(cs, interval, &field_length, &dummy);
686
704
        sql_field->length= field_length;
687
705
      }
688
706
      set_if_smaller(sql_field->length, (uint32_t)MAX_FIELD_WIDTH-1);
1265
1283
}
1266
1284
 
1267
1285
static bool locked_create_event(Session *session,
1268
 
                                const TableIdentifier &identifier,
 
1286
                                TableIdentifier &identifier,
1269
1287
                                HA_CREATE_INFO *create_info,
1270
1288
                                message::Table &table_proto,
1271
1289
                                AlterInfo *alter_info,
1300
1318
        return error;
1301
1319
      }
1302
1320
 
1303
 
      std::string path;
1304
 
      identifier.getSQLPath(path);
1305
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1306
 
 
 
1321
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getSQLPath().c_str());
1307
1322
      return error;
1308
1323
    }
1309
1324
 
1320
1335
      /*
1321
1336
        @todo improve this error condition.
1322
1337
      */
1323
 
      if (definition::Cache::singleton().find(identifier.getKey()))
 
1338
      if (TableShare::getShare(identifier))
1324
1339
      {
1325
 
        std::string path;
1326
 
        identifier.getSQLPath(path);
1327
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1328
 
 
 
1340
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getSQLPath().c_str());
1329
1341
        return error;
1330
1342
      }
1331
1343
    }
1401
1413
*/
1402
1414
 
1403
1415
bool mysql_create_table_no_lock(Session *session,
1404
 
                                const TableIdentifier &identifier,
 
1416
                                TableIdentifier &identifier,
1405
1417
                                HA_CREATE_INFO *create_info,
1406
1418
                                message::Table &table_proto,
1407
1419
                                AlterInfo *alter_info,
1427
1439
 
1428
1440
  /* Build a Table object to pass down to the engine, and the do the actual create. */
1429
1441
  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))
 
1442
                                 internal_tmp_table,
 
1443
                                 &db_options,
 
1444
                                 &key_info_buffer, &key_count,
 
1445
                                 select_field_count))
1434
1446
  {
1435
 
    boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
 
1447
    boost::mutex::scoped_lock lock(LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1436
1448
    error= locked_create_event(session,
1437
1449
                               identifier,
1438
1450
                               create_info,
1453
1465
  @note the following two methods implement create [temporary] table.
1454
1466
*/
1455
1467
static bool drizzle_create_table(Session *session,
1456
 
                                 const TableIdentifier &identifier,
 
1468
                                 TableIdentifier &identifier,
1457
1469
                                 HA_CREATE_INFO *create_info,
1458
1470
                                 message::Table &table_proto,
1459
1471
                                 AlterInfo *alter_info,
1480
1492
    }
1481
1493
    else
1482
1494
    {
1483
 
      std::string path;
1484
 
      identifier.getSQLPath(path);
1485
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
1495
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getSQLPath().c_str());
1486
1496
      result= true;
1487
1497
    }
1488
1498
  }
1500
1510
 
1501
1511
  if (name_lock)
1502
1512
  {
1503
 
    boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* Lock for removing name_lock during table create */
 
1513
    boost::mutex::scoped_lock lock(LOCK_open); /* Lock for removing name_lock during table create */
1504
1514
    session->unlink_open_table(name_lock);
1505
1515
  }
1506
1516
 
1512
1522
  Database locking aware wrapper for mysql_create_table_no_lock(),
1513
1523
*/
1514
1524
bool mysql_create_table(Session *session,
1515
 
                        const TableIdentifier &identifier,
 
1525
                        TableIdentifier &identifier,
1516
1526
                        HA_CREATE_INFO *create_info,
1517
1527
                        message::Table &table_proto,
1518
1528
                        AlterInfo *alter_info,
1608
1618
bool
1609
1619
mysql_rename_table(Session &session,
1610
1620
                   plugin::StorageEngine *base,
1611
 
                   const TableIdentifier &from,
1612
 
                   const TableIdentifier &to)
 
1621
                   TableIdentifier &from,
 
1622
                   TableIdentifier &to)
1613
1623
{
1614
1624
  int error= 0;
1615
1625
 
1629
1639
  }
1630
1640
  else if (error)
1631
1641
  {
1632
 
    std::string from_path;
1633
 
    std::string to_path;
1634
 
 
1635
 
    from.getSQLPath(from_path);
1636
 
    to.getSQLPath(to_path);
1637
 
 
1638
 
    const char *from_identifier= from.isTmp() ? "#sql-temporary" : from_path.c_str();
1639
 
    const char *to_identifier= to.isTmp() ? "#sql-temporary" : to_path.c_str();
 
1642
    const char *from_identifier= from.isTmp() ? "#sql-temporary" : from.getSQLPath().c_str();
 
1643
    const char *to_identifier= to.isTmp() ? "#sql-temporary" : to.getSQLPath().c_str();
1640
1644
 
1641
1645
    my_error(ER_ERROR_ON_RENAME, MYF(0), from_identifier, to_identifier, error);
1642
1646
  }
1660
1664
   the table is closed.
1661
1665
 
1662
1666
  PREREQUISITES
1663
 
    Lock on table::Cache::singleton().mutex()
 
1667
    Lock on LOCK_open
1664
1668
    Win32 clients must also have a WRITE LOCK on the table !
1665
1669
*/
1666
1670
 
1668
1672
                              enum ha_extra_function function)
1669
1673
{
1670
1674
 
1671
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1675
  safe_mutex_assert_owner(LOCK_open.native_handle());
1672
1676
 
1673
1677
  table->cursor->extra(function);
1674
1678
  /* Mark all tables that are in use as 'old' */
1675
 
  session->abortLock(table);    /* end threads waiting on lock */
 
1679
  mysql_lock_abort(session, table);     /* end threads waiting on lock */
1676
1680
 
1677
1681
  /* Wait until all there are no other threads that has this table open */
1678
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1679
 
  table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
 
1682
  TableIdentifier identifier(table->getMutableShare()->getSchemaName(), table->getMutableShare()->getTableName());
 
1683
  remove_table_from_cache(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1680
1684
}
1681
1685
 
1682
1686
/*
1692
1696
    reopen the table.
1693
1697
 
1694
1698
  PREREQUISITES
1695
 
    Lock on table::Cache::singleton().mutex()
 
1699
    Lock on LOCK_open
1696
1700
    Win32 clients must also have a WRITE LOCK on the table !
1697
1701
*/
1698
1702
 
1703
1707
  /* Close lock if this is not got with LOCK TABLES */
1704
1708
  if (lock)
1705
1709
  {
1706
 
    unlockTables(lock);
 
1710
    mysql_unlock_tables(this, lock);
1707
1711
    lock= NULL;                 // Start locked threads
1708
1712
  }
1709
1713
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
1710
1714
  unlink_open_table(table);
1711
1715
 
1712
 
  /* When lock on table::Cache::singleton().mutex() is freed other threads can continue */
1713
 
  locking::broadcast_refresh();
 
1716
  /* When lock on LOCK_open is freed other threads can continue */
 
1717
  broadcast_refresh();
1714
1718
}
1715
1719
 
1716
1720
/*
1754
1758
  for (table= tables; table; table= table->next_local)
1755
1759
  {
1756
1760
    char table_name[NAME_LEN*2+2];
 
1761
    char* db = table->db;
1757
1762
    bool fatal_error=0;
1758
1763
 
1759
 
    snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
 
1764
    snprintf(table_name, sizeof(table_name), "%s.%s",db,table->table_name);
1760
1765
    table->lock_type= lock_type;
1761
1766
    /* open only one table from local list of command */
1762
1767
    {
1822
1827
    /* Close all instances of the table to allow repair to rename files */
1823
1828
    if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1824
1829
    {
1825
 
      table::Cache::singleton().mutex().lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1826
 
      const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
 
1830
      LOCK_open.lock(); /* Lock type is TL_WRITE and we lock to repair the table */
 
1831
      const char *old_message=session->enter_cond(COND_refresh, LOCK_open,
1827
1832
                                                  "Waiting to get writelock");
1828
 
      session->abortLock(table->table);
1829
 
      TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1830
 
      table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
 
1833
      mysql_lock_abort(session,table->table);
 
1834
      TableIdentifier identifier(table->table->getMutableShare()->getSchemaName(), table->table->getMutableShare()->getTableName());
 
1835
      remove_table_from_cache(session, identifier,
 
1836
                              RTFC_WAIT_OTHER_THREAD_FLAG |
 
1837
                              RTFC_CHECK_KILLED_FLAG);
1831
1838
      session->exit_cond(old_message);
1832
 
      if (session->getKilled())
 
1839
      if (session->killed)
1833
1840
        goto err;
1834
1841
      open_for_modify= 0;
1835
1842
    }
1927
1934
        }
1928
1935
        else
1929
1936
        {
1930
 
          boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1931
 
          TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1932
 
          table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
 
1937
          boost::mutex::scoped_lock lock(LOCK_open);
 
1938
          TableIdentifier identifier(table->table->getMutableShare()->getSchemaName(), table->table->getMutableShare()->getTableName());
 
1939
          remove_table_from_cache(session, identifier, RTFC_NO_FLAG);
1933
1940
        }
1934
1941
      }
1935
1942
    }
1959
1966
    Altough exclusive name-lock on target table protects us from concurrent
1960
1967
    DML and DDL operations on it we still want to wrap .FRM creation and call
1961
1968
    to plugin::StorageEngine::createTable() in critical section protected by
1962
 
    table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
 
1969
    LOCK_open in order to provide minimal atomicity against operations which
1963
1970
    disregard name-locks, like I_S implementation, for example. This is a
1964
1971
    temporary and should not be copied. Instead we should fix our code to
1965
1972
    always honor name-locks.
1966
1973
 
1967
 
    Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
 
1974
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
1975
    during the call to plugin::StorageEngine::createTable().
1969
1976
    See bug #28614 for more info.
1970
1977
  */
1971
1978
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
 
                                 const TableIdentifier &destination_identifier,
1973
 
                                 const TableIdentifier &src_table,
 
1979
                                 TableIdentifier &destination_identifier,
 
1980
                                 TableIdentifier &src_table,
1974
1981
                                 bool is_engine_set)
1975
1982
{
1976
1983
  int protoerr= EEXIST;
1977
1984
  message::Table new_proto;
1978
 
  message::table::shared_ptr src_proto;
 
1985
  message::Table src_proto;
1979
1986
 
1980
1987
  protoerr= plugin::StorageEngine::getTableDefinition(session,
1981
1988
                                                      src_table,
1982
1989
                                                      src_proto);
1983
 
  new_proto.CopyFrom(*src_proto);
 
1990
  new_proto.CopyFrom(src_proto);
1984
1991
 
1985
1992
  if (destination_identifier.isTmp())
1986
1993
  {
2046
2053
*/
2047
2054
 
2048
2055
bool mysql_create_like_table(Session* session,
2049
 
                             const TableIdentifier &destination_identifier,
 
2056
                             TableIdentifier &destination_identifier,
2050
2057
                             TableList* table, TableList* src_table,
2051
2058
                             message::Table &create_table_proto,
2052
2059
                             bool is_if_not_exists,
2053
2060
                             bool is_engine_set)
2054
2061
{
 
2062
  char *db= table->db;
 
2063
  char *table_name= table->table_name;
2055
2064
  bool res= true;
2056
2065
  uint32_t not_used;
2057
2066
 
2067
2076
  if (session->open_tables_from_list(&src_table, &not_used))
2068
2077
    return true;
2069
2078
 
2070
 
  TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2071
 
                                 src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
 
2079
  TableIdentifier src_identifier(src_table->table->getMutableShare()->getSchemaName(),
 
2080
                                 src_table->table->getMutableShare()->getTableName(), src_table->table->getMutableShare()->getType());
2072
2081
 
2073
2082
 
2074
2083
 
2081
2090
  bool table_exists= false;
2082
2091
  if (destination_identifier.isTmp())
2083
2092
  {
2084
 
    if (session->find_temporary_table(destination_identifier))
 
2093
    if (session->find_temporary_table(db, table_name))
2085
2094
    {
2086
2095
      table_exists= true;
2087
2096
    }
2112
2121
    {
2113
2122
      if (name_lock)
2114
2123
      {
2115
 
        boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* unlink open tables for create table like*/
 
2124
        boost::mutex::scoped_lock lock(LOCK_open); /* unlink open tables for create table like*/
2116
2125
        session->unlink_open_table(name_lock);
2117
2126
      }
2118
2127
 
2131
2140
    {
2132
2141
      bool was_created;
2133
2142
      {
2134
 
        boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
 
2143
        boost::mutex::scoped_lock lock(LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2135
2144
        was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2136
2145
                                               src_identifier, is_engine_set);
2137
2146
      }
2140
2149
      // anything that might have been created (read... it is a hack)
2141
2150
      if (not was_created)
2142
2151
      {
2143
 
        plugin::StorageEngine::dropTable(*session, destination_identifier);
 
2152
        quick_rm_table(*session, destination_identifier);
2144
2153
      } 
2145
2154
      else
2146
2155
      {
2150
2159
 
2151
2160
    if (name_lock)
2152
2161
    {
2153
 
      boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* unlink open tables for create table like*/
 
2162
      boost::mutex::scoped_lock lock(LOCK_open); /* unlink open tables for create table like*/
2154
2163
      session->unlink_open_table(name_lock);
2155
2164
    }
2156
2165
  }
2161
2170
    {
2162
2171
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
2163
2172
      snprintf(warn_buff, sizeof(warn_buff),
2164
 
               ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
 
2173
               ER(ER_TABLE_EXISTS_ERROR), table_name);
2165
2174
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2166
2175
                   ER_TABLE_EXISTS_ERROR,warn_buff);
2167
2176
      res= false;
2168
2177
    }
2169
2178
    else
2170
2179
    {
2171
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
 
2180
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2172
2181
    }
2173
2182
  }
2174
2183