Commit e5aa8ea5 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent 38b6dc5a
#
# 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;
--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;
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -3787,6 +3788,9 @@ dict_create_foreign_constraints_low( ...@@ -3787,6 +3788,9 @@ dict_create_foreign_constraints_low(
} }
goto loop; goto loop;
} else {
strncpy(create_name, name, sizeof create_name);
create_name[(sizeof create_name) - 1] = '\0';
} }
if (table == NULL) { if (table == NULL) {
...@@ -3811,11 +3815,20 @@ dict_create_foreign_constraints_low( ...@@ -3811,11 +3815,20 @@ dict_create_foreign_constraints_low(
goto loop; goto loop;
} }
ptr = dict_accept(cs, ptr, "TABLE", &success); orig = ptr;
for (;;) {
if (!success) { ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
goto loop; 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 */ /* We are doing an ALTER TABLE: scan the table name we are altering */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -3921,6 +3922,9 @@ dict_create_foreign_constraints_low( ...@@ -3921,6 +3922,9 @@ dict_create_foreign_constraints_low(
} }
goto loop; goto loop;
} else {
strncpy(create_name, name, sizeof create_name);
create_name[(sizeof create_name) - 1] = '\0';
} }
if (table == NULL) { if (table == NULL) {
...@@ -3945,11 +3949,20 @@ dict_create_foreign_constraints_low( ...@@ -3945,11 +3949,20 @@ dict_create_foreign_constraints_low(
goto loop; goto loop;
} }
ptr = dict_accept(cs, ptr, "TABLE", &success); orig = ptr;
for (;;) {
if (!success) { ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
goto loop; 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 */ /* We are doing an ALTER TABLE: scan the table name we are altering */
......
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