271
255
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);
281
deleted= drop_tables_via_filenames(session, schema_identifier, dropped_tables);
286
/* We've already verified that the schema does exist, so safe to log it */
287
TransactionServices &transaction_services= TransactionServices::singleton();
288
transaction_services.dropSchema(session, schema_identifier.getSchemaName());
293
session->clear_error();
294
session->server_status|= SERVER_STATUS_DB_DROPPED;
295
session->my_ok((uint32_t) deleted);
296
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
300
char *query, *query_pos, *query_end, *query_data_start;
302
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
303
goto exit; /* not much else we can do */
304
query_pos= query_data_start= strcpy(query,"drop table ")+11;
305
query_end= query + MAX_DROP_TABLE_Q_LEN;
307
TransactionServices &transaction_services= TransactionServices::singleton();
308
for (TableIdentifier::vector::iterator it= dropped_tables.begin();
309
it != dropped_tables.end();
312
uint32_t tbl_name_len;
314
/* 3 for the quotes and the comma*/
315
tbl_name_len= (*it).getTableName().length() + 3;
316
if (query_pos + tbl_name_len + 1 >= query_end)
318
/* These DDL methods and logging protected with LOCK_create_db */
319
transaction_services.rawStatement(session, query);
320
query_pos= query_data_start;
324
query_pos= strcpy(query_pos, (*it).getTableName().c_str()) + (tbl_name_len-3);
329
if (query_pos != query_data_start)
331
/* These DDL methods and logging protected with LOCK_create_db */
332
transaction_services.rawStatement(session, query);
338
If this database was the client's selected database, we silently
339
change the client's selected database to nothing (to have an empty
340
SELECT DATABASE() in the future). For this we free() session->db and set
343
if (schema_identifier.compare(*session->schema()))
344
change_db_impl(session);
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);
347
275
session->startWaitingGlobalReadLock();
353
static int rm_table_part2(Session *session, TableList *tables)
355
TransactionServices &transaction_services= TransactionServices::singleton();
360
bool foreign_key_error= false;
363
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
365
if (session->lock_table_names_exclusively(tables))
367
table::Cache::singleton().mutex().unlock();
371
/* Don't give warnings for not found errors, as we already generate notes */
372
session->no_warnings_for_error= 1;
374
for (table= tables; table; table= table->next_local)
376
const char *db=table->getSchemaName();
377
TableIdentifier identifier(table->getSchemaName(), table->getTableName());
379
plugin::StorageEngine *table_type;
381
error= session->drop_temporary_table(identifier);
385
// removed temporary table
389
tables->unlock_table_names();
390
table::Cache::singleton().mutex().unlock();
391
session->no_warnings_for_error= 0;
395
// temporary table not found
399
table_type= table->getDbType();
403
abort_locked_tables(session, identifier);
404
table::Cache::singleton().removeTable(session, identifier,
405
RTFC_WAIT_OTHER_THREAD_FLAG |
406
RTFC_CHECK_KILLED_FLAG);
408
If the table was used in lock tables, remember it so that
409
unlock_table_names can free it
411
if ((locked_table= drop_locked_tables(session, identifier)))
412
table->table= locked_table;
414
if (session->getKilled())
417
tables->unlock_table_names();
418
table::Cache::singleton().mutex().unlock();
419
session->no_warnings_for_error= 0;
424
identifier.getPath();
426
if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
428
// Table was not found on disk and table can't be created from engine
429
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
430
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
431
table->getTableName());
435
error= plugin::StorageEngine::dropTable(*session, identifier);
437
/* Generate transaction event ONLY when we successfully drop */
440
transaction_services.dropTable(session, string(db), string(table->getTableName()));
443
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
446
session->clear_error();
449
if (error == HA_ERR_ROW_IS_REFERENCED)
451
/* the table is referenced by a foreign key constraint */
452
foreign_key_error= 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.