MDEV-32527 Server aborts during alter operation when table doesn't have foreign index

Problem:
========
InnoDB fails to find the foreign key index for the
foreign key relation in the table while iterating the
foreign key constraints during alter operation. This is
caused by commit 5f09b53b
(MDEV-31086).

Fix:
====
In check_col_is_in_fk_indexes(), while iterating through
the foreign key relationship, InnoDB should consider that
foreign key relation may not have foreign index when
foreign key check is disabled.
parent 186ac474
...@@ -105,4 +105,17 @@ ALTER TABLE t MODIFY f VARCHAR(8); ...@@ -105,4 +105,17 @@ ALTER TABLE t MODIFY f VARCHAR(8);
ALTER TABLE t MODIFY vf VARCHAR(18); ALTER TABLE t MODIFY vf VARCHAR(18);
ERROR HY000: This is not yet supported for generated columns ERROR HY000: This is not yet supported for generated columns
DROP TABLE t; DROP TABLE t;
#
# MDEV-32527 Server aborts during alter operation
# when table doesn't have foreign index
#
CREATE TABLE t1 (f1 INT NOT NULL, INDEX(f1)) ENGINE=InnoDB;
CREATE TABLE t2(f1 INT NOT NULL, f2 VARCHAR(100) DEFAULT NULL,
INDEX idx(f1, f2),
FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB;
SET SESSION FOREIGN_KEY_CHECKS = OFF;
ALTER TABLE t2 DROP INDEX idx;
ALTER TABLE t2 MODIFY f2 VARCHAR(1023);
SET SESSION FOREIGN_KEY_CHECKS = ON;
DROP TABLE t2, t1;
# End of 10.4 tests # End of 10.4 tests
...@@ -139,4 +139,18 @@ ALTER TABLE t MODIFY f VARCHAR(8); ...@@ -139,4 +139,18 @@ ALTER TABLE t MODIFY f VARCHAR(8);
--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN --error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN
ALTER TABLE t MODIFY vf VARCHAR(18); ALTER TABLE t MODIFY vf VARCHAR(18);
DROP TABLE t; DROP TABLE t;
--echo #
--echo # MDEV-32527 Server aborts during alter operation
--echo # when table doesn't have foreign index
--echo #
CREATE TABLE t1 (f1 INT NOT NULL, INDEX(f1)) ENGINE=InnoDB;
CREATE TABLE t2(f1 INT NOT NULL, f2 VARCHAR(100) DEFAULT NULL,
INDEX idx(f1, f2),
FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=INNODB;
SET SESSION FOREIGN_KEY_CHECKS = OFF;
ALTER TABLE t2 DROP INDEX idx;
ALTER TABLE t2 MODIFY f2 VARCHAR(1023);
SET SESSION FOREIGN_KEY_CHECKS = ON;
DROP TABLE t2, t1;
--echo # End of 10.4 tests --echo # End of 10.4 tests
...@@ -7680,20 +7680,17 @@ bool check_col_is_in_fk_indexes( ...@@ -7680,20 +7680,17 @@ bool check_col_is_in_fk_indexes(
{ {
char *fk_id= nullptr; char *fk_id= nullptr;
for (dict_foreign_set::iterator it= table->foreign_set.begin(); for (const auto &f : table->foreign_set)
it!= table->foreign_set.end();)
{ {
if (std::find(drop_fk.begin(), drop_fk.end(), (*it)) if (!f->foreign_index ||
!= drop_fk.end()) std::find(drop_fk.begin(), drop_fk.end(), f) != drop_fk.end())
goto next_item; continue;
for (ulint i= 0; i < (*it)->n_fields; i++) for (ulint i= 0; i < f->n_fields; i++)
if ((*it)->foreign_index->fields[i].col == col) if (f->foreign_index->fields[i].col == col)
{ {
fk_id= (*it)->id; fk_id= f->id;
goto err_exit; goto err_exit;
} }
next_item:
it++;
} }
for (const auto &a : add_fk) for (const auto &a : add_fk)
...@@ -7703,17 +7700,16 @@ bool check_col_is_in_fk_indexes( ...@@ -7703,17 +7700,16 @@ bool check_col_is_in_fk_indexes(
if (a->foreign_index->fields[i].col == col) if (a->foreign_index->fields[i].col == col)
{ {
fk_id= a->id; fk_id= a->id;
goto err_exit; goto err_exit;
} }
} }
} }
for (const auto &f : table->referenced_set) for (const auto &f : table->referenced_set)
{ {
if (!f->referenced_index) continue;
for (ulint i= 0; i < f->n_fields; i++) for (ulint i= 0; i < f->n_fields; i++)
{ {
if (!f->referenced_index)
continue;
if (f->referenced_index->fields[i].col == col) if (f->referenced_index->fields[i].col == col)
{ {
my_error(ER_FK_COLUMN_CANNOT_CHANGE_CHILD, MYF(0), my_error(ER_FK_COLUMN_CANNOT_CHANGE_CHILD, MYF(0),
......
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