Commit d63fa0a4 authored by unknown's avatar unknown
Browse files

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.
parent db42257d
Loading
Loading
Loading
Loading
+21 −21
Original line number Diff line number Diff line
@@ -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;
+28 −23
Original line number Diff line number Diff line
@@ -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,24 +3350,6 @@ 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,
@@ -3353,6 +3357,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
			  table->alias);
      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);
  }