diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result index 17ea0341049..1584c433009 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -590,3 +590,101 @@ SELECT * FROM t2; fld1 fld2 1 1 DROP TABLE t2, t1; +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, +KEY (f1, f2), FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +EXPLAIN SELECT f1, f2 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL f1 9 NULL 1 Using index +SELECT f1, f2 FROM t2; +f1 f2 +1 1 +INSERT INTO t2(f1) VALUES(2); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)) +DROP TABLE t2, t1; +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, +KEY (f1, f2), FOREIGN KEY(f1) REFERENCES t1(f1) +ON UPDATE CASCADE)ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +EXPLAIN SELECT f1, f2 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL f1 9 NULL 1 Using index +SELECT f1, f2 FROM t2; +f1 f2 +1 1 +UPDATE t1 SET f1 = 2 WHERE f1 = 1; +EXPLAIN SELECT f1, f2 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL f1 9 NULL 1 Using index +SELECT f1, f2 FROM t2; +f1 f2 +2 2 +DROP TABLE t2, t1; +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, +KEY (f1, f2))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +SET FOREIGN_KEY_CHECKS = 0; +ALTER TABLE t2 ADD FOREIGN KEY (f1) REFERENCES t1(f1) +ON UPDATE CASCADE, ALGORITHM=INPLACE; +SET FOREIGN_KEY_CHECKS = 1; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f2 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL f1 9 NULL 1 Using index +SELECT f1, f2 FROM t2; +f1 f2 +3 3 +DROP TABLE t2, t1; +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, +KEY (f1, f2))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 ADD FOREIGN KEY (f1) REFERENCES t1(f1) +ON UPDATE CASCADE, ALGORITHM=COPY; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f2 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL f1 9 NULL 1 Using index +SELECT f1, f2 FROM t2; +f1 f2 +3 3 +DROP TABLE t2, t1; +CREATE TABLE t1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=INNODB; +CREATE TABLE t2(f1 INT NOT NULL, f2 INT AS (1) VIRTUAL, +f3 INT AS (2) VIRTUAL, +FOREIGN KEY idx (f1) REFERENCES t1(f1) ON UPDATE CASCADE, +KEY idx1 (f2, f1, f3))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 DROP COLUMN f2, ALGORITHM=INPLACE; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f3 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL idx1 9 NULL 1 Using index +SELECT f1, f3 FROM t2; +f1 f3 +3 2 +DROP TABLE t2, t1; +CREATE TABLE t1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=INNODB; +CREATE TABLE t2(f1 INT NOT NULL, f2 INT AS (1) VIRTUAL, +f3 INT AS (2) VIRTUAL, +FOREIGN KEY idx (f1) REFERENCES t1(f1) ON UPDATE CASCADE, +KEY idx1 (f2, f1, f3))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 DROP COLUMN f2, ALGORITHM=COPY; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f3 FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL idx1 9 NULL 1 Using index +SELECT f1, f3 FROM t2; +f1 f3 +3 2 +DROP TABLE t2, t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test index 78b2159e020..6b02b0adbbe 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -490,3 +490,89 @@ UPDATE t1 SET fld1= 2; SELECT fld2 FROM t2; SELECT * FROM t2; DROP TABLE t2, t1; + +# Foreign key constraint references to virtual index +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, + KEY (f1, f2), FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +EXPLAIN SELECT f1, f2 FROM t2; +SELECT f1, f2 FROM t2; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2(f1) VALUES(2); +DROP TABLE t2, t1; + +# Update foreign key constraint references to virtual index +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, + KEY (f1, f2), FOREIGN KEY(f1) REFERENCES t1(f1) + ON UPDATE CASCADE)ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +EXPLAIN SELECT f1, f2 FROM t2; +SELECT f1, f2 FROM t2; +UPDATE t1 SET f1 = 2 WHERE f1 = 1; +EXPLAIN SELECT f1, f2 FROM t2; +SELECT f1, f2 FROM t2; +DROP TABLE t2, t1; + +# Add foreign key constraint via inplace alter references to virtual index + +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, + KEY (f1, f2))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +SET FOREIGN_KEY_CHECKS = 0; +ALTER TABLE t2 ADD FOREIGN KEY (f1) REFERENCES t1(f1) + ON UPDATE CASCADE, ALGORITHM=INPLACE; +SET FOREIGN_KEY_CHECKS = 1; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f2 FROM t2; +SELECT f1, f2 FROM t2; +DROP TABLE t2, t1; + +# Add foreign key constraint via copy alter references to virtual index + +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY)ENGINE=INNODB; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT AS (f1) VIRTUAL, + KEY (f1, f2))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 ADD FOREIGN KEY (f1) REFERENCES t1(f1) + ON UPDATE CASCADE, ALGORITHM=COPY; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f2 FROM t2; +SELECT f1, f2 FROM t2; +DROP TABLE t2, t1; + +# Drop column via inplace alter which triggers to remove the FK index idx + +CREATE TABLE t1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=INNODB; +CREATE TABLE t2(f1 INT NOT NULL, f2 INT AS (1) VIRTUAL, + f3 INT AS (2) VIRTUAL, + FOREIGN KEY idx (f1) REFERENCES t1(f1) ON UPDATE CASCADE, + KEY idx1 (f2, f1, f3))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 DROP COLUMN f2, ALGORITHM=INPLACE; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f3 FROM t2; +SELECT f1, f3 FROM t2; +DROP TABLE t2, t1; + +# Drop column via copy alter which triggers to remove the FK index idx + +CREATE TABLE t1(f1 INT NOT NULL, PRIMARY KEY(f1))ENGINE=INNODB; +CREATE TABLE t2(f1 INT NOT NULL, f2 INT AS (1) VIRTUAL, + f3 INT AS (2) VIRTUAL, + FOREIGN KEY idx (f1) REFERENCES t1(f1) ON UPDATE CASCADE, + KEY idx1 (f2, f1, f3))ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +INSERT INTO t2(f1) VALUES(1); +ALTER TABLE t2 DROP COLUMN f2, ALGORITHM=COPY; +UPDATE t1 SET f1 = 3; +EXPLAIN SELECT f1, f3 FROM t2; +SELECT f1, f3 FROM t2; +DROP TABLE t2, t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 8f619c98187..90a866b4714 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1296,7 +1296,6 @@ innobase_find_fk_index( while (index != NULL) { if (!(index->type & DICT_FTS) - && !dict_index_has_virtual(index) && dict_foreign_qualify_index( table, col_names, columns, n_cols, index, NULL, true, 0,