149
148
bool foreign_key_error= false;
152
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
154
if (not drop_temporary && session->lock_table_names_exclusively(tables))
156
table::Cache::singleton().mutex().unlock();
160
/* Don't give warnings for not found errors, as we already generate notes */
161
session->no_warnings_for_error= 1;
163
for (table= tables; table; table= table->next_local)
165
TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
167
error= session->drop_temporary_table(tmp_identifier);
171
// removed temporary table
150
LOCK_open.lock(); /* Part 2 of rm a table */
152
if (not drop_temporary && lock_table_names_exclusively(session, tables))
158
/* Don't give warnings for not found errors, as we already generate notes */
159
session->no_warnings_for_error= 1;
161
for (table= tables; table; table= table->next_local)
165
error= session->drop_temporary_table(table);
169
// removed temporary table
173
goto err_with_placeholders;
175
// temporary table not found
179
if (drop_temporary == false)
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);
188
If the table was used in lock tables, remember it so that
189
unlock_table_names can free it
191
if ((locked_table= drop_locked_tables(session, identifier)))
192
table->table= locked_table;
197
goto err_with_placeholders;
200
TableIdentifier identifier(db, table->table_name, table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
202
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
// Table was not found on disk and table can't be created from engine
206
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
207
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
175
goto err_with_placeholders;
177
// temporary table not found
214
error= plugin::StorageEngine::dropTable(*session, identifier);
216
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
181
if (drop_temporary == false)
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);
189
If the table was used in lock tables, remember it so that
190
unlock_table_names can free it
192
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
193
table->table= locked_table;
195
if (session->getKilled())
198
goto err_with_placeholders;
201
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
203
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
205
// Table was not found on disk and table can't be created from engine
207
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
table->getTableName());
215
error= plugin::StorageEngine::dropTable(*session, identifier);
217
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
220
session->clear_error();
223
if (error == HA_ERR_ROW_IS_REFERENCED)
225
/* the table is referenced by a foreign key constraint */
226
foreign_key_error= true;
230
if (error == 0 || (if_exists && foreign_key_error == false))
232
TransactionServices &transaction_services= TransactionServices::singleton();
233
transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
238
if (wrong_tables.length())
239
wrong_tables.append(',');
240
wrong_tables.append(String(table->getTableName(), system_charset_info));
244
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
247
table::Cache::singleton().mutex().unlock();
219
session->clear_error();
222
if (error == HA_ERR_ROW_IS_REFERENCED)
224
/* the table is referenced by a foreign key constraint */
225
foreign_key_error= true;
229
if (error == 0 || (if_exists && foreign_key_error == false))
231
TransactionServices &transaction_services= TransactionServices::singleton();
232
transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
237
if (wrong_tables.length())
238
wrong_tables.append(',');
239
wrong_tables.append(String(table->table_name,system_charset_info));
243
It's safe to unlock LOCK_open: we have an exclusive lock
251
249
if (wrong_tables.length())
1668
1673
enum ha_extra_function function)
1671
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1676
safe_mutex_assert_owner(LOCK_open.native_handle());
1673
1678
table->cursor->extra(function);
1674
1679
/* Mark all tables that are in use as 'old' */
1675
session->abortLock(table); /* end threads waiting on lock */
1680
mysql_lock_abort(session, table); /* end threads waiting on lock */
1677
1682
/* 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);
1683
TableIdentifier identifier(table->getMutableShare()->getSchemaName(), table->getMutableShare()->getTableName());
1684
remove_table_from_cache(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1822
1828
/* Close all instances of the table to allow repair to rename files */
1823
1829
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
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(),
1831
LOCK_open.lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1832
const char *old_message=session->enter_cond(COND_refresh, LOCK_open,
1827
1833
"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);
1834
mysql_lock_abort(session,table->table);
1835
TableIdentifier identifier(table->table->getMutableShare()->getSchemaName(), table->table->getMutableShare()->getTableName());
1836
remove_table_from_cache(session, identifier,
1837
RTFC_WAIT_OTHER_THREAD_FLAG |
1838
RTFC_CHECK_KILLED_FLAG);
1831
1839
session->exit_cond(old_message);
1832
if (session->getKilled())
1840
if (session->killed)
1834
1842
open_for_modify= 0;
1959
1967
Altough exclusive name-lock on target table protects us from concurrent
1960
1968
DML and DDL operations on it we still want to wrap .FRM creation and call
1961
1969
to plugin::StorageEngine::createTable() in critical section protected by
1962
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
1970
LOCK_open in order to provide minimal atomicity against operations which
1963
1971
disregard name-locks, like I_S implementation, for example. This is a
1964
1972
temporary and should not be copied. Instead we should fix our code to
1965
1973
always honor name-locks.
1967
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
1975
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
1976
during the call to plugin::StorageEngine::createTable().
1969
1977
See bug #28614 for more info.
1971
1979
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
1980
TableIdentifier &destination_identifier,
1981
TableIdentifier &src_table,
1974
1982
bool is_engine_set)
1976
1984
int protoerr= EEXIST;
1977
1985
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
1986
message::Table src_proto;
1980
1988
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
1991
new_proto.CopyFrom(src_proto);
1985
1993
if (destination_identifier.isTmp())