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

MDEV-25691 fixup: Correctly drop orphan foreign keys

innodb_drop_database_fk(): Use the correct length when comparing.
Fix a debug assertion in previously unreachable code.
This error was caught by MSAN.

innodb_drop_database(): Correct the SQL for traversing SYS_FOREIGN.
The incorrect code would cause orphan FOREIGN KEY entries to be
left behind in the test innodb.alter_foreign_crash.
parent 5d495fc4
...@@ -1295,12 +1295,13 @@ static ibool innodb_drop_database_fk(void *node, void *report) ...@@ -1295,12 +1295,13 @@ static ibool innodb_drop_database_fk(void *node, void *report)
ut_ad(name->type.mtype == DATA_VARCHAR); ut_ad(name->type.mtype == DATA_VARCHAR);
if (name->len == UNIV_SQL_NULL || name->len <= r->name.size() || if (name->len == UNIV_SQL_NULL || name->len <= r->name.size() ||
memcmp(static_cast<const char*>(name->data), r->name.data(), name->len)) memcmp(static_cast<const char*>(name->data), r->name.data(),
r->name.size()))
return false; /* End of matches */ return false; /* End of matches */
node= que_node_get_next(s->select_list); node= que_node_get_next(s->select_list);
const dfield_t *id= que_node_get_val(node); const dfield_t *id= que_node_get_val(node);
ut_ad(id->type.mtype == DATA_BINARY); ut_ad(id->type.mtype == DATA_VARCHAR);
ut_ad(!que_node_get_next(node)); ut_ad(!que_node_get_next(node));
if (id->len != UNIV_SQL_NULL) if (id->len != UNIV_SQL_NULL)
...@@ -1407,8 +1408,7 @@ static void innodb_drop_database(handlerton*, char *path) ...@@ -1407,8 +1408,7 @@ static void innodb_drop_database(handlerton*, char *path)
"DECLARE FUNCTION fk_report;\n" "DECLARE FUNCTION fk_report;\n"
"DECLARE CURSOR fkf IS\n" "DECLARE CURSOR fkf IS\n"
"SELECT ID FROM SYS_FOREIGN WHERE FOR_NAME >= :db FOR UPDATE\n" "SELECT ID FROM SYS_FOREIGN WHERE ID >= :db FOR UPDATE;\n"
"ORDER BY FOR_NAME;\n"
"DECLARE CURSOR fkr IS\n" "DECLARE CURSOR fkr IS\n"
"SELECT REF_NAME,ID FROM SYS_FOREIGN WHERE REF_NAME >= :db FOR UPDATE\n" "SELECT REF_NAME,ID FROM SYS_FOREIGN WHERE REF_NAME >= :db FOR UPDATE\n"
...@@ -1428,7 +1428,7 @@ static void innodb_drop_database(handlerton*, char *path) ...@@ -1428,7 +1428,7 @@ static void innodb_drop_database(handlerton*, char *path)
" IF (SQL % NOTFOUND) THEN EXIT; END IF;\n" " IF (SQL % NOTFOUND) THEN EXIT; END IF;\n"
" IF SUBSTR(fk, 0, LENGTH(:db)) <> :db THEN EXIT; END IF;\n" " IF SUBSTR(fk, 0, LENGTH(:db)) <> :db THEN EXIT; END IF;\n"
" DELETE FROM SYS_FOREIGN_COLS WHERE ID=fk;\n" " DELETE FROM SYS_FOREIGN_COLS WHERE ID=fk;\n"
" DELETE FROM SYS_FOREIGN WHERE FOR_NAME=fk;\n" " DELETE FROM SYS_FOREIGN WHERE CURRENT OF fkf;\n"
"END LOOP;\n" "END LOOP;\n"
"CLOSE fkf;\n" "CLOSE fkf;\n"
......
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