diff options
Diffstat (limited to 'storage/xtradb/row')
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 26 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 152 | ||||
-rw-r--r-- | storage/xtradb/row/row0upd.cc | 71 |
3 files changed, 128 insertions, 121 deletions
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index ecbf9425f43..c0396a96cfc 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1745,12 +1745,11 @@ do_possible_lock_wait: table case (check_ref == 0), since MDL lock will prevent concurrent DDL and DML on the same table */ if (!check_ref) { - for (const dict_foreign_t* check_foreign - = UT_LIST_GET_FIRST( table->referenced_list); - check_foreign; - check_foreign = UT_LIST_GET_NEXT( - referenced_list, check_foreign)) { - if (check_foreign == foreign) { + for (dict_foreign_set::iterator it + = table->referenced_set.begin(); + it != table->referenced_set.end(); + ++it) { + if (*it == foreign) { verified = true; break; } @@ -1803,12 +1802,15 @@ row_ins_check_foreign_constraints( trx = thr_get_trx(thr); - foreign = UT_LIST_GET_FIRST(table->foreign_list); - DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd, "foreign_constraint_check_for_ins"); - while (foreign) { + for (dict_foreign_set::iterator it = table->foreign_set.begin(); + it != table->foreign_set.end(); + ++it) { + + foreign = *it; + if (foreign->foreign_index == index) { dict_table_t* ref_table = NULL; dict_table_t* foreign_table = foreign->foreign_table; @@ -1864,8 +1866,6 @@ row_ins_check_foreign_constraints( return(err); } } - - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } return(DB_SUCCESS); @@ -2915,7 +2915,7 @@ row_ins_clust_index_entry( dberr_t err; ulint n_uniq; - if (UT_LIST_GET_FIRST(index->table->foreign_list)) { + if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints( index->table, index, entry, thr); if (err != DB_SUCCESS) { @@ -2973,7 +2973,7 @@ row_ins_sec_index_entry( mem_heap_t* offsets_heap; mem_heap_t* heap; - if (UT_LIST_GET_FIRST(index->table->foreign_list)) { + if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, entry, thr); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 671714c5b3d..ebf991e6ff8 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -62,6 +62,7 @@ Created 9/17/2000 Heikki Tuuri #include "m_string.h" #include "my_sys.h" #include "ha_prototypes.h" +#include <algorithm> /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; @@ -1576,8 +1577,6 @@ init_fts_doc_id_for_ref( { dict_foreign_t* foreign; - foreign = UT_LIST_GET_FIRST(table->referenced_list); - table->fk_max_recusive_level = 0; (*depth)++; @@ -1589,17 +1588,25 @@ init_fts_doc_id_for_ref( /* Loop through this table's referenced list and also recursively traverse each table's foreign table list */ - while (foreign && foreign->foreign_table) { - if (foreign->foreign_table->fts) { - fts_init_doc_id(foreign->foreign_table); + for (dict_foreign_set::iterator it = table->referenced_set.begin(); + it != table->referenced_set.end(); + ++it) { + + foreign = *it; + + if (foreign->foreign_table == NULL) { + break; } - if (UT_LIST_GET_LEN(foreign->foreign_table->referenced_list) - > 0 && foreign->foreign_table != table) { - init_fts_doc_id_for_ref(foreign->foreign_table, depth); + if (foreign->foreign_table->fts != NULL) { + fts_init_doc_id(foreign->foreign_table); } - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + if (!foreign->foreign_table->referenced_set.empty() + && foreign->foreign_table != table) { + init_fts_doc_id_for_ref( + foreign->foreign_table, depth); + } } } @@ -2839,43 +2846,47 @@ row_discard_tablespace_foreign_key_checks( const trx_t* trx, /*!< in: transaction handle */ const dict_table_t* table) /*!< in: table to be discarded */ { - const dict_foreign_t* foreign; + + if (srv_read_only_mode || !trx->check_foreigns) { + return(DB_SUCCESS); + } /* Check if the table is referenced by foreign key constraints from some other table (not the table itself) */ + dict_foreign_set::iterator it + = std::find_if(table->referenced_set.begin(), + table->referenced_set.end(), + dict_foreign_different_tables()); - for (foreign = UT_LIST_GET_FIRST(table->referenced_list); - foreign && foreign->foreign_table == table; - foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { - + if (it == table->referenced_set.end()) { + return(DB_SUCCESS); } - if (!srv_read_only_mode && foreign && trx->check_foreigns) { + const dict_foreign_t* foreign = *it; + FILE* ef = dict_foreign_err_file; - FILE* ef = dict_foreign_err_file; + ut_ad(foreign->foreign_table != table); + ut_ad(foreign->referenced_table == table); - /* We only allow discarding a referenced table if - FOREIGN_KEY_CHECKS is set to 0 */ + /* We only allow discarding a referenced table if + FOREIGN_KEY_CHECKS is set to 0 */ - mutex_enter(&dict_foreign_err_mutex); + mutex_enter(&dict_foreign_err_mutex); - rewind(ef); + rewind(ef); - ut_print_timestamp(ef); + ut_print_timestamp(ef); - fputs(" Cannot DISCARD table ", ef); - ut_print_name(stderr, trx, TRUE, table->name); - fputs("\n" - "because it is referenced by ", ef); - ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name); - putc('\n', ef); + fputs(" Cannot DISCARD table ", ef); + ut_print_name(stderr, trx, TRUE, table->name); + fputs("\n" + "because it is referenced by ", ef); + ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name); + putc('\n', ef); - mutex_exit(&dict_foreign_err_mutex); - - return(DB_CANNOT_DROP_CONSTRAINT); - } + mutex_exit(&dict_foreign_err_mutex); - return(DB_SUCCESS); + return(DB_CANNOT_DROP_CONSTRAINT); } /*********************************************************************//** @@ -3178,7 +3189,6 @@ row_truncate_table_for_mysql( dict_table_t* table, /*!< in: table handle */ trx_t* trx) /*!< in: transaction handle */ { - dict_foreign_t* foreign; dberr_t err; mem_heap_t* heap; byte* buf; @@ -3270,18 +3280,17 @@ row_truncate_table_for_mysql( /* Check if the table is referenced by foreign key constraints from some other table (not the table itself) */ - for (foreign = UT_LIST_GET_FIRST(table->referenced_list); - foreign != 0 && foreign->foreign_table == table; - foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { - - /* Do nothing. */ - } + dict_foreign_set::iterator it + = std::find_if(table->referenced_set.begin(), + table->referenced_set.end(), + dict_foreign_different_tables()); if (!srv_read_only_mode - && foreign + && it != table->referenced_set.end() && trx->check_foreigns) { - FILE* ef = dict_foreign_err_file; + FILE* ef = dict_foreign_err_file; + dict_foreign_t* foreign = *it; /* We only allow truncating a referenced table if FOREIGN_KEY_CHECKS is set to 0 */ @@ -3882,42 +3891,45 @@ row_drop_table_for_mysql( /* Check if the table is referenced by foreign key constraints from some other table (not the table itself) */ - foreign = UT_LIST_GET_FIRST(table->referenced_list); + if (!srv_read_only_mode && trx->check_foreigns) { - while (foreign && foreign->foreign_table == table) { -check_next_foreign: - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); - } + for (dict_foreign_set::iterator it + = table->referenced_set.begin(); + it != table->referenced_set.end(); + ++it) { - if (!srv_read_only_mode - && foreign - && trx->check_foreigns - && !(drop_db && dict_tables_have_same_db( - name, foreign->foreign_table_name_lookup))) { - FILE* ef = dict_foreign_err_file; + foreign = *it; - /* We only allow dropping a referenced table if - FOREIGN_KEY_CHECKS is set to 0 */ + const bool ref_ok = drop_db + && dict_tables_have_same_db( + name, + foreign->foreign_table_name_lookup); - err = DB_CANNOT_DROP_CONSTRAINT; + if (foreign->foreign_table != table && !ref_ok) { - mutex_enter(&dict_foreign_err_mutex); - rewind(ef); - ut_print_timestamp(ef); + FILE* ef = dict_foreign_err_file; - fputs(" Cannot drop table ", ef); - ut_print_name(ef, trx, TRUE, name); - fputs("\n" - "because it is referenced by ", ef); - ut_print_name(ef, trx, TRUE, foreign->foreign_table_name); - putc('\n', ef); - mutex_exit(&dict_foreign_err_mutex); + /* We only allow dropping a referenced table + if FOREIGN_KEY_CHECKS is set to 0 */ - goto funct_exit; - } + err = DB_CANNOT_DROP_CONSTRAINT; + + mutex_enter(&dict_foreign_err_mutex); + rewind(ef); + ut_print_timestamp(ef); - if (foreign && trx->check_foreigns) { - goto check_next_foreign; + fputs(" Cannot drop table ", ef); + ut_print_name(ef, trx, TRUE, name); + fputs("\n" + "because it is referenced by ", ef); + ut_print_name(ef, trx, TRUE, + foreign->foreign_table_name); + putc('\n', ef); + mutex_exit(&dict_foreign_err_mutex); + + goto funct_exit; + } + } } /* TODO: could we replace the counter n_foreign_key_checks_running diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc index bdd2a691368..53da8fea77e 100644 --- a/storage/xtradb/row/row0upd.cc +++ b/storage/xtradb/row/row0upd.cc @@ -53,11 +53,12 @@ Created 12/27/1996 Heikki Tuuri #include "pars0sym.h" #include "eval0eval.h" #include "buf0lru.h" +#include <algorithm> + #ifdef WITH_WSREP extern my_bool wsrep_debug; #endif - /* What kind of latch and lock can we assume when the control comes to ------------------------------------------------------------------- an update node? @@ -141,12 +142,10 @@ row_upd_index_is_referenced( trx_t* trx) /*!< in: transaction */ { dict_table_t* table = index->table; - dict_foreign_t* foreign; ibool froze_data_dict = FALSE; ibool is_referenced = FALSE; - if (!UT_LIST_GET_FIRST(table->referenced_list)) { - + if (table->referenced_set.empty()) { return(FALSE); } @@ -155,19 +154,13 @@ row_upd_index_is_referenced( froze_data_dict = TRUE; } - foreign = UT_LIST_GET_FIRST(table->referenced_list); + dict_foreign_set::iterator it + = std::find_if(table->referenced_set.begin(), + table->referenced_set.end(), + dict_foreign_with_index(index)); - while (foreign) { - if (foreign->referenced_index == index) { + is_referenced = (it != table->referenced_set.end()); - is_referenced = TRUE; - goto func_exit; - } - - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); - } - -func_exit: if (froze_data_dict) { row_mysql_unfreeze_data_dictionary(trx); } @@ -188,8 +181,7 @@ wsrep_row_upd_index_is_foreign( ibool froze_data_dict = FALSE; ibool is_referenced = FALSE; - if (!UT_LIST_GET_FIRST(table->foreign_list)) { - + if (table->foreign_set.empty()) { return(FALSE); } @@ -198,17 +190,18 @@ wsrep_row_upd_index_is_foreign( froze_data_dict = TRUE; } - foreign = UT_LIST_GET_FIRST(table->foreign_list); + for (dict_foreign_set::iterator it= table->foreign_set.begin(); + it != table->foreign_set.end(); + ++ it) + { + foreign= *it; - while (foreign) { - if (foreign->foreign_index == index) { - - is_referenced = TRUE; - goto func_exit; - } - - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); - } + if (foreign->foreign_index == index) + { + is_referenced= TRUE; + goto func_exit; + } + } func_exit: if (froze_data_dict) { @@ -249,7 +242,7 @@ row_upd_check_references_constraints( dberr_t err; ibool got_s_lock = FALSE; - if (UT_LIST_GET_FIRST(table->referenced_list) == NULL) { + if (table->referenced_set.empty()) { return(DB_SUCCESS); } @@ -276,9 +269,13 @@ row_upd_check_references_constraints( } run_again: - foreign = UT_LIST_GET_FIRST(table->referenced_list); - while (foreign) { + for (dict_foreign_set::iterator it = table->referenced_set.begin(); + it != table->referenced_set.end(); + ++it) { + + foreign = *it; + /* Note that we may have an update which updates the index record, but does NOT update the first fields which are referenced in a foreign key constraint. Then the update does @@ -331,8 +328,6 @@ run_again: goto func_exit; } } - - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } err = DB_SUCCESS; @@ -369,8 +364,7 @@ wsrep_row_upd_check_foreign_constraints( ibool got_s_lock = FALSE; ibool opened = FALSE; - if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) { - + if (table->foreign_set.empty()) { return(DB_SUCCESS); } @@ -396,9 +390,12 @@ wsrep_row_upd_check_foreign_constraints( row_mysql_freeze_data_dictionary(trx); } - foreign = UT_LIST_GET_FIRST(table->foreign_list); + for (dict_foreign_set::iterator it= table->foreign_set.begin(); + it != table->foreign_set.end(); + ++ it) + { + foreign= *it; - while (foreign) { /* Note that we may have an update which updates the index record, but does NOT update the first fields which are referenced in a foreign key constraint. Then the update does @@ -448,8 +445,6 @@ wsrep_row_upd_check_foreign_constraints( goto func_exit; } } - - foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } err = DB_SUCCESS; |