From 909f7607018e644754a2c41b791b44b25a05e8fb Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 15 Jun 2015 15:37:14 +0400 Subject: [PATCH] MDEV-5309 - RENAME TABLE does not check for existence of the table's engine When RENAME TABLE is executed, it apparently does not check whether the engine is available (unlike ALTER TABLE .. RENAME, which does). It means that if the engine in question was not loaded on some reason, the table might become unusable, since the engine won't know about the change. With this patch RENAME TABLE fails if storage engine is not available. --- mysql-test/r/plugin.result | 10 ++++++++++ mysql-test/t/plugin.test | 11 +++++++++++ sql/sql_rename.cc | 9 ++------- sql/sql_table.cc | 4 ++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 630f0141d18..3a2bb32b13d 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -321,3 +321,13 @@ UNUSABLE uninstall soname 'ha_example'; select plugin_name from information_schema.plugins where plugin_library like 'ha_example%'; plugin_name +# +# MDEV-5309 - RENAME TABLE does not check for existence of the table's +# engine +# +INSTALL PLUGIN example SONAME 'ha_example'; +CREATE TABLE t1(a INT) ENGINE=EXAMPLE; +UNINSTALL PLUGIN example; +RENAME TABLE t1 TO t2; +ERROR 42S02: Table 'test.t1' doesn't exist +DROP TABLE t1; diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 0655aff9fc9..9c2a408b612 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -252,3 +252,14 @@ select plugin_name from information_schema.plugins where plugin_library like 'ha uninstall soname 'ha_example'; select plugin_name from information_schema.plugins where plugin_library like 'ha_example%'; + +--echo # +--echo # MDEV-5309 - RENAME TABLE does not check for existence of the table's +--echo # engine +--echo # +INSTALL PLUGIN example SONAME 'ha_example'; +CREATE TABLE t1(a INT) ENGINE=EXAMPLE; +UNINSTALL PLUGIN example; +--error ER_NO_SUCH_TABLE +RENAME TABLE t1 TO t2; +DROP TABLE t1; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 2c17898f07c..6496e1895fb 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -238,7 +238,6 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, { int rc= 1; handlerton *hton; - bool new_exists, old_exists; const char *new_alias, *old_alias; DBUG_ENTER("do_rename"); @@ -254,17 +253,13 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } DBUG_ASSERT(new_alias); - new_exists= ha_table_exists(thd, new_db, new_alias); - - if (new_exists) + if (ha_table_exists(thd, new_db, new_alias)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(1); // This can't be skipped } - old_exists= ha_table_exists(thd, ren_table->db, old_alias, &hton); - - if (old_exists) + if (ha_table_exists(thd, ren_table->db, old_alias, &hton) && hton) { DBUG_ASSERT(!thd->locked_tables_mode); tdc_remove_table(thd, TDC_RT_REMOVE_ALL, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6ee0e9bc871..c31a6fd6474 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5149,6 +5149,7 @@ mysql_rename_table(handlerton *base, const char *old_db, ulonglong save_bits= thd->variables.option_bits; int length; DBUG_ENTER("mysql_rename_table"); + DBUG_ASSERT(base); DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'", old_db, old_name, new_db, new_name)); @@ -5156,8 +5157,7 @@ mysql_rename_table(handlerton *base, const char *old_db, if (flags & NO_FK_CHECKS) thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS; - file= (base == NULL ? 0 : - get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base)); + file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base); build_table_filename(from, sizeof(from) - 1, old_db, old_name, "", flags & FN_FROM_IS_TMP);