Commit de904f54 authored by andrey@example.com's avatar andrey@example.com

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.
parent 3ebd031e
...@@ -543,3 +543,14 @@ ERROR 3D000: No database selected ...@@ -543,3 +543,14 @@ ERROR 3D000: No database selected
alter table test.t1 rename test.t1; alter table test.t1 rename test.t1;
use test; use test;
drop table t1; 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;
...@@ -392,4 +392,22 @@ alter table test.t1 rename test.t1; ...@@ -392,4 +392,22 @@ alter table test.t1 rename test.t1;
use test; use test;
drop table t1; 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 # End of 4.1 tests
...@@ -2949,8 +2949,35 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2949,8 +2949,35 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->proc_info="setup"; thd->proc_info="setup";
if (alter_info->is_simple && !table->tmp_table) if (alter_info->is_simple && !table->tmp_table)
{ {
error=0; switch (alter_info->keys_onoff) {
if (new_name != table_name || new_db != db) 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"; thd->proc_info="rename";
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
...@@ -2971,27 +2998,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2971,27 +2998,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_unlock(&LOCK_open)); 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) if (error == HA_ERR_WRONG_COMMAND)
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 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, ...@@ -2999,6 +3005,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
table->table_name); table->table_name);
error=0; error=0;
} }
if (!error) if (!error)
{ {
mysql_update_log.write(thd, thd->query, thd->query_length); mysql_update_log.write(thd, thd->query, thd->query_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment