Commit 9319ba1e authored by marko's avatar marko

branches/zip: Disallow duplicate index name when creating an index.

This should fix Mantis Issue #461.

innodb.test, innodb.result, innodb-index.test, innodb-index.result:
Adjust the test result and mention that the introduced restriction
has been reported as MySQL Bug #51451.

innobase_check_index_keys(): Add a parameter for the InnoDB table and
check that no duplicate index name is added.  Report errors by
my_error() instead of sql_print_error().

rb://260 approved by Sunny Bains
parent 0ad5bf27
...@@ -229,9 +229,11 @@ static ...@@ -229,9 +229,11 @@ static
int int
innobase_check_index_keys( innobase_check_index_keys(
/*======================*/ /*======================*/
const KEY* key_info, /*!< in: Indexes to be created */ const KEY* key_info, /*!< in: Indexes to be
ulint num_of_keys) /*!< in: Number of indexes to created */
be created */ ulint num_of_keys, /*!< in: Number of
indexes to be created */
const dict_table_t* table) /*!< in: Existing indexes */
{ {
ulint key_num; ulint key_num;
...@@ -248,9 +250,22 @@ innobase_check_index_keys( ...@@ -248,9 +250,22 @@ innobase_check_index_keys(
const KEY& key2 = key_info[i]; const KEY& key2 = key_info[i];
if (0 == strcmp(key.name, key2.name)) { if (0 == strcmp(key.name, key2.name)) {
sql_print_error("InnoDB: key name `%s` appears" my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
" twice in CREATE INDEX\n", key.name);
key.name);
return(ER_WRONG_NAME_FOR_INDEX);
}
}
/* Check that the same index name does not already exist. */
for (const dict_index_t* index
= dict_table_get_first_index(table);
index; index = dict_table_get_next_index(index)) {
if (0 == strcmp(key.name, index->name)) {
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
key.name);
return(ER_WRONG_NAME_FOR_INDEX); return(ER_WRONG_NAME_FOR_INDEX);
} }
...@@ -258,7 +273,7 @@ innobase_check_index_keys( ...@@ -258,7 +273,7 @@ innobase_check_index_keys(
/* Check that MySQL does not try to create a column /* Check that MySQL does not try to create a column
prefix index field on an inappropriate data type and prefix index field on an inappropriate data type and
that the same colum does not appear twice in the index. */ that the same column does not appear twice in the index. */
for (ulint i = 0; i < key.key_parts; i++) { for (ulint i = 0; i < key.key_parts; i++) {
const KEY_PART_INFO& key_part1 const KEY_PART_INFO& key_part1
...@@ -289,14 +304,8 @@ innobase_check_index_keys( ...@@ -289,14 +304,8 @@ innobase_check_index_keys(
} }
} }
sql_print_error("InnoDB: MySQL is trying to" my_error(ER_WRONG_KEY_COLUMN, MYF(0),
" create a column prefix" field->field_name);
" index field on an"
" inappropriate data type."
" column `%s`,"
" index `%s`.\n",
field->field_name,
key.name);
return(ER_WRONG_KEY_COLUMN); return(ER_WRONG_KEY_COLUMN);
} }
...@@ -309,11 +318,8 @@ innobase_check_index_keys( ...@@ -309,11 +318,8 @@ innobase_check_index_keys(
continue; continue;
} }
sql_print_error("InnoDB: column `%s`" my_error(ER_WRONG_KEY_COLUMN, MYF(0),
" is not allowed to occur" key_part1.field->field_name);
" twice in index `%s`.\n",
key_part1.field->field_name,
key.name);
return(ER_WRONG_KEY_COLUMN); return(ER_WRONG_KEY_COLUMN);
} }
} }
...@@ -666,7 +672,8 @@ ha_innobase::add_index( ...@@ -666,7 +672,8 @@ ha_innobase::add_index(
error = -1; error = -1;
} else { } else {
/* Check that index keys are sensible */ /* Check that index keys are sensible */
error = innobase_check_index_keys(key_info, num_of_keys); error = innobase_check_index_keys(key_info, num_of_keys,
innodb_table);
} }
if (UNIV_UNLIKELY(error)) { if (UNIV_UNLIKELY(error)) {
...@@ -808,18 +815,6 @@ err_exit: ...@@ -808,18 +815,6 @@ err_exit:
index, num_of_idx, table); index, num_of_idx, table);
error_handling: error_handling:
#ifdef UNIV_DEBUG
/* TODO: At the moment we can't handle the following statement
in our debugging code below:
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
/* After an error, remove all those index definitions from the /* After an error, remove all those index definitions from the
dictionary which were defined. */ dictionary which were defined. */
...@@ -831,6 +826,8 @@ error_handling: ...@@ -831,6 +826,8 @@ error_handling:
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE; dict_locked = TRUE;
ut_d(dict_table_check_for_dup_indexes(prebuilt->table));
if (!new_primary) { if (!new_primary) {
error = row_merge_rename_indexes(trx, indexed_table); error = row_merge_rename_indexes(trx, indexed_table);
...@@ -1211,9 +1208,7 @@ ha_innobase::final_drop_index( ...@@ -1211,9 +1208,7 @@ ha_innobase::final_drop_index(
valid index entry count in the translation table to zero */ valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0; share->idx_trans_tbl.index_count = 0;
#ifdef UNIV_DEBUG ut_d(dict_table_check_for_dup_indexes(prebuilt->table));
dict_table_check_for_dup_indexes(prebuilt->table);
#endif
func_exit: func_exit:
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
......
...@@ -441,6 +441,7 @@ t3 CREATE TABLE `t3` ( ...@@ -441,6 +441,7 @@ t3 CREATE TABLE `t3` (
KEY `c` (`c`) KEY `c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
alter table t2 drop index b, add index (b); alter table t2 drop index b, add index (b);
ERROR 42000: Incorrect index name 'b'
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
...@@ -451,8 +452,8 @@ t2 CREATE TABLE `t2` ( ...@@ -451,8 +452,8 @@ t2 CREATE TABLE `t2` (
`e` int(11) DEFAULT NULL, `e` int(11) DEFAULT NULL,
PRIMARY KEY (`a`), PRIMARY KEY (`a`),
UNIQUE KEY `dc` (`d`,`c`), UNIQUE KEY `dc` (`d`,`c`),
KEY `c` (`c`),
KEY `b` (`b`), KEY `b` (`b`),
KEY `c` (`c`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`b`) ON DELETE CASCADE, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`b`) ON DELETE CASCADE,
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t3` (`c`), CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t3` (`c`),
CONSTRAINT `t2_ibfk_3` FOREIGN KEY (`d`) REFERENCES `t4` (`d`) CONSTRAINT `t2_ibfk_3` FOREIGN KEY (`d`) REFERENCES `t4` (`d`)
......
...@@ -141,6 +141,8 @@ show create table t4; ...@@ -141,6 +141,8 @@ show create table t4;
--error ER_CANT_CREATE_TABLE --error ER_CANT_CREATE_TABLE
alter table t3 add constraint dc foreign key (a) references t1(a); alter table t3 add constraint dc foreign key (a) references t1(a);
show create table t3; show create table t3;
# this should be fixed by MySQL (see Bug #51451)
--error ER_WRONG_NAME_FOR_INDEX
alter table t2 drop index b, add index (b); alter table t2 drop index b, add index (b);
show create table t2; show create table t2;
--error ER_ROW_IS_REFERENCED_2 --error ER_ROW_IS_REFERENCED_2
......
...@@ -692,6 +692,9 @@ select count(*) from t1 where sca_pic is null; ...@@ -692,6 +692,9 @@ select count(*) from t1 where sca_pic is null;
count(*) count(*)
2 2
alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic); alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
ERROR 42000: Incorrect index name 'sca_pic'
alter table t1 drop index sca_pic;
alter table t1 add index sca_pic (cat_code, sca_pic);
select count(*) from t1 where sca_code='PD' and sca_pic is null; select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*) count(*)
1 1
...@@ -699,6 +702,9 @@ select count(*) from t1 where cat_code='E'; ...@@ -699,6 +702,9 @@ select count(*) from t1 where cat_code='E';
count(*) count(*)
0 0
alter table t1 drop index sca_pic, add index (sca_pic, cat_code); alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
ERROR 42000: Incorrect index name 'sca_pic'
alter table t1 drop index sca_pic;
alter table t1 add index (sca_pic, cat_code);
select count(*) from t1 where sca_code='PD' and sca_pic is null; select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*) count(*)
1 1
...@@ -1833,6 +1839,7 @@ show variables like "innodb_thread_sleep_delay"; ...@@ -1833,6 +1839,7 @@ show variables like "innodb_thread_sleep_delay";
Variable_name Value Variable_name Value
innodb_thread_sleep_delay 10000 innodb_thread_sleep_delay 10000
set storage_engine=INNODB; set storage_engine=INNODB;
set session old_alter_table=1;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
--- Testing varchar --- --- Testing varchar ---
--- Testing varchar --- --- Testing varchar ---
...@@ -1970,7 +1977,7 @@ explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' ...@@ -1970,7 +1977,7 @@ explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a '
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 13 const # Using where; Using index 1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v); alter table t1 add unique(v);
ERROR 23000: Duplicate entry 'v' for key 'v_2' ERROR 23000: Duplicate entry '{ ' for key 'v_2'
alter table t1 add key(v); alter table t1 add key(v);
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a'; select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
qq qq
...@@ -2406,6 +2413,7 @@ select * from t1 where a=20 and b is null; ...@@ -2406,6 +2413,7 @@ select * from t1 where a=20 and b is null;
a b a b
20 NULL 20 NULL
drop table t1; drop table t1;
set session old_alter_table=0;
create table t1 (v varchar(65530), key(v)); create table t1 (v varchar(65530), key(v));
Warnings: Warnings:
Warning 1071 Specified key was too long; max key length is 767 bytes Warning 1071 Specified key was too long; max key length is 767 bytes
......
...@@ -427,11 +427,19 @@ INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca ...@@ -427,11 +427,19 @@ INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca
select count(*) from t1 where sca_code = 'PD'; select count(*) from t1 where sca_code = 'PD';
select count(*) from t1 where sca_code <= 'PD'; select count(*) from t1 where sca_code <= 'PD';
select count(*) from t1 where sca_pic is null; select count(*) from t1 where sca_pic is null;
# this should be fixed by MySQL (see Bug #51451)
--error ER_WRONG_NAME_FOR_INDEX
alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic); alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
alter table t1 drop index sca_pic;
alter table t1 add index sca_pic (cat_code, sca_pic);
select count(*) from t1 where sca_code='PD' and sca_pic is null; select count(*) from t1 where sca_code='PD' and sca_pic is null;
select count(*) from t1 where cat_code='E'; select count(*) from t1 where cat_code='E';
# this should be fixed by MySQL (see Bug #51451)
--error ER_WRONG_NAME_FOR_INDEX
alter table t1 drop index sca_pic, add index (sca_pic, cat_code); alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
alter table t1 drop index sca_pic;
alter table t1 add index (sca_pic, cat_code);
select count(*) from t1 where sca_code='PD' and sca_pic is null; select count(*) from t1 where sca_code='PD' and sca_pic is null;
select count(*) from t1 where sca_pic >= 'n'; select count(*) from t1 where sca_pic >= 'n';
select sca_pic from t1 where sca_pic is null; select sca_pic from t1 where sca_pic is null;
...@@ -1377,7 +1385,10 @@ show variables like "innodb_thread_sleep_delay"; ...@@ -1377,7 +1385,10 @@ show variables like "innodb_thread_sleep_delay";
let $default=`select @@storage_engine`; let $default=`select @@storage_engine`;
set storage_engine=INNODB; set storage_engine=INNODB;
# this should be fixed by MySQL (see Bug #51451)
set session old_alter_table=1;
source include/varchar.inc; source include/varchar.inc;
set session old_alter_table=0;
# #
# Some errors/warnings on create # Some errors/warnings on create
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment