mirror of
https://github.com/MariaDB/server.git
synced 2025-05-28 13:01:41 +03:00
MDEV-19092 Server crash when renaming the column when
FOREIGN_KEY_CHECKS is disabled - Referenced index can be null While renaming the referenced column name. In that case, rename the referenced column name in dict_foreign_t and find the equivalent referenced index.
This commit is contained in:
parent
d233fd14a3
commit
2748c4993c
@ -119,4 +119,14 @@ ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES tx(x);
|
||||
ALTER TABLE t1 DROP KEY idx;
|
||||
ALTER TABLE t1 CHANGE a c INT;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
|
||||
ALTER TABLE t1 ADD COLUMN f INT;
|
||||
SET FOREIGN_KEY_CHECKS= OFF;
|
||||
ALTER TABLE t1 DROP KEY idx;
|
||||
ALTER TABLE t1 ADD KEY idx (f1);
|
||||
SET FOREIGN_KEY_CHECKS= ON;
|
||||
ALTER TABLE t1 DROP f3;
|
||||
ALTER TABLE t1 CHANGE f f3 INT;
|
||||
DROP TABLE t1;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
@ -144,4 +144,17 @@ ALTER TABLE t1 DROP KEY idx;
|
||||
ALTER TABLE t1 CHANGE a c INT;
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
|
||||
ALTER TABLE t1 ADD COLUMN f INT;
|
||||
SET FOREIGN_KEY_CHECKS= OFF;
|
||||
ALTER TABLE t1 DROP KEY idx;
|
||||
ALTER TABLE t1 ADD KEY idx (f1);
|
||||
SET FOREIGN_KEY_CHECKS= ON;
|
||||
ALTER TABLE t1 DROP f3;
|
||||
ALTER TABLE t1 CHANGE f f3 INT;
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
@ -415,17 +415,15 @@ dict_mem_table_col_rename_low(
|
||||
}
|
||||
}
|
||||
|
||||
dict_index_t* new_index = dict_foreign_find_index(
|
||||
/* New index can be null if InnoDB already dropped
|
||||
the foreign index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->foreign_index = dict_foreign_find_index(
|
||||
foreign->foreign_table, NULL,
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields, NULL, true, false,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* New index can be null if InnoDB already dropped
|
||||
the foreign index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->foreign_index = new_index;
|
||||
|
||||
} else {
|
||||
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
@ -447,7 +445,41 @@ dict_mem_table_col_rename_low(
|
||||
|
||||
foreign = *it;
|
||||
|
||||
ut_ad(foreign->referenced_index != NULL);
|
||||
if (!foreign->referenced_index) {
|
||||
/* Referenced index could have been dropped
|
||||
when foreign_key_checks is disabled. In that case,
|
||||
rename the corresponding referenced_col_names and
|
||||
find the equivalent referenced index also */
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
|
||||
const char*& rc =
|
||||
foreign->referenced_col_names[f];
|
||||
if (strcmp(rc, from)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (to_len <= strlen(rc)) {
|
||||
memcpy(const_cast<char*>(rc), to,
|
||||
to_len + 1);
|
||||
} else {
|
||||
rc = static_cast<char*>(
|
||||
mem_heap_dup(
|
||||
foreign->heap,
|
||||
to, to_len + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* New index can be null if InnoDB already dropped
|
||||
the referenced index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->referenced_index = dict_foreign_find_index(
|
||||
foreign->referenced_table, NULL,
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields, NULL, true, false,
|
||||
NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
/* foreign->referenced_col_names[] need to be
|
||||
|
@ -416,17 +416,15 @@ dict_mem_table_col_rename_low(
|
||||
}
|
||||
}
|
||||
|
||||
dict_index_t* new_index = dict_foreign_find_index(
|
||||
/* New index can be null if XtraDB already dropped
|
||||
the foreign index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->foreign_index = dict_foreign_find_index(
|
||||
foreign->foreign_table, NULL,
|
||||
foreign->foreign_col_names,
|
||||
foreign->n_fields, NULL, true, false,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* New index can be null if XtraDB already dropped
|
||||
the foreign index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->foreign_index = new_index;
|
||||
|
||||
} else {
|
||||
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
@ -448,7 +446,41 @@ dict_mem_table_col_rename_low(
|
||||
|
||||
foreign = *it;
|
||||
|
||||
ut_ad(foreign->referenced_index != NULL);
|
||||
if (!foreign->referenced_index) {
|
||||
/* Referenced index could have been dropped
|
||||
when foreign_key_checks is disabled. In that case,
|
||||
rename the corresponding referenced_col_names and
|
||||
find the equivalent referenced index also */
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
|
||||
const char*& rc =
|
||||
foreign->referenced_col_names[f];
|
||||
|
||||
if (strcmp(rc, from)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (to_len <= strlen(rc)) {
|
||||
memcpy(const_cast<char*>(rc), to,
|
||||
to_len + 1);
|
||||
} else {
|
||||
rc = static_cast<char*>(
|
||||
mem_heap_dup(
|
||||
foreign->heap,
|
||||
to, to_len + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* New index can be null if InnoDB already dropped
|
||||
the referenced index when FOREIGN_KEY_CHECKS is
|
||||
disabled */
|
||||
foreign->referenced_index = dict_foreign_find_index(
|
||||
foreign->referenced_table, NULL,
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields, NULL, true, false,
|
||||
NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned f = 0; f < foreign->n_fields; f++) {
|
||||
/* foreign->referenced_col_names[] need to be
|
||||
|
Loading…
x
Reference in New Issue
Block a user