mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 08:44:33 +01:00
MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP non-existing FOREIGN KEY
mysql_prepare_alter_table(): Alter table should check whether foreign key exists when it expected to exists and report the error in early stage dict_foreign_parse_drop_constraints(): Don't throw error if the foreign key constraints doesn't exist when if exists is given in the statement.
This commit is contained in:
parent
c432c9ef19
commit
5bb31bc882
8 changed files with 121 additions and 11 deletions
mysql-test
main
suite/innodb
sql
storage/innobase/dict
|
@ -1998,8 +1998,7 @@ ALTER TABLE ti1 DROP FOREIGN KEY fi1;
|
|||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
ALTER TABLE tm1 DROP FOREIGN KEY fm1;
|
||||
affected rows: 2
|
||||
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||
ERROR 42000: Can't DROP FOREIGN KEY `fm1`; check that it exists
|
||||
ALTER TABLE ti1 RENAME TO ti3;
|
||||
affected rows: 0
|
||||
ALTER TABLE tm1 RENAME TO tm3;
|
||||
|
|
|
@ -1700,6 +1700,7 @@ ALTER TABLE ti1 DROP PRIMARY KEY;
|
|||
ALTER TABLE tm1 DROP PRIMARY KEY;
|
||||
|
||||
ALTER TABLE ti1 DROP FOREIGN KEY fi1;
|
||||
--error ER_CANT_DROP_FIELD_OR_KEY
|
||||
ALTER TABLE tm1 DROP FOREIGN KEY fm1;
|
||||
|
||||
ALTER TABLE ti1 RENAME TO ti3;
|
||||
|
|
|
@ -144,8 +144,10 @@ alter short drop default,
|
|||
DROP INDEX utiny,
|
||||
DROP INDEX ushort,
|
||||
DROP PRIMARY KEY,
|
||||
DROP FOREIGN KEY any_name,
|
||||
DROP FOREIGN KEY IF EXISTS any_name,
|
||||
ADD INDEX (auto);
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `any_name`; check that it exists
|
||||
LOCK TABLES t1 WRITE;
|
||||
ALTER TABLE t1
|
||||
RENAME as t2,
|
||||
|
|
|
@ -76,7 +76,7 @@ alter short drop default,
|
|||
DROP INDEX utiny,
|
||||
DROP INDEX ushort,
|
||||
DROP PRIMARY KEY,
|
||||
DROP FOREIGN KEY any_name,
|
||||
DROP FOREIGN KEY IF EXISTS any_name,
|
||||
ADD INDEX (auto);
|
||||
|
||||
LOCK TABLES t1 WRITE;
|
||||
|
|
44
mysql-test/suite/innodb/r/fk_drop_alter.result
Normal file
44
mysql-test/suite/innodb/r/fk_drop_alter.result
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP
|
||||
# non-existing FOREIGN KEY
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=COPY;
|
||||
ERROR 42000: Can't DROP FOREIGN KEY `x`; check that it exists
|
||||
ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=INPLACE;
|
||||
ERROR 42000: Can't DROP FOREIGN KEY `x`; check that it exists
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (a INT, FOREIGN KEY fk_id (a) REFERENCES t1(a))ENGINE=InnoDB;
|
||||
CREATE TABLE t3 (a INT, FOREIGN KEY fk_1 (a) REFERENCES t1(a))ENGINE=InnoDB;
|
||||
ALTER TABLE t3 DROP FOREIGN KEY IF EXISTS fk_id;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `fk_id`; check that it exists
|
||||
DROP TABLE t3, t2;
|
||||
ALTER TABLE t1 MODIFY COLUMN a VARCHAR(2), DROP FOREIGN KEY IF EXISTS x;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `x`; check that it exists
|
||||
DROP TABLE t1;
|
||||
CREATE DATABASE best;
|
||||
CREATE TABLE best.t1(f1 INT, KEY(f1))ENGINE=InnoDB;
|
||||
CREATE TABLE best.t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||
CREATE TABLE t1(f1 INT, KEY(f1))ENGINE=InnoDB;
|
||||
CREATE TABLE t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY foo;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY foo;
|
||||
ERROR 42000: Can't DROP FOREIGN KEY `foo`; check that it exists
|
||||
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS foo;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `foo`; check that it exists
|
||||
SHOW CREATE TABLE best.t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`f1` int(11) DEFAULT NULL,
|
||||
KEY `foo` (`f1`),
|
||||
CONSTRAINT `foo` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
|
||||
ID FOR_NAME REF_NAME N_COLS TYPE
|
||||
best/foo best/t2 best/t1 1 0
|
||||
DROP TABLE best.t2, best.t1, t2, t1;
|
||||
DROP DATABASE best;
|
35
mysql-test/suite/innodb/t/fk_drop_alter.test
Normal file
35
mysql-test/suite/innodb/t/fk_drop_alter.test
Normal file
|
@ -0,0 +1,35 @@
|
|||
--source include/have_innodb.inc
|
||||
--echo #
|
||||
--echo # MDEV-22230 : Unexpected ER_ERROR_ON_RENAME upon DROP
|
||||
--echo # non-existing FOREIGN KEY
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
--error ER_CANT_DROP_FIELD_OR_KEY
|
||||
ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=COPY;
|
||||
--error ER_CANT_DROP_FIELD_OR_KEY
|
||||
ALTER TABLE t1 DROP FOREIGN KEY x, ALGORITHM=INPLACE;
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (a INT, FOREIGN KEY fk_id (a) REFERENCES t1(a))ENGINE=InnoDB;
|
||||
CREATE TABLE t3 (a INT, FOREIGN KEY fk_1 (a) REFERENCES t1(a))ENGINE=InnoDB;
|
||||
ALTER TABLE t3 DROP FOREIGN KEY IF EXISTS fk_id;
|
||||
DROP TABLE t3, t2;
|
||||
ALTER TABLE t1 MODIFY COLUMN a VARCHAR(2), DROP FOREIGN KEY IF EXISTS x;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE DATABASE best;
|
||||
CREATE TABLE best.t1(f1 INT, KEY(f1))ENGINE=InnoDB;
|
||||
CREATE TABLE best.t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE t1(f1 INT, KEY(f1))ENGINE=InnoDB;
|
||||
CREATE TABLE t2(f1 INT, FOREIGN KEY foo(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY foo;
|
||||
--error ER_CANT_DROP_FIELD_OR_KEY
|
||||
ALTER TABLE t2 DROP FOREIGN KEY foo;
|
||||
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS foo;
|
||||
SHOW CREATE TABLE best.t2;
|
||||
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
|
||||
DROP TABLE best.t2, best.t1, t2, t1;
|
||||
DROP DATABASE best;
|
|
@ -9056,6 +9056,30 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
goto err;
|
||||
case Alter_drop::FOREIGN_KEY:
|
||||
// Leave the DROP FOREIGN KEY names in the alter_info->drop_list.
|
||||
/* If this is DROP FOREIGN KEY without IF EXIST,
|
||||
we can now check does it exists and if not report a error. */
|
||||
if (!drop->drop_if_exists)
|
||||
{
|
||||
List <FOREIGN_KEY_INFO> fk_child_key_list;
|
||||
table->file->get_foreign_key_list(thd, &fk_child_key_list);
|
||||
if (fk_child_key_list.is_empty())
|
||||
{
|
||||
fk_not_found:
|
||||
my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop->type_name(),
|
||||
drop->name);
|
||||
goto err;
|
||||
}
|
||||
List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
|
||||
while (FOREIGN_KEY_INFO *f_key= fk_key_it++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
|
||||
drop->name) == 0)
|
||||
goto fk_found;
|
||||
}
|
||||
goto fk_not_found;
|
||||
fk_found:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4592,6 +4592,7 @@ dict_foreign_parse_drop_constraints(
|
|||
const char* ptr1;
|
||||
const char* id;
|
||||
CHARSET_INFO* cs;
|
||||
bool if_exists = false;
|
||||
|
||||
ut_a(trx->mysql_thd);
|
||||
|
||||
|
@ -4645,6 +4646,7 @@ loop:
|
|||
ptr1 = dict_accept(cs, ptr1, "EXISTS", &success);
|
||||
if (success) {
|
||||
ptr = ptr1;
|
||||
if_exists = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4655,14 +4657,14 @@ loop:
|
|||
goto syntax_error;
|
||||
}
|
||||
|
||||
ut_a(*n < 1000);
|
||||
(*constraints_to_drop)[*n] = id;
|
||||
(*n)++;
|
||||
|
||||
if (std::find_if(table->foreign_set.begin(),
|
||||
table->foreign_set.end(),
|
||||
dict_foreign_matches_id(id))
|
||||
== table->foreign_set.end()) {
|
||||
table->foreign_set.end(),
|
||||
dict_foreign_matches_id(id))
|
||||
== table->foreign_set.end()) {
|
||||
|
||||
if (if_exists) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (!srv_read_only_mode) {
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
|
@ -4684,6 +4686,9 @@ loop:
|
|||
return(DB_CANNOT_DROP_CONSTRAINT);
|
||||
}
|
||||
|
||||
ut_a(*n < 1000);
|
||||
(*constraints_to_drop)[*n] = id;
|
||||
(*n)++;
|
||||
goto loop;
|
||||
|
||||
syntax_error:
|
||||
|
|
Loading…
Add table
Reference in a new issue