diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-10-21 14:02:04 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-10-21 14:02:04 +0300 |
commit | 620ea816adeceaba7c875679ab8505f4c07a22b8 (patch) | |
tree | a52749e4f0c1fd07bc9f0c2a1159706a4e7789c3 /storage | |
parent | a1b6691f93e50ad4a8a53dbf89ba578d6a64b2cb (diff) | |
parent | b4c225ac354686242b5336da84b7a758640936bd (diff) | |
download | mariadb-git-620ea816adeceaba7c875679ab8505f4c07a22b8.tar.gz |
Merge 10.1 into 10.2
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 63 | ||||
-rw-r--r-- | storage/innobase/fts/fts0que.cc | 15 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 12 | ||||
-rw-r--r-- | storage/innobase/include/fts0ast.h | 2 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 49 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 34 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0mem.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0que.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/include/dict0mem.h | 4 | ||||
-rw-r--r-- | storage/xtradb/include/fts0ast.h | 15 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 41 |
11 files changed, 123 insertions, 150 deletions
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 8327318e46c..639fdbac22b 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -96,6 +96,28 @@ operator<<( return(s << ut_get_name(NULL, table_name.m_name)); } +/** @return whether a table belongs to a system database */ +static bool dict_mem_table_is_system(char *name) +{ + /* table has the following format: database/table + and some system table are of the form SYS_* */ + if (strchr(name, '/')) { + size_t table_len = strlen(name); + const char *system_db; + int i = 0; + while ((system_db = innobase_system_databases[i++]) + && (system_db != NullS)) { + size_t len = strlen(system_db); + if (table_len > len && !strncmp(name, system_db, len)) { + return true; + } + } + return false; + } else { + return true; + } +} + /**********************************************************************//** Creates a table memory object. @return own: table object */ @@ -1195,31 +1217,20 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set) return(out); } -/****************************************************************//** -Determines if a table belongs to a system database -@return */ -bool -dict_mem_table_is_system( -/*================*/ - char *name) /*!< in: table name */ +/** Check whether fulltext index gets affected by foreign +key constraint. */ +bool dict_foreign_t::affects_fulltext() const { - ut_ad(name); - - /* table has the following format: database/table - and some system table are of the form SYS_* */ - if (strchr(name, '/')) { - size_t table_len = strlen(name); - const char *system_db; - int i = 0; - while ((system_db = innobase_system_databases[i++]) - && (system_db != NullS)) { - size_t len = strlen(system_db); - if (table_len > len && !strncmp(name, system_db, len)) { - return true; - } - } - return false; - } else { - return true; - } + if (foreign_table == referenced_table || !foreign_table->fts) + return false; + + for (ulint i= 0; i < n_fields; i++) + { + const dict_col_t *col= dict_index_get_nth_col(foreign_index, i); + if (dict_table_is_fts_column(foreign_table->fts->indexes, col->ind, + col->is_virtual()) != ULINT_UNDEFINED) + return true; + } + + return false; } diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 6396dad4aa5..be758c13d52 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -144,6 +144,8 @@ struct fts_query_t { ib_rbt_t* wildcard_words; /*!< words with wildcard */ bool multi_exist; /*!< multiple FTS_EXIST oper */ + byte visiting_sub_exp; /*!< count of nested + fts_ast_visit_sub_exp() */ st_mysql_ftparser* parser; /*!< fts plugin parser */ }; @@ -2963,6 +2965,8 @@ fts_query_get_token( return(new_ptr); } +static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*); + /*****************************************************************//** Visit every node of the AST. */ static @@ -3087,6 +3091,14 @@ fts_ast_visit_sub_exp( ut_a(node->type == FTS_AST_SUBEXP_LIST); + /* To avoid stack overflow, we limit the mutual recursion + depth between fts_ast_visit(), fts_query_visitor() and + fts_ast_visit_sub_exp(). */ + if (query->visiting_sub_exp++ > 31) { + query->error = DB_OUT_OF_MEMORY; + DBUG_RETURN(query->error); + } + cur_oper = query->oper; /* Save current result set */ @@ -3109,6 +3121,7 @@ fts_ast_visit_sub_exp( /* Reinstate parent node state */ query->multi_exist = multi_exist; query->oper = cur_oper; + query->visiting_sub_exp--; /* Merge the sub-expression result with the parent result set. */ subexpr_doc_ids = query->doc_ids; diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 21d9e763178..e8005cbc352 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -314,14 +314,6 @@ dict_mem_table_create( ulint n_v_cols, /*!< in: number of virtual columns */ ulint flags, /*!< in: table flags */ ulint flags2); /*!< in: table flags2 */ -/**********************************************************************//** -Determines if a table belongs to a system database -@return */ -UNIV_INTERN -bool -dict_mem_table_is_system( -/*==================*/ - char *name); /*!< in: table name */ /****************************************************************//** Free a table memory object. */ void @@ -1214,6 +1206,10 @@ struct dict_foreign_t{ dict_vcol_set* v_cols; /*!< set of virtual columns affected by foreign key constraint. */ + + /** Check whether the fulltext index gets affected by + foreign key constraint */ + bool affects_fulltext() const; }; std::ostream& diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h index bad040fdcda..5799776c32d 100644 --- a/storage/innobase/include/fts0ast.h +++ b/storage/innobase/include/fts0ast.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 87f62125c03..ca04be71953 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -496,7 +496,7 @@ row_ins_cascade_calc_update_vec( n_fields_updated = 0; - bool affects_fulltext = false; + bool affects_fulltext = foreign->affects_fulltext(); if (table->fts) { doc_id_pos = dict_table_get_nth_col_pos( @@ -617,17 +617,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), - dict_col_is_virtual(col)) - != ULINT_UNDEFINED) { - affects_fulltext = true; - } - /* If Doc ID is updated, check whether the Doc ID is valid */ if (table->fts @@ -1257,8 +1246,6 @@ row_ins_foreign_check_on_constraint( update->n_fields * sizeof *update->fields); #endif /* HAVE_valgrind_or_MSAN */ - bool affects_fulltext = false; - for (ulint i = 0; i < foreign->n_fields; i++) { upd_field_t* ufield = &update->fields[i]; ulint col_no = dict_index_get_nth_col_no( @@ -1274,19 +1261,9 @@ row_ins_foreign_check_on_constraint( ufield->orig_len = 0; ufield->exp = NULL; dfield_set_null(&ufield->new_val); - - if (!affects_fulltext - && table->fts && dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i), - dict_col_is_virtual( - dict_index_get_nth_col(index, i))) - != ULINT_UNDEFINED) { - affects_fulltext = true; - } } - if (affects_fulltext) { + if (foreign->affects_fulltext()) { fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL); } @@ -1300,25 +1277,9 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } } - } else if (table->fts && cascade->is_delete) { - /* DICT_FOREIGN_ON_DELETE_CASCADE case */ - bool affects_fulltext = false; - - for (ulint i = 0; i < foreign->n_fields; i++) { - if (dict_table_is_fts_column( - table->fts->indexes, - dict_index_get_nth_col_no(index, i), - dict_col_is_virtual( - dict_index_get_nth_col(index, i))) - != ULINT_UNDEFINED) { - affects_fulltext = true; - break; - } - } - - if (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/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index c07b42ea8d7..0451a240ffc 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4024,7 +4024,7 @@ row_sel_try_search_shortcut_for_mysql( /*********************************************************************//** Check a pushed-down index condition. -@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ +@return ICP_ABORTED_BY_USER, ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ static ICP_RESULT row_search_idx_cond_check( @@ -4551,10 +4551,13 @@ row_search_mvcc( switch (row_search_idx_cond_check( buf, prebuilt, rec, offsets)) { - case ICP_NO_MATCH: - case ICP_OUT_OF_RANGE: case ICP_ABORTED_BY_USER: + mtr_commit(&mtr); + err = DB_INTERRUPTED; + goto unlock_and_exit; case ICP_ERROR: + case ICP_NO_MATCH: + case ICP_OUT_OF_RANGE: goto shortcut_mismatch; case ICP_MATCH: goto shortcut_match; @@ -4582,14 +4585,11 @@ row_search_mvcc( shortcut_match: mtr.commit(); - + err = DB_SUCCESS; + unlock_and_exit: /* NOTE that we do NOT store the cursor position */ - - err = DB_SUCCESS; - rw_lock_s_unlock(latch); - goto func_exit; case SEL_EXHAUSTED: @@ -4597,13 +4597,7 @@ row_search_mvcc( mtr.commit(); err = DB_RECORD_NOT_FOUND; - - rw_lock_s_unlock(latch); - - /* NOTE that we do NOT store the cursor - position */ - - goto func_exit; + goto unlock_and_exit; case SEL_RETRY: break; @@ -5336,8 +5330,10 @@ no_gap_lock: buf, prebuilt, rec, offsets)) { case ICP_NO_MATCH: goto next_rec; - case ICP_OUT_OF_RANGE: case ICP_ABORTED_BY_USER: + err = DB_INTERRUPTED; + goto idx_cond_failed; + case ICP_OUT_OF_RANGE: case ICP_ERROR: err = DB_RECORD_NOT_FOUND; goto idx_cond_failed; @@ -5396,9 +5392,11 @@ locks_ok_del_marked: row_unlock_for_mysql(prebuilt, TRUE); } goto next_rec; + case ICP_ABORTED_BY_USER: + err = DB_INTERRUPTED; + goto idx_cond_failed; case ICP_OUT_OF_RANGE: - case ICP_ABORTED_BY_USER: - case ICP_ERROR: + case ICP_ERROR: err = DB_RECORD_NOT_FOUND; goto idx_cond_failed; case ICP_MATCH: 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/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc index 8fce8efac2b..0c51e702907 100644 --- a/storage/xtradb/fts/fts0que.cc +++ b/storage/xtradb/fts/fts0que.cc @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -146,6 +146,8 @@ struct fts_query_t { fts_word_freq_t */ bool multi_exist; /*!< multiple FTS_EXIST oper */ + byte visiting_sub_exp; /*!< count of nested + fts_ast_visit_sub_exp() */ }; /** For phrase matching, first we collect the documents and the positions @@ -2856,6 +2858,8 @@ fts_query_get_token( return(new_ptr); } +static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*); + /*****************************************************************//** Visit every node of the AST. */ static @@ -2945,7 +2949,7 @@ Process (nested) sub-expression, create a new result set to store the sub-expression result by processing nodes under current sub-expression list. Merge the sub-expression result with that of parent expression list. @return DB_SUCCESS if all well */ -UNIV_INTERN +static dberr_t fts_ast_visit_sub_exp( /*==================*/ @@ -2965,6 +2969,14 @@ fts_ast_visit_sub_exp( ut_a(node->type == FTS_AST_SUBEXP_LIST); + /* To avoid stack overflow, we limit the mutual recursion + depth between fts_ast_visit(), fts_query_visitor() and + fts_ast_visit_sub_exp(). */ + if (query->visiting_sub_exp++ > 31) { + query->error = DB_OUT_OF_MEMORY; + DBUG_RETURN(query->error); + } + cur_oper = query->oper; /* Save current result set */ @@ -2987,6 +2999,7 @@ fts_ast_visit_sub_exp( /* Reinstate parent node state */ query->multi_exist = multi_exist; query->oper = cur_oper; + query->visiting_sub_exp--; /* Merge the sub-expression result with the parent result set. */ subexpr_doc_ids = query->doc_ids; 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/include/fts0ast.h b/storage/xtradb/include/fts0ast.h index b7d467e0082..b7870cbc7bc 100644 --- a/storage/xtradb/include/fts0ast.h +++ b/storage/xtradb/include/fts0ast.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -204,19 +204,6 @@ fts_ast_visit( operator, currently we only ignore FTS_IGNORE operator */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/*****************************************************************//** -Process (nested) sub-expression, create a new result set to store the -sub-expression result by processing nodes under current sub-expression -list. Merge the sub-expression result with that of parent expression list. -@return DB_SUCCESS if all went well */ -UNIV_INTERN -dberr_t -fts_ast_visit_sub_exp( -/*==================*/ - fts_ast_node_t* node, /*!< in: instance to traverse*/ - fts_ast_callback visitor, /*!< in: callback */ - void* arg) /*!< in: callback arg */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************** Create a lex instance.*/ UNIV_INTERN 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 |