summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorunknown <andrey@example.com>2006-11-16 14:01:51 +0100
committerunknown <andrey@example.com>2006-11-16 14:01:51 +0100
commitd63fa0a4078985e656e4c057583fc572add8d3a5 (patch)
tree24e96e21bb2b19afcae7133bcd7191800c783ad8 /sql/sql_table.cc
parentdb42257de8504d78046a6c5227491ce8edaebe29 (diff)
downloadmariadb-git-d63fa0a4078985e656e4c057583fc572add8d3a5.tar.gz
Fix for bug#24219 ALTER TABLE ... RENAME TO ... , DISABLE KEYS leads to crash
(this is the 5.0 patch, because 4.1 differs) 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: post-merge fix my locale is utf8, and this breaks non-utf8 stuff when doing manual merge :( 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.
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc51
1 files changed, 28 insertions, 23 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c76ebe7ef49..e7e08837b65 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3300,13 +3300,35 @@ view_err:
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
!table->s->tmp_table) // no need to touch frm
{
- error=0;
VOID(pthread_mutex_lock(&LOCK_open));
- if (new_name != table_name || new_db != db)
+
+ switch (alter_info->keys_onoff) {
+ case LEAVE_AS_IS:
+ error= 0;
+ break;
+ case ENABLE:
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ /* COND_refresh will be signaled in close_thread_tables() */
+ break;
+ case DISABLE:
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ 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->alias);
+ error= 0;
+ }
+
+ if (!error && (new_name != table_name || new_db != db))
{
thd->proc_info="rename";
/* Then do a 'simple' rename of the table */
- error=0;
if (!access(new_name_buff,F_OK))
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
@@ -3328,31 +3350,14 @@ view_err:
}
}
- if (!error)
- {
- switch (alter_info->keys_onoff) {
- case LEAVE_AS_IS:
- break;
- case ENABLE:
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
- /* COND_refresh will be signaled in close_thread_tables() */
- break;
- case DISABLE:
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- 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->alias);
- error=0;
+ error= 0;
}
+
if (!error)
{
if (mysql_bin_log.is_open())
@@ -3370,7 +3375,7 @@ view_err:
error= -1;
}
VOID(pthread_mutex_unlock(&LOCK_open));
- table_list->table=0; // For query cache
+ table_list->table= NULL; // For query cache
query_cache_invalidate3(thd, table_list, 0);
DBUG_RETURN(error);
}