Loading include/my_base.h +7 −1 Original line number Diff line number Diff line Loading @@ -206,6 +206,11 @@ enum ha_base_keytype { #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ #define HA_GENERATED_KEY 8192 /* Automaticly generated key */ /* The combination of the above can be used for key type comparison. */ #define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \ HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) /* Automatic bits in key-flag */ #define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */ Loading Loading @@ -349,8 +354,9 @@ enum ha_base_keytype { #define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for given value */ #define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */ #define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr. */ #define HA_ERR_LAST 161 /* Copy last error no */ #define HA_ERR_LAST 162 /* Copy last error no */ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) Loading mysql-test/r/key.result +68 −0 Original line number Diff line number Diff line Loading @@ -396,3 +396,71 @@ a int(11) NO PRI b varchar(20) NO MUL c varchar(20) NO drop table t1; create table t1 ( c1 int, c2 char(12), c3 varchar(123), c4 timestamp, index (c1), index i1 (c1), index i2 (c2), index i3 (c3), unique i4 (c4), index i5 (c1, c2, c3, c4), primary key (c2, c3), index (c2, c4)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) default NULL, `c2` char(12) NOT NULL default '', `c3` varchar(123) NOT NULL default '', `c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (`c2`,`c3`), UNIQUE KEY `i4` (`c4`), KEY `c1` (`c1`), KEY `i1` (`c1`), KEY `i2` (`c2`), KEY `i3` (`c3`), KEY `i5` (`c1`,`c2`,`c3`,`c4`), KEY `c2` (`c2`,`c4`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t1 drop index c1; alter table t1 add index (c1); alter table t1 add index (c1); alter table t1 drop index i3; alter table t1 add index i3 (c3); alter table t1 drop index i2, drop index i4; alter table t1 add index i2 (c2), add index i4 (c4); alter table t1 drop index i2, drop index i4, add index i6 (c2, c4); alter table t1 add index i2 (c2), add index i4 (c4), drop index i6; alter table t1 drop index i2, drop index i4, add unique i4 (c4); alter table t1 add index i2 (c2), drop index i4, add index i4 (c4); alter table t1 drop index c2, add index (c2(4),c3(7)); alter table t1 drop index c2, add index (c2(4),c3(7)); alter table t1 add primary key (c1, c2), drop primary key; alter table t1 drop primary key; alter table t1 add primary key (c1, c2), drop primary key; ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL default '0', `c2` char(12) NOT NULL default '', `c3` varchar(123) NOT NULL default '', `c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, KEY `i1` (`c1`), KEY `i5` (`c1`,`c2`,`c3`,`c4`), KEY `c1` (`c1`), KEY `c1_2` (`c1`), KEY `i3` (`c3`), KEY `i2` (`c2`), KEY `i4` (`c4`), KEY `c2` (`c2`(4),`c3`(7)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 insert into t1 values(1, 'a', 'a', NULL); insert into t1 values(1, 'b', 'b', NULL); alter table t1 drop index i3, drop index i2, drop index i1; alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1); ERROR 23000: Duplicate entry '1' for key 1 drop table t1; mysql-test/t/key.test +58 −0 Original line number Diff line number Diff line Loading @@ -372,3 +372,61 @@ desc t1; drop table t1; # End of 4.1 tests # # WL#1563 - Modify MySQL to support on-line CREATE/DROP INDEX # To test if this really works, you need to run with --debug # and check the trace file. # # Create a table with named and unnamed indexes. create table t1 ( c1 int, c2 char(12), c3 varchar(123), c4 timestamp, index (c1), index i1 (c1), index i2 (c2), index i3 (c3), unique i4 (c4), index i5 (c1, c2, c3, c4), primary key (c2, c3), index (c2, c4)); show create table t1; # Some simple tests. alter table t1 drop index c1; alter table t1 add index (c1); # This creates index 'c1_2'. alter table t1 add index (c1); alter table t1 drop index i3; alter table t1 add index i3 (c3); # Two indexes at the same time. alter table t1 drop index i2, drop index i4; alter table t1 add index i2 (c2), add index i4 (c4); # Three indexes, one of them reversely. alter table t1 drop index i2, drop index i4, add index i6 (c2, c4); alter table t1 add index i2 (c2), add index i4 (c4), drop index i6; # include an unique index. alter table t1 drop index i2, drop index i4, add unique i4 (c4); alter table t1 add index i2 (c2), drop index i4, add index i4 (c4); # Modify an index by changing its definition. alter table t1 drop index c2, add index (c2(4),c3(7)); # Change nothing. The new key definition is the same as the old one. alter table t1 drop index c2, add index (c2(4),c3(7)); # Test primary key handling. alter table t1 add primary key (c1, c2), drop primary key; alter table t1 drop primary key; # Drop is checked first. Primary key must exist. --error 1091 alter table t1 add primary key (c1, c2), drop primary key; show create table t1; # Insert non-unique values. insert into t1 values(1, 'a', 'a', NULL); insert into t1 values(1, 'b', 'b', NULL); # Drop some indexes for new adds. alter table t1 drop index i3, drop index i2, drop index i1; # Add indexes, one is unique on non-unique values. --error 1062 alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1); drop table t1; sql/handler.cc +15 −1 Original line number Diff line number Diff line Loading @@ -1851,7 +1851,12 @@ void handler::print_error(int error, myf errflag) str.length(max_length-4); str.append(STRING_WITH_LEN("...")); } #ifdef XXX_TO_BE_DONE_BY_A_FOLLOWUP_OF_WL1563 my_printf_error(ER_DUP_ENTRY, "Duplicate entry '%s' for key '%s'", MYF(0), str.c_ptr(), table->key_info[key_nr].name); #else my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1); #endif DBUG_VOID_RETURN; } textno=ER_DUP_KEY; Loading Loading @@ -1936,6 +1941,15 @@ void handler::print_error(int error, myf errflag) case HA_ERR_RBR_LOGGING_FAILED: textno= ER_BINLOG_ROW_LOGGING_FAILED; break; case HA_ERR_DROP_INDEX_FK: { const char *ptr= "???"; uint key_nr= get_dup_key(error); if ((int) key_nr >= 0) ptr= table->key_info[key_nr].name; my_error(ER_DROP_INDEX_FK, MYF(0), ptr); DBUG_VOID_RETURN; } default: { /* The error was "unknown" to this function. Loading Loading @@ -1984,7 +1998,7 @@ uint handler::get_dup_key(int error) DBUG_ENTER("handler::get_dup_key"); table->file->errkey = (uint) -1; if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL) error == HA_ERR_NULL_IN_SPATIAL || error == HA_ERR_DROP_INDEX_FK) info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK); DBUG_RETURN(table->file->errkey); } Loading sql/handler.h +28 −15 Original line number Diff line number Diff line Loading @@ -110,8 +110,29 @@ #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */ /* bits in alter_table_flags */ #define HA_ONLINE_ADD_EMPTY_PARTITION 1 #define HA_ONLINE_DROP_PARTITION 2 #define HA_ONLINE_ADD_EMPTY_PARTITION 0x00000001 #define HA_ONLINE_DROP_PARTITION 0x00000002 /* These bits are set if different kinds of indexes can be created off-line without re-create of the table (but with a table lock). */ #define HA_ONLINE_ADD_INDEX_NO_WRITES 0x00000004 /*add index w/lock*/ #define HA_ONLINE_DROP_INDEX_NO_WRITES 0x00000008 /*drop index w/lock*/ #define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES 0x00000010 /*add unique w/lock*/ #define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES 0x00000020 /*drop uniq. w/lock*/ #define HA_ONLINE_ADD_PK_INDEX_NO_WRITES 0x00000040 /*add prim. w/lock*/ #define HA_ONLINE_DROP_PK_INDEX_NO_WRITES 0x00000080 /*drop prim. w/lock*/ /* These are set if different kinds of indexes can be created on-line (without a table lock). If a handler is capable of one or more of these, it should also set the corresponding *_NO_WRITES bit(s). */ #define HA_ONLINE_ADD_INDEX 0x00000100 /*add index online*/ #define HA_ONLINE_DROP_INDEX 0x00000200 /*drop index online*/ #define HA_ONLINE_ADD_UNIQUE_INDEX 0x00000400 /*add unique online*/ #define HA_ONLINE_DROP_UNIQUE_INDEX 0x00000800 /*drop uniq. online*/ #define HA_ONLINE_ADD_PK_INDEX 0x00001000 /*add prim. online*/ #define HA_ONLINE_DROP_PK_INDEX 0x00002000 /*drop prim. online*/ /* Index scan will not return records in rowid order. Not guaranteed to be Loading @@ -134,16 +155,6 @@ */ #define MAX_HA 15 /* Bits in index_ddl_flags(KEY *wanted_index) for what ddl you can do with index If none is set, the wanted type of index is not supported by the handler at all. See WorkLog 1563. */ #define HA_DDL_SUPPORT 1 /* Supported by handler */ #define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */ #define HA_DDL_ONLINE 4 /* Can create/drop without lock */ /* Parameters for open() (in register form->filestat) HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED Loading Loading @@ -1442,11 +1453,13 @@ class handler :public Sql_alloc virtual void set_part_info(partition_info *part_info) { return; } #endif virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; virtual ulong index_ddl_flags(KEY *wanted_index) const { return (HA_DDL_SUPPORT); } virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } virtual int drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } virtual int final_drop_index(TABLE *table_arg) { return (HA_ERR_WRONG_COMMAND); } uint max_record_length() const Loading Loading
include/my_base.h +7 −1 Original line number Diff line number Diff line Loading @@ -206,6 +206,11 @@ enum ha_base_keytype { #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ #define HA_GENERATED_KEY 8192 /* Automaticly generated key */ /* The combination of the above can be used for key type comparison. */ #define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \ HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) /* Automatic bits in key-flag */ #define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */ Loading Loading @@ -349,8 +354,9 @@ enum ha_base_keytype { #define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for given value */ #define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */ #define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr. */ #define HA_ERR_LAST 161 /* Copy last error no */ #define HA_ERR_LAST 162 /* Copy last error no */ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) Loading
mysql-test/r/key.result +68 −0 Original line number Diff line number Diff line Loading @@ -396,3 +396,71 @@ a int(11) NO PRI b varchar(20) NO MUL c varchar(20) NO drop table t1; create table t1 ( c1 int, c2 char(12), c3 varchar(123), c4 timestamp, index (c1), index i1 (c1), index i2 (c2), index i3 (c3), unique i4 (c4), index i5 (c1, c2, c3, c4), primary key (c2, c3), index (c2, c4)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) default NULL, `c2` char(12) NOT NULL default '', `c3` varchar(123) NOT NULL default '', `c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (`c2`,`c3`), UNIQUE KEY `i4` (`c4`), KEY `c1` (`c1`), KEY `i1` (`c1`), KEY `i2` (`c2`), KEY `i3` (`c3`), KEY `i5` (`c1`,`c2`,`c3`,`c4`), KEY `c2` (`c2`,`c4`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t1 drop index c1; alter table t1 add index (c1); alter table t1 add index (c1); alter table t1 drop index i3; alter table t1 add index i3 (c3); alter table t1 drop index i2, drop index i4; alter table t1 add index i2 (c2), add index i4 (c4); alter table t1 drop index i2, drop index i4, add index i6 (c2, c4); alter table t1 add index i2 (c2), add index i4 (c4), drop index i6; alter table t1 drop index i2, drop index i4, add unique i4 (c4); alter table t1 add index i2 (c2), drop index i4, add index i4 (c4); alter table t1 drop index c2, add index (c2(4),c3(7)); alter table t1 drop index c2, add index (c2(4),c3(7)); alter table t1 add primary key (c1, c2), drop primary key; alter table t1 drop primary key; alter table t1 add primary key (c1, c2), drop primary key; ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL default '0', `c2` char(12) NOT NULL default '', `c3` varchar(123) NOT NULL default '', `c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, KEY `i1` (`c1`), KEY `i5` (`c1`,`c2`,`c3`,`c4`), KEY `c1` (`c1`), KEY `c1_2` (`c1`), KEY `i3` (`c3`), KEY `i2` (`c2`), KEY `i4` (`c4`), KEY `c2` (`c2`(4),`c3`(7)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 insert into t1 values(1, 'a', 'a', NULL); insert into t1 values(1, 'b', 'b', NULL); alter table t1 drop index i3, drop index i2, drop index i1; alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1); ERROR 23000: Duplicate entry '1' for key 1 drop table t1;
mysql-test/t/key.test +58 −0 Original line number Diff line number Diff line Loading @@ -372,3 +372,61 @@ desc t1; drop table t1; # End of 4.1 tests # # WL#1563 - Modify MySQL to support on-line CREATE/DROP INDEX # To test if this really works, you need to run with --debug # and check the trace file. # # Create a table with named and unnamed indexes. create table t1 ( c1 int, c2 char(12), c3 varchar(123), c4 timestamp, index (c1), index i1 (c1), index i2 (c2), index i3 (c3), unique i4 (c4), index i5 (c1, c2, c3, c4), primary key (c2, c3), index (c2, c4)); show create table t1; # Some simple tests. alter table t1 drop index c1; alter table t1 add index (c1); # This creates index 'c1_2'. alter table t1 add index (c1); alter table t1 drop index i3; alter table t1 add index i3 (c3); # Two indexes at the same time. alter table t1 drop index i2, drop index i4; alter table t1 add index i2 (c2), add index i4 (c4); # Three indexes, one of them reversely. alter table t1 drop index i2, drop index i4, add index i6 (c2, c4); alter table t1 add index i2 (c2), add index i4 (c4), drop index i6; # include an unique index. alter table t1 drop index i2, drop index i4, add unique i4 (c4); alter table t1 add index i2 (c2), drop index i4, add index i4 (c4); # Modify an index by changing its definition. alter table t1 drop index c2, add index (c2(4),c3(7)); # Change nothing. The new key definition is the same as the old one. alter table t1 drop index c2, add index (c2(4),c3(7)); # Test primary key handling. alter table t1 add primary key (c1, c2), drop primary key; alter table t1 drop primary key; # Drop is checked first. Primary key must exist. --error 1091 alter table t1 add primary key (c1, c2), drop primary key; show create table t1; # Insert non-unique values. insert into t1 values(1, 'a', 'a', NULL); insert into t1 values(1, 'b', 'b', NULL); # Drop some indexes for new adds. alter table t1 drop index i3, drop index i2, drop index i1; # Add indexes, one is unique on non-unique values. --error 1062 alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1); drop table t1;
sql/handler.cc +15 −1 Original line number Diff line number Diff line Loading @@ -1851,7 +1851,12 @@ void handler::print_error(int error, myf errflag) str.length(max_length-4); str.append(STRING_WITH_LEN("...")); } #ifdef XXX_TO_BE_DONE_BY_A_FOLLOWUP_OF_WL1563 my_printf_error(ER_DUP_ENTRY, "Duplicate entry '%s' for key '%s'", MYF(0), str.c_ptr(), table->key_info[key_nr].name); #else my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1); #endif DBUG_VOID_RETURN; } textno=ER_DUP_KEY; Loading Loading @@ -1936,6 +1941,15 @@ void handler::print_error(int error, myf errflag) case HA_ERR_RBR_LOGGING_FAILED: textno= ER_BINLOG_ROW_LOGGING_FAILED; break; case HA_ERR_DROP_INDEX_FK: { const char *ptr= "???"; uint key_nr= get_dup_key(error); if ((int) key_nr >= 0) ptr= table->key_info[key_nr].name; my_error(ER_DROP_INDEX_FK, MYF(0), ptr); DBUG_VOID_RETURN; } default: { /* The error was "unknown" to this function. Loading Loading @@ -1984,7 +1998,7 @@ uint handler::get_dup_key(int error) DBUG_ENTER("handler::get_dup_key"); table->file->errkey = (uint) -1; if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL) error == HA_ERR_NULL_IN_SPATIAL || error == HA_ERR_DROP_INDEX_FK) info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK); DBUG_RETURN(table->file->errkey); } Loading
sql/handler.h +28 −15 Original line number Diff line number Diff line Loading @@ -110,8 +110,29 @@ #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */ /* bits in alter_table_flags */ #define HA_ONLINE_ADD_EMPTY_PARTITION 1 #define HA_ONLINE_DROP_PARTITION 2 #define HA_ONLINE_ADD_EMPTY_PARTITION 0x00000001 #define HA_ONLINE_DROP_PARTITION 0x00000002 /* These bits are set if different kinds of indexes can be created off-line without re-create of the table (but with a table lock). */ #define HA_ONLINE_ADD_INDEX_NO_WRITES 0x00000004 /*add index w/lock*/ #define HA_ONLINE_DROP_INDEX_NO_WRITES 0x00000008 /*drop index w/lock*/ #define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES 0x00000010 /*add unique w/lock*/ #define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES 0x00000020 /*drop uniq. w/lock*/ #define HA_ONLINE_ADD_PK_INDEX_NO_WRITES 0x00000040 /*add prim. w/lock*/ #define HA_ONLINE_DROP_PK_INDEX_NO_WRITES 0x00000080 /*drop prim. w/lock*/ /* These are set if different kinds of indexes can be created on-line (without a table lock). If a handler is capable of one or more of these, it should also set the corresponding *_NO_WRITES bit(s). */ #define HA_ONLINE_ADD_INDEX 0x00000100 /*add index online*/ #define HA_ONLINE_DROP_INDEX 0x00000200 /*drop index online*/ #define HA_ONLINE_ADD_UNIQUE_INDEX 0x00000400 /*add unique online*/ #define HA_ONLINE_DROP_UNIQUE_INDEX 0x00000800 /*drop uniq. online*/ #define HA_ONLINE_ADD_PK_INDEX 0x00001000 /*add prim. online*/ #define HA_ONLINE_DROP_PK_INDEX 0x00002000 /*drop prim. online*/ /* Index scan will not return records in rowid order. Not guaranteed to be Loading @@ -134,16 +155,6 @@ */ #define MAX_HA 15 /* Bits in index_ddl_flags(KEY *wanted_index) for what ddl you can do with index If none is set, the wanted type of index is not supported by the handler at all. See WorkLog 1563. */ #define HA_DDL_SUPPORT 1 /* Supported by handler */ #define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */ #define HA_DDL_ONLINE 4 /* Can create/drop without lock */ /* Parameters for open() (in register form->filestat) HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED Loading Loading @@ -1442,11 +1453,13 @@ class handler :public Sql_alloc virtual void set_part_info(partition_info *part_info) { return; } #endif virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; virtual ulong index_ddl_flags(KEY *wanted_index) const { return (HA_DDL_SUPPORT); } virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } virtual int drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys) { return (HA_ERR_WRONG_COMMAND); } virtual int final_drop_index(TABLE *table_arg) { return (HA_ERR_WRONG_COMMAND); } uint max_record_length() const Loading