110
106
assert(schema_message.has_collation());
112
108
// @todo push this lock down into the engine
109
pthread_mutex_lock(&LOCK_create_db);
111
// Check to see if it exists already.
112
SchemaIdentifier schema_identifier(schema_message.name());
113
if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
114
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
116
// Check to see if it exists already.
117
SchemaIdentifier schema_identifier(schema_message.name());
118
if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
120
if (not is_if_not_exists)
122
my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
127
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
128
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
129
schema_message.name().c_str());
133
else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it
135
my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
115
if (not is_if_not_exists)
117
my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
140
transaction_services.createSchema(session, schema_message);
122
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
123
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
124
schema_message.name().c_str());
144
session->startWaitingGlobalReadLock();
128
else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it
130
my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
135
transaction_services.createSchema(session, schema_message);
139
pthread_mutex_unlock(&LOCK_create_db);
140
start_waiting_global_read_lock(session);
165
161
has the global read lock and refuses the operation with
166
162
ER_CANT_UPDATE_WITH_READLOCK if applicable.
168
if ((session->wait_if_global_read_lock(false, true)))
173
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
175
SchemaIdentifier schema_idenifier(schema_message.name());
176
if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
178
my_error(ER_SCHEMA_DOES_NOT_EXIST, MYF(0), schema_message.name().c_str());
182
/* Change options if current database is being altered. */
183
success= plugin::StorageEngine::alterSchema(schema_message);
187
transaction_services.rawStatement(session, *session->getQueryString());
192
my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
195
session->startWaitingGlobalReadLock();
164
if ((wait_if_global_read_lock(session, 0, 1)))
167
pthread_mutex_lock(&LOCK_create_db);
169
SchemaIdentifier schema_idenifier(schema_message.name());
170
if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
172
my_error(ER_SCHEMA_DOES_NOT_EXIST, MYF(0), schema_message.name().c_str());
176
/* Change options if current database is being altered. */
177
bool success= plugin::StorageEngine::alterSchema(schema_message);
181
transaction_services.rawStatement(session, session->getQueryString());
186
my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
189
pthread_mutex_unlock(&LOCK_create_db);
190
start_waiting_global_read_lock(session);
250
245
session->close_temporary_table(table);
248
pthread_mutex_lock(&LOCK_create_db);
251
/* See if the schema exists */
252
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
254
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
256
/* See if the schema exists */
257
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
260
schema_identifier.getSQLPath(path);
264
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
265
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
271
my_error(ER_DB_DROP_EXISTS, MYF(0), path.c_str());
256
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
257
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
258
schema_identifier.getSQLPath().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);
263
my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
269
pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
270
remove_db_from_cache(schema_identifier);
271
pthread_mutex_unlock(&LOCK_open);
275
deleted= mysql_rm_known_files(session, schema_identifier, dropped_tables);
288
276
if (deleted >= 0)
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;
283
assert(! session->query.empty());
285
TransactionServices &transaction_services= TransactionServices::singleton();
286
transaction_services.dropSchema(session, schema_identifier.getSchemaName());
287
session->clear_error();
288
session->server_status|= SERVER_STATUS_DB_DROPPED;
289
session->my_ok((uint32_t) deleted);
290
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
294
char *query, *query_pos, *query_end, *query_data_start;
296
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
297
goto exit; /* not much else we can do */
298
query_pos= query_data_start= strcpy(query,"drop table ")+11;
299
query_end= query + MAX_DROP_TABLE_Q_LEN;
301
TransactionServices &transaction_services= TransactionServices::singleton();
302
for (plugin::TableNameList::iterator it= dropped_tables.begin();
303
it != dropped_tables.end();
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)
306
uint32_t tbl_name_len;
308
/* 3 for the quotes and the comma*/
309
tbl_name_len= (*it).length() + 3;
310
if (query_pos + tbl_name_len + 1 >= query_end)
332
312
/* These DDL methods and logging protected with LOCK_create_db */
333
313
transaction_services.rawStatement(session, query);
314
query_pos= query_data_start;
318
query_pos= strcpy(query_pos, (*it).c_str()) + (tbl_name_len-3);
323
if (query_pos != query_data_start)
325
/* These DDL methods and logging protected with LOCK_create_db */
326
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);
348
session->startWaitingGlobalReadLock();
332
If this database was the client's selected database, we silently
333
change the client's selected database to nothing (to have an empty
334
SELECT DATABASE() in the future). For this we free() session->db and set
337
if (schema_identifier.compare(session->db))
338
mysql_change_db_impl(session);
339
pthread_mutex_unlock(&LOCK_create_db);
340
start_waiting_global_read_lock(session);
354
346
static int rm_table_part2(Session *session, TableList *tables)
356
TransactionServices &transaction_services= TransactionServices::singleton();
358
348
TableList *table;
359
349
String wrong_tables;
361
351
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();
353
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
356
If we have the table in the definition cache, we don't have to check the
357
.frm cursor to find if the table is a normal table (not view) and what
361
for (table= tables; table; table= table->next_local)
363
TableIdentifier identifier(table->db, table->table_name);
365
table->db_type= NULL;
366
if ((share= TableShare::getShare(identifier)))
368
table->db_type= share->db_type();
372
if (lock_table_names_exclusively(session, tables))
374
pthread_mutex_unlock(&LOCK_open);
378
/* Don't give warnings for not found errors, as we already generate notes */
379
session->no_warnings_for_error= 1;
381
for (table= tables; table; table= table->next_local)
384
plugin::StorageEngine *table_type;
386
error= session->drop_temporary_table(table);
390
// removed temporary table
394
goto err_with_placeholders;
396
// temporary table not found
400
table_type= table->db_type;
404
abort_locked_tables(session, db, table->table_name);
405
remove_table_from_cache(session, db, table->table_name,
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, db, table->table_name)))
413
table->table= locked_table;
418
goto err_with_placeholders;
422
TableIdentifier identifier(db, table->table_name);
423
identifier.getPath();
425
if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
427
// Table was not found on disk and table can't be created from engine
428
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
429
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
434
error= plugin::StorageEngine::dropTable(*session, identifier);
436
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
439
session->clear_error();
442
if (error == HA_ERR_ROW_IS_REFERENCED)
444
/* the table is referenced by a foreign key constraint */
445
foreign_key_error= true;
449
if (error == 0 || (foreign_key_error == false))
450
write_bin_log_drop_table(session, true, db, table->table_name);
454
if (wrong_tables.length())
455
wrong_tables.append(',');
456
wrong_tables.append(String(table->table_name,system_charset_info));
460
It's safe to unlock LOCK_open: we have an exclusive lock
463
pthread_mutex_unlock(&LOCK_open);
471
465
if (wrong_tables.length())
515
509
TableList *table_list=(TableList*)
516
510
session->calloc(sizeof(*table_list) +
518
(*it).getTableName().length() + 1);
520
514
if (not table_list)
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(),
517
table_list->db= (char*) (table_list+1);
518
table_list->table_name= strcpy(table_list->db, schema_identifier.getSchemaName().c_str()) + db_len + 1;
519
filename_to_tablename((*it).c_str(), table_list->table_name,
521
table_list->alias= table_list->table_name; // If lower_case_table_names=2
522
table_list->internal_tmp_table= (strncmp((*it).c_str(),
529
strlen(TMP_FILE_PREFIX)) == 0));
524
strlen(TMP_FILE_PREFIX)) == 0);
530
525
/* Link into list */
531
526
(*tot_list_next)= table_list;
532
527
tot_list_next= &table_list->next_local;
535
if (session->getKilled())