From 2748c4993c68aa4b03049a97f3657de42dd01c52 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 4 May 2020 13:42:38 +0530 Subject: 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. --- storage/xtradb/dict/dict0mem.cc | 46 ++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'storage/xtradb') diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index 51ca6de8cd2..89b9bd9aead 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -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(rc), to, + to_len + 1); + } else { + rc = static_cast( + 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 -- cgit v1.2.1