MDEV-23387 dict_load_foreign() fails to load the table during alter

Problem:
=======
 InnoDB allows virtual index to be referenced index in foreign key
relations. While dropping the virtual column, Inplace alter does
allow the table to be closed and open it using table name to
update dict_table_t::v_cols. While loading the table, it doesn't
allow any error to be ignored. InnoDB can't find the referenced
virtual index and fails to load the table during Inplace alter.

Solution:
=========
  During inplace alter, ignore the foreign key error while loading
the table.

Reviewed-by: Marko Mäkelä
parent bba22543
......@@ -769,3 +769,24 @@ ID ParentID Value Flag
INSERT INTO parent (ID) VALUES (100);
UPDATE child SET ParentID=100 WHERE ID=123123;
DROP TABLE child, parent;
#
# MDEV-23387 dict_load_foreign() fails to load the table during alter
#
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
f3 INT AS (f1) VIRTUAL,
INDEX(f1), INDEX(f2))ENGINE=InnoDB;
ALTER TABLE t1 ADD CONSTRAINT r FOREIGN KEY(f2) REFERENCES t1(f1), LOCK=NONE;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` int(11) NOT NULL,
`f3` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL,
KEY `f1` (`f1`),
KEY `f2` (`f2`),
CONSTRAINT `r` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE t1 DROP INDEX f1;
ALTER TABLE t1 DROP f3;
DROP TABLE t1;
......@@ -637,3 +637,15 @@ UPDATE child SET ParentID=100 WHERE ID=123123;
# Cleanup
DROP TABLE child, parent;
--echo #
--echo # MDEV-23387 dict_load_foreign() fails to load the table during alter
--echo #
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
f3 INT AS (f1) VIRTUAL,
INDEX(f1), INDEX(f2))ENGINE=InnoDB;
ALTER TABLE t1 ADD CONSTRAINT r FOREIGN KEY(f2) REFERENCES t1(f1), LOCK=NONE;
SHOW CREATE TABLE t1;
ALTER TABLE t1 DROP INDEX f1;
ALTER TABLE t1 DROP f3;
DROP TABLE t1;
......@@ -8717,7 +8717,7 @@ ha_innobase::commit_inplace_alter_table(
dict_table_close(m_prebuilt->table, true, false);
dict_table_remove_from_cache(m_prebuilt->table);
m_prebuilt->table = dict_table_open_on_name(
tb_name, TRUE, TRUE, DICT_ERR_IGNORE_NONE);
tb_name, TRUE, TRUE, DICT_ERR_IGNORE_FK_NOKEY);
/* Drop outdated table stats. */
char errstr[1024];
......
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