diff options
author | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2015-06-19 10:17:36 +0530 |
---|---|---|
committer | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2015-06-19 10:17:52 +0530 |
commit | db2ed27e0ebe13fa70972b9993ff9bbd2f29499f (patch) | |
tree | 0c40a1c820eaeb8313a61900a036427be984ad5e /storage | |
parent | dbbe747e54a320d810fff1896ed9e553d43a0bae (diff) | |
download | mariadb-git-db2ed27e0ebe13fa70972b9993ff9bbd2f29499f.tar.gz |
Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE
Problem:
If we add a referential integrity constraint with a duplicate
name, an error occurs. The foreign key object would not have
been added to the dictionary cache. In the error path, there
is an attempt to remove this foreign key object. Since this
object is not there, the search returns a NULL result.
De-referencing the null object results in this crash.
Solution:
If the search to the foreign key object failed, then don't
attempt to access it.
rb#9309 approved by Marko.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0dict.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 56baceb7a4b..5aca95aec0d 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -2533,10 +2533,14 @@ dict_foreign_remove_from_cache( if (rbt != NULL && foreign->id != NULL) { const ib_rbt_node_t* node = rbt_lookup(rbt, foreign->id); - dict_foreign_t* val = *(dict_foreign_t**) node->value; - if (val == foreign) { - rbt_delete(rbt, foreign->id); + if (node != NULL) { + dict_foreign_t* val + = *(dict_foreign_t**) node->value; + + if (val == foreign) { + rbt_delete(rbt, foreign->id); + } } } } @@ -2552,10 +2556,14 @@ dict_foreign_remove_from_cache( if (rbt != NULL && foreign->id != NULL) { const ib_rbt_node_t* node = rbt_lookup(rbt, foreign->id); - dict_foreign_t* val = *(dict_foreign_t**) node->value; - if (val == foreign) { - rbt_delete(rbt, foreign->id); + if (node != NULL) { + dict_foreign_t* val + = *(dict_foreign_t**) node->value; + + if (val == foreign) { + rbt_delete(rbt, foreign->id); + } } } } |