summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-09-29 16:18:43 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-10-08 19:41:03 +0530
commit6504d3d229b086d20e5e4798b1ae10bbbd70d3c7 (patch)
tree0cab9d32d1112ceccc8781155550bb4665eb221b /storage
parent874942a0f910731b54eb57aef01c1bef701ab6ba (diff)
downloadmariadb-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.cc19
-rw-r--r--storage/innobase/include/dict0mem.h4
-rw-r--r--storage/innobase/row/row0ins.cc41
-rw-r--r--storage/xtradb/dict/dict0mem.cc19
-rw-r--r--storage/xtradb/include/dict0mem.h4
-rw-r--r--storage/xtradb/row/row0ins.cc41
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