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)
163
TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
165
error= session->drop_temporary_table(tmp_identifier);
169
// removed temporary table
173
goto err_with_placeholders;
175
// temporary table not found
179
if (drop_temporary == false)
182
abort_locked_tables(session, tmp_identifier);
183
table::Cache::singleton().removeTable(session, tmp_identifier,
184
RTFC_WAIT_OTHER_THREAD_FLAG |
185
RTFC_CHECK_KILLED_FLAG);
187
If the table was used in lock tables, remember it so that
188
unlock_table_names can free it
190
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
191
table->table= locked_table;
196
goto err_with_placeholders;
199
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
201
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
203
// Table was not found on disk and table can't be created from engine
205
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
206
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
207
table->getTableName());
175
goto err_with_placeholders;
177
// temporary table not found
213
error= plugin::StorageEngine::dropTable(*session, identifier);
215
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();
218
session->clear_error();
221
if (error == HA_ERR_ROW_IS_REFERENCED)
223
/* the table is referenced by a foreign key constraint */
224
foreign_key_error= true;
228
if (error == 0 || (if_exists && foreign_key_error == false))
230
TransactionServices &transaction_services= TransactionServices::singleton();
231
transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
236
if (wrong_tables.length())
237
wrong_tables.append(',');
238
wrong_tables.append(String(table->getTableName(), system_charset_info));
242
It's safe to unlock LOCK_open: we have an exclusive lock
251
248
if (wrong_tables.length())
1822
1826
/* Close all instances of the table to allow repair to rename files */
1823
1827
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(),
1829
LOCK_open.lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1830
const char *old_message=session->enter_cond(COND_refresh, LOCK_open,
1827
1831
"Waiting to get writelock");
1828
session->abortLock(table->table);
1832
mysql_lock_abort(session,table->table);
1829
1833
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1830
1834
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1831
1835
session->exit_cond(old_message);
1832
if (session->getKilled())
1836
if (session->killed)
1834
1838
open_for_modify= 0;
1959
1963
Altough exclusive name-lock on target table protects us from concurrent
1960
1964
DML and DDL operations on it we still want to wrap .FRM creation and call
1961
1965
to plugin::StorageEngine::createTable() in critical section protected by
1962
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
1966
LOCK_open in order to provide minimal atomicity against operations which
1963
1967
disregard name-locks, like I_S implementation, for example. This is a
1964
1968
temporary and should not be copied. Instead we should fix our code to
1965
1969
always honor name-locks.
1967
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
1971
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
1972
during the call to plugin::StorageEngine::createTable().
1969
1973
See bug #28614 for more info.
1971
1975
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
1976
TableIdentifier &destination_identifier,
1977
TableIdentifier &src_table,
1974
1978
bool is_engine_set)
1976
1980
int protoerr= EEXIST;
1977
1981
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
1982
message::Table src_proto;
1980
1984
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
1987
new_proto.CopyFrom(src_proto);
1985
1989
if (destination_identifier.isTmp())