[Commits] e5aa8ea5255: MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error
revision-id: e5aa8ea52552759453fdd86eeab0007df1781b62 (mariadb-5.5.63-19-ge5aa8ea5255) parent(s): 38b6dc5a3d11d9917c02ad10293807b5a0a4f5a0 author: Marko Mäkelä committer: Marko Mäkelä timestamp: 2019-04-23 17:56:43 +0300 message: MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error dict_create_foreign_constraints_low(): Tolerate the keywords IGNORE and ONLINE between the keywords ALTER and TABLE. We should really remove the hacky FOREIGN KEY constraint parser from InnoDB. --- mysql-test/suite/innodb/r/foreign_key.result | 20 ++++++++++++++++++++ mysql-test/suite/innodb/t/foreign_key.test | 22 ++++++++++++++++++++++ storage/innobase/dict/dict0dict.c | 23 ++++++++++++++++++----- storage/xtradb/dict/dict0dict.c | 23 ++++++++++++++++++----- 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result new file mode 100644 index 00000000000..39f99513ee0 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -0,0 +1,20 @@ +# +# MDEV-18630 Conditional jump or move depends on uninitialised value +# in ib_push_warning / dict_create_foreign_constraints_low +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); +ERROR HY000: Can't create table 'test.#sql-temporary' (errno: 150) +SHOW WARNINGS; +Level Code Message +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'. +Error 1005 Can't create table 'test.#sql-temporary' (errno: 150) +DROP TABLE t1; +# +# MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error +# +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f); +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1); +DROP TABLE t1, t2; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test new file mode 100644 index 00000000000..281193d60ec --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-18630 Conditional jump or move depends on uninitialised value +--echo # in ib_push_warning / dict_create_foreign_constraints_low +--echo # +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +--replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ +--error ER_CANT_CREATE_TABLE +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); +--replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ +SHOW WARNINGS; +DROP TABLE t1; + +--echo # +--echo # MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error +--echo # +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f); +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1); +DROP TABLE t1, t2; diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 588c2968b6a..fcb9a48e4c0 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -3787,6 +3788,9 @@ dict_create_foreign_constraints_low( } goto loop; + } else { + strncpy(create_name, name, sizeof create_name); + create_name[(sizeof create_name) - 1] = '\0'; } if (table == NULL) { @@ -3811,11 +3815,20 @@ dict_create_foreign_constraints_low( goto loop; } - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + orig = ptr; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */ diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index 5da4509599e..12d3a600e54 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -3921,6 +3922,9 @@ dict_create_foreign_constraints_low( } goto loop; + } else { + strncpy(create_name, name, sizeof create_name); + create_name[(sizeof create_name) - 1] = '\0'; } if (table == NULL) { @@ -3945,11 +3949,20 @@ dict_create_foreign_constraints_low( goto loop; } - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + orig = ptr; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */
participants (1)
-
sujatha