diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-03-03 13:50:33 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-03-03 13:50:33 +0300 |
commit | 193725b81ed813d0318c1fa82de284c337246d9e (patch) | |
tree | 5491a62650565a58d24cfc629b7466f29b617d18 | |
parent | fa8ad7543947f5c74dece982d42bab59b6479449 (diff) | |
download | mariadb-git-193725b81ed813d0318c1fa82de284c337246d9e.tar.gz |
MDEV-7318 RENAME INDEX
This patch adds support of RENAME INDEX operation to the ALTER TABLE
statement. Code which determines if ALTER TABLE can be done in-place
for "simple" storage engines like MyISAM, Heap and etc. was updated to
handle ALTER TABLE ... RENAME INDEX as an in-place operation. Support
for in-place ALTER TABLE ... RENAME INDEX for InnoDB was covered by
MDEV-13301.
Syntax changes
==============
A new type of <alter_specification> is added:
<rename index clause> ::= RENAME ( INDEX | KEY ) <oldname> TO <newname>
Where <oldname> and <newname> are identifiers for old name and new
name of the index.
Semantic changes
================
The result of "ALTER TABLE t1 RENAME INDEX a TO b" is a table which
contents and structure are identical to the old version of 't1' with
the only exception index 'a' being called 'b'.
Neither <oldname> nor <newname> can be "primary". The index being
renamed should exist and its new name should not be occupied
by another index on the same table.
Related to: WL#6555, MDEV-13301
-rw-r--r-- | mysql-test/main/alter_table.result | 393 | ||||
-rw-r--r-- | mysql-test/main/alter_table.test | 180 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-alter-debug.result | 9 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_rename_index.result | 989 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-alter-debug.test | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb_rename_index.test | 538 | ||||
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/sql_alter.cc | 2 | ||||
-rw-r--r-- | sql/sql_alter.h | 4 | ||||
-rw-r--r-- | sql/sql_class.h | 15 | ||||
-rw-r--r-- | sql/sql_table.cc | 43 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 8 |
13 files changed, 2204 insertions, 2 deletions
diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 8a2a9d21f35..c2c5813a100 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -2849,5 +2849,398 @@ DROP VIEW v1; DROP TABLE t3,t1,t2; SET DEFAULT_STORAGE_ENGINE= @save_default_engine; # +# MDEV-7318 RENAME INDEX +# +# +# 1) Tests for syntax and semantics of ALTER TABLE RENAME +# KEY/INDEX result. +# +# 1.a) Both RENAME KEY and RENAME INDEX variants should be +# allowed and produce expected results. +create table t1 (pk int primary key, i int, j int, key a(i)); +alter table t1 rename key a to b; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `b` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename index b to c; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# 1.b) It should be impossible to rename index that doesn't +# exists, dropped or added within the same ALTER TABLE. +alter table t1 rename key d to e; +ERROR 42000: Key 'd' doesn't exist in table 't1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 drop key c, rename key c to d; +ERROR 42000: Key 'c' doesn't exist in table 't1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 add key d(j), rename key d to e; +ERROR 42000: Key 'd' doesn't exist in table 't1' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# 1.c) It should be impossible to rename index to a name +# which is already used by another index, or is used +# by index which is added within the same ALTER TABLE. +alter table t1 add key d(j); +alter table t1 rename key c to d; +ERROR 42000: Duplicate key name 'd' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`), + KEY `d` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 drop key d; +alter table t1 add key d(j), rename key c to d; +ERROR 42000: Duplicate key name 'd' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# 1.d) It should be possible to rename index to a name +# which belongs to index which is dropped within the +# same ALTER TABLE. +alter table t1 add key d(j); +alter table t1 drop key c, rename key d to c; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# 1.e) We disallow renaming from/to PRIMARY as it might +# lead to some other key becoming "primary" internally, +# which will be interpreted as dropping/addition of +# primary key. +alter table t1 rename key primary to d; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'primary to d' at line 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# Even using 'funny' syntax. +alter table t1 rename key `primary` to d; +ERROR 42000: Incorrect index name 'primary' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key c to primary; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'primary' at line 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key c to `primary`; +ERROR 42000: Incorrect index name 'primary' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `i` int(11) DEFAULT NULL, + `j` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `c` (`j`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# +# 2) More complex tests for semantics of ALTER TABLE. +# +# 2.a) Check that standalone RENAME KEY works as expected +# for unique and non-unique indexes. +create table t1 (a int, unique u(a), b int, key k(b)); +alter table t1 rename key u to uu; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + UNIQUE KEY `uu` (`a`), + KEY `k` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key k to kk; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + UNIQUE KEY `uu` (`a`), + KEY `kk` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +# 2.b) Check how that this clause can be mixed with other +# clauses which don't affect key or its columns. +alter table t1 rename key kk to kkk, add column c int; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + UNIQUE KEY `uu` (`a`), + KEY `kkk` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key uu to uuu, add key c(c); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + UNIQUE KEY `uuu` (`a`), + KEY `kkk` (`b`), + KEY `c` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key kkk to k, drop key uuu; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `k` (`b`), + KEY `c` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 rename key k to kk, rename to t2; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + KEY `kk` (`b`), + KEY `c` (`c`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; +# +# 3) Test coverage for handling of RENAME INDEX clause in +# various storage engines and using different ALTER +# algorithm. +# +# 3.a) Test coverage for simple storage engines (MyISAM/Heap). +create table t1 (i int, key k(i)) engine=myisam; +insert into t1 values (1); +create table t2 (i int, key k(i)) engine=memory; +insert into t2 values (1); +# MyISAM and Heap should be able to handle key renaming in-place. +alter table t1 algorithm=inplace, rename key k to kk; +alter table t2 algorithm=inplace, rename key k to kk; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + KEY `kk` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT NULL, + KEY `kk` (`i`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +# So by default in-place algorithm should be chosen. +# (ALTER TABLE should report 0 rows affected). +alter table t1 rename key kk to kkk; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +alter table t2 rename key kk to kkk; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + KEY `kkk` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT NULL, + KEY `kkk` (`i`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +# Copy algorithm should work as well. +alter table t1 algorithm=copy, rename key kkk to kkkk; +alter table t2 algorithm=copy, rename key kkk to kkkk; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + KEY `kkkk` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT NULL, + KEY `kkkk` (`i`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +# When renaming is combined with other in-place operation +# it still works as expected (i.e. works in-place). +alter table t1 algorithm=inplace, rename key kkkk to k, alter column i set default 100; +alter table t2 algorithm=inplace, rename key kkkk to k, alter column i set default 100; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT 100, + KEY `k` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT 100, + KEY `k` (`i`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +# Combining with non-inplace operation results in the whole ALTER +# becoming non-inplace. +alter table t1 algorithm=inplace, rename key k to kk, add column j int; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t2 algorithm=inplace, rename key k to kk, add column j int; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +drop table t1, t2; +# 3.b) Basic tests for InnoDB. More tests can be found in +# innodb.innodb_rename_index* +create table t1 (i int, key k(i)) engine=innodb; +insert into t1 values (1); +# Basic rename, inplace algorithm should be chosen +alter table t1 algorithm=inplace, rename key k to kk; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + KEY `kk` (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +# copy algorithm should work as well. +alter table t1 algorithm=copy, rename key kk to kkk; +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + KEY `kkk` (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +# +# 4) Additional coverage for complex cases in which code +# in ALTER TABLE comparing old and new table version +# got confused. +# +# Once InnoDB starts to support in-place index renaming the result +# of below statements should stay the same. Information about +# indexes returned by SHOW CREATE TABLE (from .FRM) and by +# InnoDB (from InnoDB data-dictionary) should be consistent. +# +create table t1 ( a int, b int, c int, d int, +primary key (a), index i1 (b), index i2 (c) ) engine=innodb; +alter table t1 add index i1 (d), rename index i1 to x; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `x` (`b`), + KEY `i2` (`c`), + KEY `i1` (`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +select i.name as k, f.name as c from information_schema.innodb_sys_tables as t, +information_schema.innodb_sys_indexes as i, +information_schema.innodb_sys_fields as f +where t.name='test/t1' and t.table_id = i.table_id and i.index_id = f.index_id +order by k, c; +k c +i1 d +i2 c +PRIMARY a +x b +drop table t1; +create table t1 (a int, b int, c int, d int, +primary key (a), index i1 (b), index i2 (c)) engine=innodb; +alter table t1 add index i1 (d), rename index i1 to i2, drop index i2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i2` (`b`), + KEY `i1` (`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +select i.name as k, f.name as c from information_schema.innodb_sys_tables as t, +information_schema.innodb_sys_indexes as i, +information_schema.innodb_sys_fields as f +where t.name='test/t1' and t.table_id = i.table_id and i.index_id = f.index_id +order by k, c; +k c +i1 d +i2 b +PRIMARY a +drop table t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index ccd2ee953b1..19f9777d803 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2274,5 +2274,185 @@ DROP TABLE t3,t1,t2; SET DEFAULT_STORAGE_ENGINE= @save_default_engine; --echo # +--echo # MDEV-7318 RENAME INDEX +--echo # + +--echo # +--echo # 1) Tests for syntax and semantics of ALTER TABLE RENAME +--echo # KEY/INDEX result. +--echo # +--echo # 1.a) Both RENAME KEY and RENAME INDEX variants should be +--echo # allowed and produce expected results. +create table t1 (pk int primary key, i int, j int, key a(i)); +alter table t1 rename key a to b; +show create table t1; +alter table t1 rename index b to c; +show create table t1; + +--echo # 1.b) It should be impossible to rename index that doesn't +--echo # exists, dropped or added within the same ALTER TABLE. +--error ER_KEY_DOES_NOT_EXITS +alter table t1 rename key d to e; +show create table t1; +--error ER_KEY_DOES_NOT_EXITS +alter table t1 drop key c, rename key c to d; +show create table t1; +--error ER_KEY_DOES_NOT_EXITS +alter table t1 add key d(j), rename key d to e; +show create table t1; + +--echo # 1.c) It should be impossible to rename index to a name +--echo # which is already used by another index, or is used +--echo # by index which is added within the same ALTER TABLE. +alter table t1 add key d(j); +--error ER_DUP_KEYNAME +alter table t1 rename key c to d; +show create table t1; +alter table t1 drop key d; +--error ER_DUP_KEYNAME +alter table t1 add key d(j), rename key c to d; +show create table t1; + +--echo # 1.d) It should be possible to rename index to a name +--echo # which belongs to index which is dropped within the +--echo # same ALTER TABLE. +alter table t1 add key d(j); +alter table t1 drop key c, rename key d to c; +show create table t1; + +--echo # 1.e) We disallow renaming from/to PRIMARY as it might +--echo # lead to some other key becoming "primary" internally, +--echo # which will be interpreted as dropping/addition of +--echo # primary key. +--error ER_PARSE_ERROR +alter table t1 rename key primary to d; +show create table t1; +--echo # Even using 'funny' syntax. +--error ER_WRONG_NAME_FOR_INDEX +alter table t1 rename key `primary` to d; +show create table t1; +--error ER_PARSE_ERROR +alter table t1 rename key c to primary; +show create table t1; +--error ER_WRONG_NAME_FOR_INDEX +alter table t1 rename key c to `primary`; +show create table t1; +drop table t1; + + +--echo # +--echo # 2) More complex tests for semantics of ALTER TABLE. +--echo # +--echo # 2.a) Check that standalone RENAME KEY works as expected +--echo # for unique and non-unique indexes. +create table t1 (a int, unique u(a), b int, key k(b)); +alter table t1 rename key u to uu; +show create table t1; +alter table t1 rename key k to kk; +show create table t1; + +--echo # 2.b) Check how that this clause can be mixed with other +--echo # clauses which don't affect key or its columns. +alter table t1 rename key kk to kkk, add column c int; +show create table t1; +alter table t1 rename key uu to uuu, add key c(c); +show create table t1; +alter table t1 rename key kkk to k, drop key uuu; +show create table t1; +alter table t1 rename key k to kk, rename to t2; +show create table t2; +drop table t2; + + +--echo # +--echo # 3) Test coverage for handling of RENAME INDEX clause in +--echo # various storage engines and using different ALTER +--echo # algorithm. +--echo # +--echo # 3.a) Test coverage for simple storage engines (MyISAM/Heap). +create table t1 (i int, key k(i)) engine=myisam; +insert into t1 values (1); +create table t2 (i int, key k(i)) engine=memory; +insert into t2 values (1); +--echo # MyISAM and Heap should be able to handle key renaming in-place. +alter table t1 algorithm=inplace, rename key k to kk; +alter table t2 algorithm=inplace, rename key k to kk; +show create table t1; +show create table t2; +--echo # So by default in-place algorithm should be chosen. +--echo # (ALTER TABLE should report 0 rows affected). +--enable_info +alter table t1 rename key kk to kkk; +alter table t2 rename key kk to kkk; +--disable_info +show create table t1; +show create table t2; +--echo # Copy algorithm should work as well. +alter table t1 algorithm=copy, rename key kkk to kkkk; +alter table t2 algorithm=copy, rename key kkk to kkkk; +show create table t1; +show create table t2; +--echo # When renaming is combined with other in-place operation +--echo # it still works as expected (i.e. works in-place). +alter table t1 algorithm=inplace, rename key kkkk to k, alter column i set default 100; +alter table t2 algorithm=inplace, rename key kkkk to k, alter column i set default 100; +show create table t1; +show create table t2; +--echo # Combining with non-inplace operation results in the whole ALTER +--echo # becoming non-inplace. +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 algorithm=inplace, rename key k to kk, add column j int; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t2 algorithm=inplace, rename key k to kk, add column j int; +drop table t1, t2; + +--echo # 3.b) Basic tests for InnoDB. More tests can be found in +--echo # innodb.innodb_rename_index* +create table t1 (i int, key k(i)) engine=innodb; +insert into t1 values (1); +--echo # Basic rename, inplace algorithm should be chosen +--enable_info +alter table t1 algorithm=inplace, rename key k to kk; +--disable_info +show create table t1; +--echo # copy algorithm should work as well. +--enable_info +alter table t1 algorithm=copy, rename key kk to kkk; +--disable_info +show create table t1; +drop table t1; + +--echo # +--echo # 4) Additional coverage for complex cases in which code +--echo # in ALTER TABLE comparing old and new table version +--echo # got confused. +--echo # +--echo # Once InnoDB starts to support in-place index renaming the result +--echo # of below statements should stay the same. Information about +--echo # indexes returned by SHOW CREATE TABLE (from .FRM) and by +--echo # InnoDB (from InnoDB data-dictionary) should be consistent. +--echo # +create table t1 ( a int, b int, c int, d int, + primary key (a), index i1 (b), index i2 (c) ) engine=innodb; +alter table t1 add index i1 (d), rename index i1 to x; +show create table t1; +select i.name as k, f.name as c from information_schema.innodb_sys_tables as t, + information_schema.innodb_sys_indexes as i, + information_schema.innodb_sys_fields as f +where t.name='test/t1' and t.table_id = i.table_id and i.index_id = f.index_id +order by k, c; +drop table t1; +create table t1 (a int, b int, c int, d int, + primary key (a), index i1 (b), index i2 (c)) engine=innodb; +alter table t1 add index i1 (d), rename index i1 to i2, drop index i2; +show create table t1; +select i.name as k, f.name as c from information_schema.innodb_sys_tables as t, + information_schema.innodb_sys_indexes as i, + information_schema.innodb_sys_fields as f +where t.name='test/t1' and t.table_id = i.table_id and i.index_id = f.index_id +order by k, c; +drop table t1; + +--echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result index 51ba58aa1ef..48722bbea44 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-debug.result +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -98,3 +98,12 @@ disconnect con1; connection default; UNLOCK TABLES; DROP TABLE t1; +# +# MDEV-7318 RENAME INDEX +# +CREATE TABLE t (c1 INT, c2 INT, KEY i2 (c2)) ENGINE=INNODB; +SET DEBUG_DBUG= '+d,ib_rename_index_fail1'; +ALTER TABLE t RENAME INDEX i2 to x, ALGORITHM=INPLACE; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET DEBUG_DBUG= '-d,ib_rename_index_fail1'; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/innodb_rename_index.result b/mysql-test/suite/innodb/r/innodb_rename_index.result new file mode 100644 index 00000000000..482070c4ffc --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_rename_index.result @@ -0,0 +1,989 @@ +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t RENAME INDEX i1 TO GEN_CLUST_INDEX; +ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' +ALTER TABLE t RENAME INDEX i1 TO i1; +ALTER TABLE t RENAME INDEX aa TO aa; +ERROR 42000: Key 'aa' doesn't exist in table 't' +# combination: aaaa +ALTER TABLE t ADD INDEX i4(f), DROP INDEX i4, RENAME INDEX i4 TO i4; +ERROR 42000: Key 'i4' doesn't exist in table 't' +# combination: aabb +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX i2 TO i2; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX bb TO bb; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX bb TO bb; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i2 TO i2; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `i1` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i1 f +test/t i2 c +test/t i3 d +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: abcc +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX cc TO cc; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX i3 TO i3; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO cc; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO i3; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i1` (`b`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `aa` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t aa f +test/t i1 b +test/t i3 d +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: abaa +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i1, RENAME INDEX aa TO aa; +ERROR 42000: Key 'aa' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i1 TO i1; +ERROR 42000: Duplicate key name 'i1' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX i1 TO i1; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX aa TO aa; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +# combination: baaa +ALTER TABLE t ADD INDEX i2(f), DROP INDEX i1, RENAME INDEX i1 TO i1; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX bb(f), DROP INDEX i1, RENAME INDEX i1 TO i1; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i2(f), DROP INDEX aa, RENAME INDEX aa TO aa; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX bb(f), DROP INDEX aa, RENAME INDEX aa TO aa; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX aa TO bb; +ERROR 42000: Key 'aa' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX bb TO aa; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX i2 TO aa; +ERROR 42000: Duplicate key name 'aa' +ALTER TABLE t ADD INDEX i1(f), RENAME INDEX i1 TO bb; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `bb` (`b`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `i1` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t bb b +test/t i1 f +test/t i2 c +test/t i3 d +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: abba +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i2 TO i1; +ERROR 42000: Key 'i2' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i2 TO aa; +ERROR 42000: Key 'i2' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX bb TO i1; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX bb TO aa; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +# combination: cabc +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i2 TO i3; +ERROR 42000: Duplicate key name 'i3' +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i2 TO i3; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX bb TO i3; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX bb TO i3; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX i2 TO cc; +ERROR 42000: Duplicate key name 'cc' +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX i2 TO cc; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX bb TO cc; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX bb TO cc; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t DROP INDEX i1, RENAME INDEX i1 TO bb; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t DROP INDEX aa, RENAME INDEX i2 TO aa; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t DROP INDEX aa, RENAME INDEX aa TO i2; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t DROP INDEX i1, RENAME INDEX i4 TO i1; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i1` (`e`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i1 e +test/t i2 c +test/t i3 d +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: accb +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i3 TO i2; +ERROR 42000: Key 'i3' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i3 TO bb; +ERROR 42000: Key 'i3' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX cc TO i2; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX cc TO bb; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX cc TO i2; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX cc TO bb; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +# combination: aaab +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO i2; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO bb; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO i2; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX aa TO bb; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +# combination: abcd +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX cc TO i4; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX cc TO dd; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO i4; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO dd; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i3 TO i4; +ERROR 42000: Duplicate key name 'i4' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i3 TO dd; +ERROR 42000: Duplicate key name 'i1' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO i4; +ERROR 42000: Duplicate key name 'i4' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO dd; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i1` (`b`), + KEY `dd` (`d`), + KEY `i4` (`e`), + KEY `aa` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t aa f +test/t dd d +test/t i1 b +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: abab +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i1 TO i2; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i2` (`b`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `i1` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i1 f +test/t i2 b +test/t i3 d +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX i1 TO bb; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX aa TO i2; +ERROR 42000: Key 'aa' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX aa TO bb; +ERROR 42000: Can't DROP INDEX `bb`; check that it exists +# combination: acbc +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX i2 TO cc; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX i2 TO cc; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX bb TO cc; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX bb TO cc; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX bb TO i3; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i3, RENAME INDEX bb TO i3; +ERROR 42000: Key 'bb' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i2 TO i3; +ERROR 42000: Duplicate key name 'i1' +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i3, RENAME INDEX i2 TO i3; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i1` (`b`), + KEY `i3` (`c`), + KEY `i4` (`e`), + KEY `aa` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t aa f +test/t i1 b +test/t i3 c +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: cacb +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX cc TO i2; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX cc TO i2; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX cc TO bb; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX cc TO bb; +ERROR 42000: Key 'cc' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i3 TO i2; +ERROR 42000: Duplicate key name 'i2' +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i3 TO i2; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i3 TO bb; +ERROR 42000: Can't DROP INDEX `aa`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i3 TO bb; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i2` (`c`), + KEY `bb` (`d`), + KEY `i4` (`e`), + KEY `i3` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t bb d +test/t i2 c +test/t i3 f +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +# combination: ccab +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX i1 TO i2; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX i1 TO bb; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX aa TO i2; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX aa TO bb; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX cc, RENAME INDEX aa TO i2; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX cc, RENAME INDEX aa TO bb; +ERROR 42000: Can't DROP INDEX `cc`; check that it exists +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i3, RENAME INDEX i1 TO i2; +ERROR 42000: Duplicate key name 'i2' +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i3, RENAME INDEX i1 TO bb; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `bb` (`b`), + KEY `i2` (`c`), + KEY `i4` (`e`), + KEY `i3` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t bb b +test/t i2 c +test/t i3 f +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t RENAME INDEX i1 TO x; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `x` (`b`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i2 c +test/t i3 d +test/t i4 e +test/t PRIMARY a +test/t x b +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t RENAME INDEX i1 TO i2; +ERROR 42000: Duplicate key name 'i2' +ALTER TABLE t RENAME INDEX foo TO i1; +ERROR 42000: Key 'foo' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i9 (f), RENAME INDEX i1 TO i8; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i8` (`b`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `i9` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i2 c +test/t i3 d +test/t i4 e +test/t i8 b +test/t i9 f +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO i9; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i9` (`b`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`), + KEY `i1` (`f`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i1 f +test/t i2 c +test/t i3 d +test/t i4 e +test/t i9 b +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT, +d INT, +e INT, +f INT, +PRIMARY KEY (a), +INDEX i1 (b), +INDEX i2 (c), +INDEX i3 (d), +INDEX i4 (e) +) ENGINE=INNODB; +INSERT INTO t SET a = 1; +ALTER TABLE t ADD INDEX foo (f), RENAME INDEX i1 TO foo; +ERROR 42000: Duplicate key name 'foo' +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO foo, DROP INDEX i1; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO foo, DROP INDEX foo; +ERROR 42000: Can't DROP INDEX `foo`; check that it exists +ALTER TABLE t ADD INDEX foo (f), RENAME INDEX foo TO bar, DROP INDEX foo; +ERROR 42000: Can't DROP INDEX `foo`; check that it exists +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i2 TO x; +ERROR 42000: Duplicate key name 'x' +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i1 TO y; +ERROR 42000: Key 'i1' doesn't exist in table 't' +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i1 TO x; +ERROR 42000: Key 'i1' doesn't exist in table 't' +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` int(11) DEFAULT NULL, + `f` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `i1` (`b`), + KEY `i2` (`c`), + KEY `i3` (`d`), + KEY `i4` (`e`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i1 b +test/t i2 c +test/t i3 d +test/t i4 e +test/t PRIMARY a +DROP TABLE t; +CREATE TABLE t ( +c1 INT NOT NULL, +c2 INT NOT NULL, +c3 INT, +c4 INT, +PRIMARY KEY (c1), +INDEX i1 (c3), +INDEX i2 (c4) +) ENGINE=INNODB; +INSERT INTO t SET c1=1, c2=2; +ALTER TABLE t DROP PRIMARY KEY, ADD PRIMARY KEY (c2), RENAME INDEX i1 TO x; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `c1` int(11) NOT NULL, + `c2` int(11) NOT NULL, + `c3` int(11) DEFAULT NULL, + `c4` int(11) DEFAULT NULL, + PRIMARY KEY (`c2`), + KEY `x` (`c3`), + KEY `i2` (`c4`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i2 c4 +test/t PRIMARY c2 +test/t x c3 +ALTER TABLE t RENAME INDEX i2 TO y, ROW_FORMAT=REDUNDANT; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `c1` int(11) NOT NULL, + `c2` int(11) NOT NULL, + `c3` int(11) DEFAULT NULL, + `c4` int(11) DEFAULT NULL, + PRIMARY KEY (`c2`), + KEY `x` (`c3`), + KEY `y` (`c4`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t PRIMARY c2 +test/t x c3 +test/t y c4 +DROP TABLE t; +CREATE TABLE t ( +c1 INT NOT NULL, +c2 INT, +c3 INT, +INDEX i1 (c2), +INDEX i2 (c3) +) ENGINE=INNODB; +INSERT INTO t SET c1=1; +ALTER TABLE t ADD PRIMARY KEY (c1), RENAME INDEX i1 TO x; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `c1` int(11) NOT NULL, + `c2` int(11) DEFAULT NULL, + `c3` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `x` (`c2`), + KEY `i2` (`c3`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; +table_name index_name column_name +test/t i2 c3 +test/t PRIMARY c1 +test/t x c2 +DROP TABLE t; +CREATE TABLE t (a INT, INDEX iiiii (a)) ENGINE=INNODB; +INSERT INTO t SET a=NULL; +ALTER TABLE t RENAME INDEX iiiii TO i; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t RENAME INDEX i TO iiiii; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t RENAME INDEX iiiii TO i; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t RENAME INDEX i TO iiiii; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index 00300bfdccc..792716aeb4e 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -132,3 +132,15 @@ DROP TABLE t1; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc + +--echo # +--echo # MDEV-7318 RENAME INDEX +--echo # +CREATE TABLE t (c1 INT, c2 INT, KEY i2 (c2)) ENGINE=INNODB; + +SET DEBUG_DBUG= '+d,ib_rename_index_fail1'; +-- error ER_LOCK_DEADLOCK +ALTER TABLE t RENAME INDEX i2 to x, ALGORITHM=INPLACE; +SET DEBUG_DBUG= '-d,ib_rename_index_fail1'; + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_rename_index.test b/mysql-test/suite/innodb/t/innodb_rename_index.test new file mode 100644 index 00000000000..9236259b279 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_rename_index.test @@ -0,0 +1,538 @@ +--source include/have_innodb.inc + +# +# Test "ALTER TABLE ... RENAME INDEX" in InnoDB +# + +let create = +CREATE TABLE t ( + a INT, + b INT, + c INT, + d INT, + e INT, + f INT, + PRIMARY KEY (a), + INDEX i1 (b), + INDEX i2 (c), + INDEX i3 (d), + INDEX i4 (e) +) ENGINE=INNODB; + +let insert = INSERT INTO t SET a = 1; + +let show_table = +SHOW CREATE TABLE t; + +let show_sys = +SELECT +t.name AS table_name, +i.name AS index_name, +f.name AS column_name +FROM +information_schema.innodb_sys_tables t, +information_schema.innodb_sys_indexes i, +information_schema.innodb_sys_fields f +WHERE +t.name LIKE '%/t' AND +t.table_id = i.table_id AND +i.index_id = f.index_id +ORDER BY 1, 2, 3; + +-- eval $create + +# Add a row, so that affected rows would be nonzero for ALGORITHM=COPY. +# ALGORITHM=INPLACE will report 0 affected row in the result file. +# We will have enable_info/disable_info around every successful ALTER +# to enable the affected rows: output in the result file. +-- eval $insert + +-- error ER_WRONG_NAME_FOR_INDEX +ALTER TABLE t RENAME INDEX i1 TO GEN_CLUST_INDEX; + +# Test all combinations of ADD w, DROP x, RENAME y TO z. +# +# Use the following names for wxyz (with 1 to 4 of wxyz being the same): +# aaaa abcd aabb abab abba abcc acbc accb cacb cabc ccab aaab aaba abaa baaa +# +# Some cases should trivially succeed or fail. Test them in isolation: +# no-op: y=z (RENAME y TO y) +# rules out the combinations ..\(.\)\1 +# a.k.a. aaaa aabb abcc abaa baaa + +# We use the index names i1 to i4 for existing indexes abcd. +# Non-existing index names will be aa,bb,cc,dd. +# Index creation on non-existing columns will not be tested. + +ALTER TABLE t RENAME INDEX i1 TO i1; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t RENAME INDEX aa TO aa; + +-- echo # combination: aaaa +# drop/add existing, null rename and drop the same +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i4(f), DROP INDEX i4, RENAME INDEX i4 TO i4; + +-- echo # combination: aabb +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX i2 TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX bb TO bb; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX bb TO bb; + +-- enable_info +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i2 TO i2; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: abcc + +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX cc TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX i3 TO i3; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO cc; + +# rename existing (succeeds) +-- enable_info +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO i3; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: abaa + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i1, RENAME INDEX aa TO aa; +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i1 TO i1; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX i1 TO i1; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX aa TO aa; + +-- echo # combination: baaa + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i2(f), DROP INDEX i1, RENAME INDEX i1 TO i1; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX bb(f), DROP INDEX i1, RENAME INDEX i1 TO i1; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i2(f), DROP INDEX aa, RENAME INDEX aa TO aa; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX bb(f), DROP INDEX aa, RENAME INDEX aa TO aa; + +# refuse: w=z (ADD w, RENAME y TO w) +# rules out the combinations \(.\)..\1 +# a.k.a. aaaa abba cabc aaba abaa +# the case w=y (ADD w, RENAME w to z) may succeed, as seen below + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX aa TO bb; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX bb TO aa; +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX aa(f), RENAME INDEX i2 TO aa; + +# rename existing, add one with the same name +-- enable_info +ALTER TABLE t ADD INDEX i1(f), RENAME INDEX i1 TO bb; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: abba + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i2 TO i1; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i2 TO aa; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX bb TO i1; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX bb TO aa; + +-- echo # combination: cabc + +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i2 TO i3; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i2 TO i3; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX bb TO i3; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX bb TO i3; + +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX i2 TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX i2 TO cc; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX bb TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX bb TO cc; + +# refuse: x=y (DROP x, RENAME x TO z) +# rules out the combinations .\(.\)\1. +# a.k.a. aaaa abba accb aaab baaa + +# rename and drop the same +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t DROP INDEX i1, RENAME INDEX i1 TO bb; +# drop non-existing +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t DROP INDEX aa, RENAME INDEX i2 TO aa; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t DROP INDEX aa, RENAME INDEX aa TO i2; + +# this one will succeed (drop, replace with an existing one) +-- enable_info +ALTER TABLE t DROP INDEX i1, RENAME INDEX i4 TO i1; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: accb + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i3 TO i2; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i3 TO bb; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX cc TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX cc TO bb; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX cc TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX cc TO bb; + +-- echo # combination: aaab + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO i2; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO bb; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i1, RENAME INDEX i1 TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX aa, RENAME INDEX aa TO bb; + +# Remaining combinations: abcd abab acbc cacb ccab + +-- echo # combination: abcd + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX cc TO i4; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX cc TO dd; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO i4; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX cc TO dd; + +# add existing, rename to existing +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i3 TO i4; +# add existing +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i3 TO dd; +# rename to existing +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO i4; + +-- enable_info +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX i3 TO dd; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: abab + +-- enable_info +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i2, RENAME INDEX i1 TO i2; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX bb, RENAME INDEX i1 TO bb; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i2, RENAME INDEX aa TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX bb, RENAME INDEX aa TO bb; + +-- echo # combination: acbc + +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX i2 TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX i2 TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1(f), DROP INDEX cc, RENAME INDEX bb TO cc; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX aa(f), DROP INDEX cc, RENAME INDEX bb TO cc; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX bb TO i3; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i3, RENAME INDEX bb TO i3; + +# add existing +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i1(f), DROP INDEX i3, RENAME INDEX i2 TO i3; + +-- enable_info +ALTER TABLE t ADD INDEX aa(f), DROP INDEX i3, RENAME INDEX i2 TO i3; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: cacb + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX cc TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX cc TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX aa, RENAME INDEX cc TO bb; +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX cc(f), DROP INDEX i1, RENAME INDEX cc TO bb; + +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i3 TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i3 TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX aa, RENAME INDEX i3 TO bb; + +-- enable_info +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i1, RENAME INDEX i3 TO bb; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- echo # combination: ccab + +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX i1 TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX i1 TO bb; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX aa TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX cc(f), DROP INDEX cc, RENAME INDEX aa TO bb; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX cc, RENAME INDEX aa TO i2; +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i3(f), DROP INDEX cc, RENAME INDEX aa TO bb; + +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i3, RENAME INDEX i1 TO i2; + +-- enable_info +ALTER TABLE t ADD INDEX i3(f), DROP INDEX i3, RENAME INDEX i1 TO bb; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +# A simple successful ALTER +-- enable_info +ALTER TABLE t RENAME INDEX i1 TO x; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- error ER_DUP_KEYNAME +ALTER TABLE t RENAME INDEX i1 TO i2; + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t RENAME INDEX foo TO i1; + +# Test ADD INDEX, RENAME INDEX + +-- enable_info +ALTER TABLE t ADD INDEX i9 (f), RENAME INDEX i1 TO i8; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- enable_info +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO i9; +-- disable_info +-- eval $show_table +-- eval $show_sys +DROP TABLE t; +-- eval $create +-- eval $insert + +-- error ER_DUP_KEYNAME +ALTER TABLE t ADD INDEX foo (f), RENAME INDEX i1 TO foo; + +# Test ADD INDEX, RENAME INDEX, DROP INDEX + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO foo, DROP INDEX i1; + +-- error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t ADD INDEX i1 (f), RENAME INDEX i1 TO foo, DROP INDEX foo; + +-- error ER_CANT_DROP_FIELD_OR_KEY +# "ALTER TABLE t ADD INDEX foo (d), DROP INDEX foo;" alone fails with the +# same error code, but we have that test here anyway +ALTER TABLE t ADD INDEX foo (f), RENAME INDEX foo TO bar, DROP INDEX foo; + +# Test RENAME INDEX, RENAME INDEX + +-- error ER_DUP_KEYNAME +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i2 TO x; + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i1 TO y; + +-- error ER_KEY_DOES_NOT_EXITS +ALTER TABLE t RENAME INDEX i1 TO x, RENAME INDEX i1 TO x; + +# show that the table did not change after all the erroneous ALTERs +-- eval $show_table +-- eval $show_sys + +DROP TABLE t; + +# now test the rebuild case (new clustered index) + +CREATE TABLE t ( + c1 INT NOT NULL, + c2 INT NOT NULL, + c3 INT, + c4 INT, + PRIMARY KEY (c1), + INDEX i1 (c3), + INDEX i2 (c4) +) ENGINE=INNODB; + +INSERT INTO t SET c1=1, c2=2; + +-- enable_info +ALTER TABLE t DROP PRIMARY KEY, ADD PRIMARY KEY (c2), RENAME INDEX i1 TO x; +-- disable_info + +-- eval $show_table +-- eval $show_sys + +-- enable_info +ALTER TABLE t RENAME INDEX i2 TO y, ROW_FORMAT=REDUNDANT; +-- disable_info + +-- eval $show_table +-- eval $show_sys + +DROP TABLE t; + +# a case where the PK does not exist prior to the ALTER TABLE command + +CREATE TABLE t ( + c1 INT NOT NULL, + c2 INT, + c3 INT, + INDEX i1 (c2), + INDEX i2 (c3) +) ENGINE=INNODB; + +INSERT INTO t SET c1=1; + +-- enable_info +ALTER TABLE t ADD PRIMARY KEY (c1), RENAME INDEX i1 TO x; +-- disable_info +-- eval $show_table +-- eval $show_sys + +DROP TABLE t; + +# Test repeated RENAMEs with alternating names + +CREATE TABLE t (a INT, INDEX iiiii (a)) ENGINE=INNODB; +INSERT INTO t SET a=NULL; +-- enable_info +ALTER TABLE t RENAME INDEX iiiii TO i; +ALTER TABLE t RENAME INDEX i TO iiiii; +ALTER TABLE t RENAME INDEX iiiii TO i; +ALTER TABLE t RENAME INDEX i TO iiiii; +-- disable_info +DROP TABLE t; + +# Below is a shell script to generate the full set of ALTER TABLE +# DROP/ADD/RENAME combinations. The generated .sql file is 3.3MB and +# executes in about 7 minutes. +# +##!/bin/sh +# +#create=" +#CREATE TABLE t ( +# a INT, +# b INT, +# c INT, +# d INT, +# PRIMARY KEY (a), +# INDEX i1 (b), +# INDEX i2 (c) +#) ENGINE=INNODB; +#" +# +#echo "DROP TABLE IF EXISTS t;" +#for r in "" ", DROP PRIMARY KEY, ADD PRIMARY KEY (a)" ", ROW_FORMAT=REDUNDANT" ; do +# for i1 in i1 i1noexist; do +# for i2 in i2 i2noexist; do +# for i3 in i3 i3noexist; do +# for i4 in i4 i4noexist; do +# for a in $i1 $i2 $i3 $i4; do +# for b in $i1 $i2 $i3 $i4; do +# for c in $i1 $i2 $i3 $i4; do +# for d in $i1 $i2 $i3 $i4; do +# echo "$create" +# echo "ALTER TABLE t ADD INDEX $a (d), RENAME INDEX $b TO $c, DROP INDEX $d $r;" +# echo "DROP TABLE t;" +# done +# done +# done +# done +# done +# done +# done +# done +#done diff --git a/sql/handler.cc b/sql/handler.cc index 7d61252eea6..806d91bdbc5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4585,7 +4585,8 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, ALTER_DROP_CHECK_CONSTRAINT | ALTER_PARTITIONED | ALTER_VIRTUAL_GCOL_EXPR | - ALTER_RENAME; + ALTER_RENAME | + ALTER_RENAME_INDEX; /* Is there at least one operation that requires copy algorithm? */ if (ha_alter_info->handler_flags & ~inplace_offline_operations) diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 0828e1b7ba8..23e2e3e097f 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -25,6 +25,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) :drop_list(rhs.drop_list, mem_root), alter_list(rhs.alter_list, mem_root), key_list(rhs.key_list, mem_root), + alter_rename_key_list(rhs.alter_rename_key_list, mem_root), create_list(rhs.create_list, mem_root), check_constraint_list(rhs.check_constraint_list, mem_root), flags(rhs.flags), partition_flags(rhs.partition_flags), @@ -46,6 +47,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) list_copy_and_replace_each_value(drop_list, mem_root); list_copy_and_replace_each_value(alter_list, mem_root); list_copy_and_replace_each_value(key_list, mem_root); + list_copy_and_replace_each_value(alter_rename_key_list, mem_root); list_copy_and_replace_each_value(create_list, mem_root); /* partition_names are not deeply copied currently */ } diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 41408a91836..a553c31346a 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -19,6 +19,7 @@ class Alter_drop; class Alter_column; +class Alter_rename_key; class Key; /** @@ -87,6 +88,8 @@ public: List<Alter_column> alter_list; // List of keys, used by both CREATE and ALTER TABLE. List<Key> key_list; + // List of keys to be renamed. + List<Alter_rename_key> alter_rename_key_list; // List of columns, used by both CREATE and ALTER TABLE. List<Create_field> create_list; @@ -123,6 +126,7 @@ public: drop_list.empty(); alter_list.empty(); key_list.empty(); + alter_rename_key_list.empty(); create_list.empty(); check_constraint_list.empty(); flags= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 6a7c0cd4d94..123bf0c0583 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -355,6 +355,21 @@ public: }; +class Alter_rename_key : public Sql_alloc +{ +public: + LEX_CSTRING old_name; + LEX_CSTRING new_name; + + Alter_rename_key(LEX_CSTRING old_name_arg, LEX_CSTRING new_name_arg) + : old_name(old_name_arg), new_name(new_name_arg) {} + + Alter_rename_key *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Alter_rename_key(*this); } + +}; + + class Key :public Sql_alloc, public DDL_options { public: enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b5cc07b1411..3b56a721801 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6601,7 +6601,7 @@ static int compare_uint(const uint *s, const uint *t) enum class Compare_keys : uint32_t { - Equal, + Equal= 0, EqualButKeyPartLength, EqualButComment, NotEqual @@ -7998,6 +7998,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, List<Create_field> new_create_list; /* New key definitions are added here */ List<Key> new_key_list; + List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list); List_iterator<Alter_drop> drop_it(alter_info->drop_list); List_iterator<Create_field> def_it(alter_info->create_list); List_iterator<Alter_column> alter_it(alter_info->alter_list); @@ -8446,6 +8447,39 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, continue; } + /* If this index is to stay in the table check if it has to be renamed. */ + List_iterator<Alter_rename_key> rename_key_it(rename_key_list); + Alter_rename_key *rename_key; + + while ((rename_key= rename_key_it++)) + { + if (!my_strcasecmp(system_charset_info, key_name, rename_key->old_name.str)) + { + if (!my_strcasecmp(system_charset_info, key_name, primary_key_name)) + { + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->old_name.str); + goto err; + } + else if (!my_strcasecmp(system_charset_info, rename_key->new_name.str, + primary_key_name)) + { + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->new_name.str); + goto err; + } + + key_name= rename_key->new_name.str; + rename_key_it.remove(); + /* + If the user has explicitly renamed the key, we should no longer + treat it as generated. Otherwise this key might be automatically + dropped by mysql_prepare_create_table() and this will confuse + code in fill_alter_inplace_info(). + */ + key_info->flags&= ~HA_GENERATED_KEY; + break; + } + } + if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) { setup_keyinfo_hash(key_info); @@ -8772,6 +8806,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } + if (rename_key_list.elements) + { + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), rename_key_list.head()->old_name.str, + table->s->table_name.str); + goto err; + } + if (!create_info->comment.str) { create_info->comment.str= table->s->comment.str; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1d4a8a7e228..b032ce66cc7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7732,6 +7732,16 @@ alter_list_item: if (unlikely(Lex->add_alter_list($3, $5))) MYSQL_YYABORT; } + | RENAME key_or_index field_ident TO_SYM field_ident + { + LEX *lex=Lex; + Alter_rename_key *ak= new (thd->mem_root) + Alter_rename_key($3, $5); + if (ak == NULL) + MYSQL_YYABORT; + lex->alter_info.alter_rename_key_list.push_back(ak); + lex->alter_info.flags|= ALTER_RENAME_INDEX; + } | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate { if (!$4) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c644ce9593f..3b84a9947b2 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3330,6 +3330,14 @@ innobase_check_index_keys( } } + for (const Alter_inplace_info::Rename_key_pair& pair : + info->rename_keys) { + if (0 == strcmp(key.name.str, + pair.old_key->name.str)) { + goto name_ok; + } + } + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key.name.str); return(ER_WRONG_NAME_FOR_INDEX); |