271
my_error(ER_DB_DROP_EXISTS, MYF(0), path.c_str());
277
/* After deleting database, remove all cache entries related to schema */
278
table::Cache::singleton().removeSchema(schema_identifier);
282
deleted= drop_tables_via_filenames(session, schema_identifier, dropped_tables);
290
assert(not session->getQueryString()->empty());
292
TransactionServices &transaction_services= TransactionServices::singleton();
293
transaction_services.dropSchema(session, schema_identifier.getSchemaName());
294
session->clear_error();
295
session->server_status|= SERVER_STATUS_DB_DROPPED;
296
session->my_ok((uint32_t) deleted);
297
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
301
char *query, *query_pos, *query_end, *query_data_start;
303
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
304
goto exit; /* not much else we can do */
305
query_pos= query_data_start= strcpy(query,"drop table ")+11;
306
query_end= query + MAX_DROP_TABLE_Q_LEN;
308
TransactionServices &transaction_services= TransactionServices::singleton();
309
for (TableIdentifier::vector::iterator it= dropped_tables.begin();
310
it != dropped_tables.end();
313
uint32_t tbl_name_len;
315
/* 3 for the quotes and the comma*/
316
tbl_name_len= (*it).getTableName().length() + 3;
317
if (query_pos + tbl_name_len + 1 >= query_end)
319
/* These DDL methods and logging protected with LOCK_create_db */
320
transaction_services.rawStatement(session, query);
321
query_pos= query_data_start;
325
query_pos= strcpy(query_pos, (*it).getTableName().c_str()) + (tbl_name_len-3);
330
if (query_pos != query_data_start)
332
/* These DDL methods and logging protected with LOCK_create_db */
333
transaction_services.rawStatement(session, query);
339
If this database was the client's selected database, we silently
340
change the client's selected database to nothing (to have an empty
341
SELECT DATABASE() in the future). For this we free() session->db and set
344
if (schema_identifier.compare(*session->schema()))
345
mysql_change_db_impl(session);
255
my_error(ER_DB_DROP_EXISTS, schema_identifier);
261
error= plugin::StorageEngine::dropSchema(*session, schema_identifier);
267
If this database was the client's selected database, we silently
268
change the client's selected database to nothing (to have an empty
269
SELECT DATABASE() in the future). For this we free() session->db and set
272
if (not error and schema_identifier.compare(*session->schema()))
273
change_db_impl(session);
348
275
session->startWaitingGlobalReadLock();
354
static int rm_table_part2(Session *session, TableList *tables)
356
TransactionServices &transaction_services= TransactionServices::singleton();
361
bool foreign_key_error= false;
364
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
366
if (session->lock_table_names_exclusively(tables))
368
table::Cache::singleton().mutex().unlock();
372
/* Don't give warnings for not found errors, as we already generate notes */
373
session->no_warnings_for_error= 1;
375
for (table= tables; table; table= table->next_local)
377
const char *db=table->getSchemaName();
378
TableIdentifier identifier(table->getSchemaName(), table->getTableName());
380
plugin::StorageEngine *table_type;
382
error= session->drop_temporary_table(identifier);
386
// removed temporary table
390
tables->unlock_table_names();
391
table::Cache::singleton().mutex().unlock();
392
session->no_warnings_for_error= 0;
396
// temporary table not found
400
table_type= table->getDbType();
404
abort_locked_tables(session, identifier);
405
table::Cache::singleton().removeTable(session, identifier,
406
RTFC_WAIT_OTHER_THREAD_FLAG |
407
RTFC_CHECK_KILLED_FLAG);
409
If the table was used in lock tables, remember it so that
410
unlock_table_names can free it
412
if ((locked_table= drop_locked_tables(session, identifier)))
413
table->table= locked_table;
415
if (session->getKilled())
418
tables->unlock_table_names();
419
table::Cache::singleton().mutex().unlock();
420
session->no_warnings_for_error= 0;
425
identifier.getPath();
427
if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
429
// Table was not found on disk and table can't be created from engine
430
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
431
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
432
table->getTableName());
436
error= plugin::StorageEngine::dropTable(*session, identifier);
438
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
441
session->clear_error();
444
if (error == HA_ERR_ROW_IS_REFERENCED)
446
/* the table is referenced by a foreign key constraint */
447
foreign_key_error= true;
451
if (error == 0 || (foreign_key_error == false))
453
transaction_services.dropTable(session, string(db), string(table->getTableName()), true);
458
if (wrong_tables.length())
459
wrong_tables.append(',');
460
wrong_tables.append(String(table->getTableName(),system_charset_info));
464
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
467
table::Cache::singleton().mutex().unlock();
471
if (wrong_tables.length())
473
if (not foreign_key_error)
474
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
475
wrong_tables.c_ptr());
478
my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
484
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* final bit in rm table lock */
485
tables->unlock_table_names();
487
session->no_warnings_for_error= 0;
493
Removes files with known extensions plus.
494
session MUST be set when calling this function!
497
static long drop_tables_via_filenames(Session *session,
498
SchemaIdentifier &schema_identifier,
499
TableIdentifier::vector &dropped_tables)
502
TableList *tot_list= NULL, **tot_list_next;
504
tot_list_next= &tot_list;
506
plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
508
for (TableIdentifier::vector::iterator it= dropped_tables.begin();
509
it != dropped_tables.end();
512
size_t db_len= schema_identifier.getSchemaName().size();
514
/* Drop the table nicely */
515
TableList *table_list=(TableList*)
516
session->calloc(sizeof(*table_list) +
518
(*it).getTableName().length() + 1);
523
table_list->setSchemaName((char*) (table_list+1));
524
table_list->setTableName(strcpy((char*) (table_list+1), schema_identifier.getSchemaName().c_str()) + db_len + 1);
525
TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), const_cast<char *>(table_list->getTableName()), (*it).getTableName().size() + 1);
526
table_list->alias= table_list->getTableName(); // If lower_case_table_names=2
527
table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
529
strlen(TMP_FILE_PREFIX)) == 0));
531
(*tot_list_next)= table_list;
532
tot_list_next= &table_list->next_local;
535
if (session->getKilled())
540
if (rm_table_part2(session, tot_list))
545
if (not plugin::StorageEngine::dropSchema(schema_identifier))
548
schema_identifier.getSQLPath(path);
549
my_error(ER_DROP_SCHEMA, MYF(0), path.c_str());
558
281
@brief Change the current database and its attributes unconditionally.