From 09fc514bd57be466589a8a4cc119ac34062d983e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Nov 2006 13:18:37 +0100 Subject: [PATCH] Fix for bug#24219 ALTER TABLE ... RENAME TO ... , DISABLE KEYS leads to crash There was an improper order of doing chained operations. To the documentor: ENABLE|DISABLE KEYS combined with RENAME TO, and no other ALTER TABLE clause, leads to server crash independent of the presence of indices and data in the table. mysql-test/r/alter_table.result: update result mysql-test/t/alter_table.test: add test for bug#24129 sql/sql_table.cc: If there is operation on the KEYS, first do it and then do a rename if there is such. Or, we will crash because the underlying table has changed. --- mysql-test/r/alter_table.result | 11 +++++++ mysql-test/t/alter_table.test | 18 +++++++++++ sql/sql_table.cc | 53 +++++++++++++++++++-------------- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index e9c9c873750..eade19e85df 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -543,3 +543,14 @@ ERROR 3D000: No database selected alter table test.t1 rename test.t1; use test; drop table t1; +DROP TABLE IF EXISTS bug24219; +DROP TABLE IF EXISTS bug24219_2; +CREATE TABLE bug24219 (a INT, INDEX(a)); +SHOW INDEX FROM bug24219; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +bug24219 1 a 1 a A NULL NULL NULL YES BTREE +ALTER TABLE bug24219 RENAME TO bug24219_2, DISABLE KEYS; +SHOW INDEX FROM bug24219_2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +bug24219_2 1 a 1 a A NULL NULL NULL YES BTREE disabled +DROP TABLE bug24219_2; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 9bd34c2a610..eba456982c8 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -392,4 +392,22 @@ alter table test.t1 rename test.t1; use test; drop table t1; +# +# Bug#24219 - ALTER TABLE ... RENAME TO ... , DISABLE KEYS leads to crash +# +--disable_warnings +DROP TABLE IF EXISTS bug24219; +DROP TABLE IF EXISTS bug24219_2; +--enable_warnings + +CREATE TABLE bug24219 (a INT, INDEX(a)); + +SHOW INDEX FROM bug24219; + +ALTER TABLE bug24219 RENAME TO bug24219_2, DISABLE KEYS; + +SHOW INDEX FROM bug24219_2; + +DROP TABLE bug24219_2; + # End of 4.1 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index da66b556b5e..256b9281e9f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2949,8 +2949,35 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->proc_info="setup"; if (alter_info->is_simple && !table->tmp_table) { - error=0; - if (new_name != table_name || new_db != db) + switch (alter_info->keys_onoff) { + case LEAVE_AS_IS: + error= 0; + break; + case ENABLE: + VOID(pthread_mutex_lock(&LOCK_open)); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); + VOID(pthread_mutex_unlock(&LOCK_open)); + error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + /* COND_refresh will be signaled in close_thread_tables() */ + break; + case DISABLE: + VOID(pthread_mutex_lock(&LOCK_open)); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); + VOID(pthread_mutex_unlock(&LOCK_open)); + error= table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + /* COND_refresh will be signaled in close_thread_tables() */ + break; + } + + if (error == HA_ERR_WRONG_COMMAND) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + table->table_name); + error= 0; + } + + if (!error && (new_name != table_name || new_db != db)) { thd->proc_info="rename"; VOID(pthread_mutex_lock(&LOCK_open)); @@ -2971,27 +2998,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, VOID(pthread_mutex_unlock(&LOCK_open)); } - if (!error) - { - switch (alter_info->keys_onoff) { - case LEAVE_AS_IS: - break; - case ENABLE: - VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); - error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - /* COND_refresh will be signaled in close_thread_tables() */ - break; - case DISABLE: - VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); - error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - /* COND_refresh will be signaled in close_thread_tables() */ - break; - } - } if (error == HA_ERR_WRONG_COMMAND) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -2999,6 +3005,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, table->table_name); error=0; } + if (!error) { mysql_update_log.write(thd, thd->query, thd->query_length);