From 516f0d7518d5229862d131def7326a0934b43b9a Mon Sep 17 00:00:00 2001
From: unknown <andrey@example.com>
Date: Thu, 16 Nov 2006 14:01:51 +0100
Subject: [PATCH] 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.
---
 mysql-test/r/alter_table.result | 42 +++++++++++++--------------
 sql/sql_table.cc                | 51 ++++++++++++++++++---------------
 2 files changed, 49 insertions(+), 44 deletions(-)

diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index a8d7b917f37..ba8c11efbe1 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -428,42 +428,42 @@ t1	MyISAM	10	Fixed	1	37	X	X	X	X	X	X	X	X	latin1_swedish_ci	NULL
 drop table t1;
 set names koi8r;
 create table t1 (a char(10) character set koi8r);
-insert into t1 values ('脭脜脫脭');
+insert into t1 values ('耘釉');
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	D4C5D3D4
+耘釉	D4C5D3D4
 alter table t1 change a a char(10) character set cp1251;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	F2E5F1F2
+耘釉	F2E5F1F2
 alter table t1 change a a binary(4);
 select a,hex(a) from t1;
 a	hex(a)
-貌氓帽貌	F2E5F1F2
+蝈耱	F2E5F1F2
 alter table t1 change a a char(10) character set cp1251;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	F2E5F1F2
+耘釉	F2E5F1F2
 alter table t1 change a a char(10) character set koi8r;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	D4C5D3D4
+耘釉	D4C5D3D4
 alter table t1 change a a varchar(10) character set cp1251;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	F2E5F1F2
+耘釉	F2E5F1F2
 alter table t1 change a a char(10) character set koi8r;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	D4C5D3D4
+耘釉	D4C5D3D4
 alter table t1 change a a text character set cp1251;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	F2E5F1F2
+耘釉	F2E5F1F2
 alter table t1 change a a char(10) character set koi8r;
 select a,hex(a) from t1;
 a	hex(a)
-脭脜脫脭	D4C5D3D4
+耘釉	D4C5D3D4
 delete from t1;
 show create table t1;
 Table	Create Table
@@ -528,7 +528,7 @@ ALTER TABLE T12207 DISCARD TABLESPACE;
 ERROR HY000: Table storage engine for 'T12207' doesn't have this option
 DROP TABLE T12207;
 create table t1 (a text) character set koi8r;
-insert into t1 values (_koi8r'脭脜脫脭');
+insert into t1 values (_koi8r'耘釉');
 select hex(a) from t1;
 hex(a)
 D4C5D3D4
@@ -556,16 +556,6 @@ ERROR 3D000: No database selected
 alter table test.t1 rename test.t1;
 use test;
 drop table t1;
-create table t1 (mycol int(10) not null);
-alter table t1 alter column mycol set default 0;
-desc t1;
-Field	Type	Null	Key	Default	Extra
-mycol	int(10)	NO		0	
-drop table t1;
-create table t1 (t varchar(255) default null, key t (t(80)))
-engine=myisam default charset=latin1;
-alter table t1 change t t text;
-drop table t1;
 DROP TABLE IF EXISTS bug24219;
 DROP TABLE IF EXISTS bug24219_2;
 CREATE TABLE bug24219 (a INT, INDEX(a));
@@ -577,3 +567,13 @@ 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;
+create table t1 (mycol int(10) not null);
+alter table t1 alter column mycol set default 0;
+desc t1;
+Field	Type	Null	Key	Default	Extra
+mycol	int(10)	NO		0	
+drop table t1;
+create table t1 (t varchar(255) default null, key t (t(80)))
+engine=myisam default charset=latin1;
+alter table t1 change t t text;
+drop table t1;
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 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
   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 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
       }
     }
 
-    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 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
       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);
   }
-- 
2.30.9