diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-09-29 16:18:43 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-10-08 19:41:03 +0530 |
commit | 6504d3d229b086d20e5e4798b1ae10bbbd70d3c7 (patch) | |
tree | 0cab9d32d1112ceccc8781155550bb4665eb221b /storage | |
parent | 874942a0f910731b54eb57aef01c1bef701ab6ba (diff) | |
download | mariadb-git-6504d3d229b086d20e5e4798b1ae10bbbd70d3c7.tar.gz |
MDEV-23722 InnoDB: Assertion: result != FTS_INVALID in fts_trx_row_get_new_state
Marking of deletion of row in fts index happens twice in
self-referential foreign key relation. So while performing
referential checks of foreign key, InnoDB can avoid updating
of fts index if the foreign key has self-referential relationship.
Reviewed-by: Marko Mäkelä
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 19 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 41 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0mem.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/include/dict0mem.h | 4 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 41 |
6 files changed, 58 insertions, 70 deletions
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 6ace0ee9a75..157e695f696 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -852,3 +852,22 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set) return(out); } +/** Check whether fulltext index gets affected by foreign +key constraint. */ +bool dict_foreign_t::affects_fulltext() const +{ + if (foreign_table == referenced_table || !foreign_table->fts) + return false; + + for (ulint i = 0; i < n_fields; i++) + { + if (dict_table_is_fts_column( + foreign_table->fts->indexes, + dict_index_get_nth_col_no(foreign_index, i)) + != ULINT_UNDEFINED) + return true; + } + + return false; +} + diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 505d4925324..7c59789d313 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -848,6 +848,10 @@ struct dict_foreign_t{ does not generate new indexes implicitly */ dict_index_t* referenced_index;/*!< referenced index */ + + /** Check whether the fulltext index gets affected by + foreign key constraint */ + bool affects_fulltext() const; }; std::ostream& diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index ecbfd03ec93..4d86b0f333c 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -510,7 +510,7 @@ row_ins_cascade_calc_update_vec( n_fields_updated = 0; - *fts_col_affected = FALSE; + *fts_col_affected = foreign->affects_fulltext(); if (table->fts) { doc_id_pos = dict_table_get_nth_col_pos( @@ -631,16 +631,6 @@ row_ins_cascade_calc_update_vec( padded_data, min_size); } - /* Check whether the current column has - FTS index on it */ - if (table->fts - && dict_table_is_fts_column( - table->fts->indexes, - dict_col_get_no(col)) - != ULINT_UNDEFINED) { - *fts_col_affected = TRUE; - } - /* If Doc ID is updated, check whether the Doc ID is valid */ if (table->fts @@ -977,7 +967,6 @@ row_ins_foreign_check_on_constraint( upd_t* update; ulint n_to_update; dberr_t err; - ulint i; trx_t* trx; mem_heap_t* tmp_heap = NULL; doc_id_t doc_id = FTS_NULL_DOC_ID; @@ -1191,7 +1180,7 @@ row_ins_foreign_check_on_constraint( UNIV_MEM_INVALID(update->fields, update->n_fields * sizeof *update->fields); - for (i = 0; i < foreign->n_fields; i++) { + for (ulint i = 0; i < foreign->n_fields; i++) { upd_field_t* ufield = &update->fields[i]; ufield->field_no = dict_table_get_nth_col_pos( @@ -1200,32 +1189,14 @@ row_ins_foreign_check_on_constraint( ufield->orig_len = 0; ufield->exp = NULL; dfield_set_null(&ufield->new_val); - - if (table->fts && dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i)) - != ULINT_UNDEFINED) { - fts_col_affacted = TRUE; - } } - if (fts_col_affacted) { - fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); - } - } else if (table->fts && cascade->is_delete) { - /* DICT_FOREIGN_ON_DELETE_CASCADE case */ - for (i = 0; i < foreign->n_fields; i++) { - if (table->fts && dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i)) - != ULINT_UNDEFINED) { - fts_col_affacted = TRUE; - } - } - - if (fts_col_affacted) { + if (foreign->affects_fulltext()) { fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); } + } else if (table->fts && cascade->is_delete + && foreign->affects_fulltext()) { + fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); } if (!node->is_delete diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index 89b9bd9aead..82480b13827 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -853,3 +853,22 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set) return(out); } +/** Check whether fulltext index gets affected by foreign +key constraint. */ +bool dict_foreign_t::affects_fulltext() const +{ + if (foreign_table == referenced_table || !foreign_table->fts) + return false; + + for (ulint i = 0; i < n_fields; i++) + { + if (dict_table_is_fts_column( + foreign_table->fts->indexes, + dict_index_get_nth_col_no(foreign_index, i)) + != ULINT_UNDEFINED) + return true; + } + + return false; +} + diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index 1dcc3ebdd0c..f39c89d8e4b 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -864,6 +864,10 @@ struct dict_foreign_t{ does not generate new indexes implicitly */ dict_index_t* referenced_index;/*!< referenced index */ + + /** Check whether the fulltext index gets affected by + foreign key constraint */ + bool affects_fulltext() const; }; std::ostream& diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index f7371d6b83e..c78f5bc8dc4 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -516,7 +516,7 @@ row_ins_cascade_calc_update_vec( n_fields_updated = 0; - *fts_col_affected = FALSE; + *fts_col_affected = foreign->affects_fulltext(); if (table->fts) { doc_id_pos = dict_table_get_nth_col_pos( @@ -637,16 +637,6 @@ row_ins_cascade_calc_update_vec( padded_data, min_size); } - /* Check whether the current column has - FTS index on it */ - if (table->fts - && dict_table_is_fts_column( - table->fts->indexes, - dict_col_get_no(col)) - != ULINT_UNDEFINED) { - *fts_col_affected = TRUE; - } - /* If Doc ID is updated, check whether the Doc ID is valid */ if (table->fts @@ -983,7 +973,6 @@ row_ins_foreign_check_on_constraint( upd_t* update; ulint n_to_update; dberr_t err; - ulint i; trx_t* trx; mem_heap_t* tmp_heap = NULL; doc_id_t doc_id = FTS_NULL_DOC_ID; @@ -1197,7 +1186,7 @@ row_ins_foreign_check_on_constraint( UNIV_MEM_INVALID(update->fields, update->n_fields * sizeof *update->fields); - for (i = 0; i < foreign->n_fields; i++) { + for (ulint i = 0; i < foreign->n_fields; i++) { upd_field_t* ufield = &update->fields[i]; ufield->field_no = dict_table_get_nth_col_pos( @@ -1206,32 +1195,14 @@ row_ins_foreign_check_on_constraint( ufield->orig_len = 0; ufield->exp = NULL; dfield_set_null(&ufield->new_val); - - if (table->fts && dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i)) - != ULINT_UNDEFINED) { - fts_col_affacted = TRUE; - } } - if (fts_col_affacted) { - fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); - } - } else if (table->fts && cascade->is_delete) { - /* DICT_FOREIGN_ON_DELETE_CASCADE case */ - for (i = 0; i < foreign->n_fields; i++) { - if (table->fts && dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i)) - != ULINT_UNDEFINED) { - fts_col_affacted = TRUE; - } - } - - if (fts_col_affacted) { + if (foreign->affects_fulltext()) { fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); } + } else if (table->fts && cascade->is_delete + && foreign->affects_fulltext()) { + fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); } if (!node->is_delete |