diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2019-12-09 01:17:16 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2019-12-09 01:17:16 +0400 |
commit | fd1979bc9a535735ed3f3a7dbb67d09568dd8417 (patch) | |
tree | 167287472141d8404b279e8a3a6152d19ab7b9c4 | |
parent | 6aa0fa3897bc9ce415efef0c0c039503881321ad (diff) | |
download | mariadb-git-fd1979bc9a535735ed3f3a7dbb67d09568dd8417.tar.gz |
MDEV-18463 Don't allow multiple table CONSTRAINTs with the same name.
Add necessary checks.
-rw-r--r-- | mysql-test/r/foreign_key.result | 26 | ||||
-rw-r--r-- | mysql-test/t/foreign_key.test | 24 | ||||
-rw-r--r-- | sql/sql_table.cc | 54 |
3 files changed, 102 insertions, 2 deletions
diff --git a/mysql-test/r/foreign_key.result b/mysql-test/r/foreign_key.result index a82151ddec0..c412be6bbdb 100644 --- a/mysql-test/r/foreign_key.result +++ b/mysql-test/r/foreign_key.result @@ -82,3 +82,29 @@ add foreign key (a) references t3 (a) on update set default on update set default); 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 'update set default)' at line 3 drop table t_34455; +# +# MDEV-18460 Don't allow multiple table CONSTRAINTs with the same name. +# +CREATE TABLE tpk (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL) ENGINE=Innodb; +CREATE TABLE tfk (c1 INT, c2 INT, CONSTRAINT sid UNIQUE (c1), CONSTRAINT sid CHECK (c2>15)); +ERROR HY000: Duplicate CHECK constraint name 'sid' +CREATE TABLE tfk (c1 INT, c2 INT, CONSTRAINT sid UNIQUE (c1)); +ALTER TABLE tfk ADD CONSTRAINT sid CHECK (c2>15); +ERROR HY000: Duplicate CHECK constraint name 'sid' +DROP TABLE tfk; +CREATE TABLE tfk (c1 INT, c2 INT, +CONSTRAINT sid FOREIGN KEY (c1) REFERENCES tpk (id)) ENGINE=Innodb; +show create table tfk; +Table Create Table +tfk CREATE TABLE `tfk` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + KEY `sid` (`c1`), + CONSTRAINT `sid` FOREIGN KEY (`c1`) REFERENCES `tpk` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE tfk ADD CONSTRAINT sid CHECK (c2>15); +ERROR HY000: Duplicate CHECK constraint name 'sid' +ALTER TABLE tfk ADD CONSTRAINT sid UNIQUE(c2); +ERROR 42000: Duplicate key name 'sid' +DROP TABLE tfk; +DROP TABLE tpk; diff --git a/mysql-test/t/foreign_key.test b/mysql-test/t/foreign_key.test index 17c93332cb3..3a09a544532 100644 --- a/mysql-test/t/foreign_key.test +++ b/mysql-test/t/foreign_key.test @@ -117,4 +117,28 @@ alter table t_34455 drop table t_34455; +--echo # +--echo # MDEV-18460 Don't allow multiple table CONSTRAINTs with the same name. +--echo # + +CREATE TABLE tpk (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL) ENGINE=Innodb; +--error ER_DUP_CONSTRAINT_NAME +CREATE TABLE tfk (c1 INT, c2 INT, CONSTRAINT sid UNIQUE (c1), CONSTRAINT sid CHECK (c2>15)); + +CREATE TABLE tfk (c1 INT, c2 INT, CONSTRAINT sid UNIQUE (c1)); +--error ER_DUP_CONSTRAINT_NAME +ALTER TABLE tfk ADD CONSTRAINT sid CHECK (c2>15); +DROP TABLE tfk; + +CREATE TABLE tfk (c1 INT, c2 INT, + CONSTRAINT sid FOREIGN KEY (c1) REFERENCES tpk (id)) ENGINE=Innodb; +show create table tfk; +--error ER_DUP_CONSTRAINT_NAME +ALTER TABLE tfk ADD CONSTRAINT sid CHECK (c2>15); +--error ER_DUP_KEYNAME +ALTER TABLE tfk ADD CONSTRAINT sid UNIQUE(c2); +DROP TABLE tfk; + +DROP TABLE tpk; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4ad68d9d03b..878c09286b5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4196,10 +4196,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, continue; { - /* Check that there's no repeating constraint names. */ + /* Check that there's no repeating table CHECK constraint names. */ List_iterator_fast<Virtual_column_info> dup_it(alter_info->check_constraint_list); - Virtual_column_info *dup_check; + const Virtual_column_info *dup_check; while ((dup_check= dup_it++) && dup_check != check) { if (check->name.length == dup_check->name.length && @@ -4212,6 +4212,27 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } + /* Check that there's no repeating key constraint names. */ + List_iterator_fast<Key> key_it(alter_info->key_list); + while (const Key *key= key_it++) + { + /* + Not all keys considered to be the CONSTRAINT + Noly Primary Key UNIQUE and Foreign keys. + */ + if (key->type != Key::PRIMARY && key->type != Key::UNIQUE && + key->type != Key::FOREIGN_KEY) + continue; + + if (check->name.length == key->name.length && + my_strcasecmp(system_charset_info, + check->name.str, key->name.str) == 0) + { + my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); + DBUG_RETURN(TRUE); + } + } + if (check_string_char_length(&check->name, 0, NAME_CHAR_LEN, system_charset_info, 1)) { @@ -8176,6 +8197,35 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } } + + if (!alter_info->check_constraint_list.is_empty()) + { + /* Check the table FOREIGN KEYs for name duplications. */ + List <FOREIGN_KEY_INFO> fk_child_key_list; + FOREIGN_KEY_INFO *f_key; + table->file->get_foreign_key_list(thd, &fk_child_key_list); + List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list); + while ((f_key= fk_key_it++)) + { + List_iterator_fast<Virtual_column_info> + c_it(alter_info->check_constraint_list); + Virtual_column_info *check; + while ((check= c_it++)) + { + if (!check->name.length || check->automatic_name) + continue; + + if (check->name.length == f_key->foreign_id->length && + my_strcasecmp(system_charset_info, f_key->foreign_id->str, + check->name.str) == 0) + { + my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); + goto err; + } + } + } + } + /* Add new constraints */ new_constraint_list.append(&alter_info->check_constraint_list); |