Commit fd1979bc authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-18463 Don't allow multiple table CONSTRAINTs with the same name.

Add necessary checks.
parent 6aa0fa38
......@@ -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;
......@@ -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;
......@@ -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);
......
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