diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-03-02 00:15:50 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-03-02 00:15:50 +0300 |
commit | 32147cff6cd6550bf929b260e5c32c12490bfa37 (patch) | |
tree | 0bb84566a28c7724252b120ce6d43eed42fab5e1 | |
parent | 99cb1fe51e3ead519bc7f62cd6bdaafda2c8e2be (diff) | |
download | mariadb-git-fk_list_span.tar.gz |
FK_list: change foreign_fields/referenced_fields from List to st_::spanfk_list_span
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 36 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 8 | ||||
-rw-r--r-- | sql/table.cc | 107 | ||||
-rw-r--r-- | sql/table.h | 8 | ||||
-rw-r--r-- | sql/unireg.cc | 47 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 118 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 4 |
9 files changed, 154 insertions, 184 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a9911c07710..b98d1aeb623 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2056,7 +2056,7 @@ retry_share: 0 != cmp_table(rk.foreign_table, tbl->table_name)) continue; // NB: rk can be not resolved (see GTS_FK_SHALLOW_HINTS) - if (rk.foreign_fields.elements > 0) + if (rk.foreign_fields.size() > 0) ref_found= true; break; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4de99645eca..2c9610b450e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7257,12 +7257,12 @@ static int get_schema_key_column_usage_record(THD *thd, for (FK_info &fk: show_table->s->foreign_keys) { - List_iterator_fast<Lex_cstring> rf_it(fk.referenced_fields); uint f_idx= 0; - DBUG_ASSERT(fk.foreign_fields.elements == fk.referenced_fields.elements); - for (const Lex_cstring &ff: fk.foreign_fields) + DBUG_ASSERT(fk.foreign_fields.size() == fk.referenced_fields.size()); + for (size_t i= 0; i < fk.foreign_fields.size(); i++) { - const Lex_cstring &rf= *(rf_it++); + const Lex_cstring &ff= fk.foreign_fields[i]; + const Lex_cstring &rf= fk.referenced_fields[i]; f_idx++; restore_record(table, s->default_values); store_key_column_usage(table, db_name, table_name, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 714a9a343f0..b4f647718fa 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2931,6 +2931,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { FK_info *fk= new (thd->mem_root) FK_info(); Foreign_key &fkey= static_cast<Foreign_key &>(*key); + if (!fk || !fk->alloc(thd->mem_root, fkey.columns.elements)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(true); + } + fk->assign(fkey, {db, table_name}); if (!fk->foreign_id.str) { @@ -2999,6 +3005,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (key->foreign) { FK_info *fk= new (thd->mem_root) FK_info(); + if (!fk || !fk->alloc(thd->mem_root, key->columns.elements)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(true); + } fk->assign(*(Foreign_key *) key, {db, table_name}); fk->foreign_id= key_name; if (foreign_keys.push_back(fk)) @@ -5906,7 +5917,7 @@ drop_create_field: { if (fk->update_method != new_fk->update_opt || fk->delete_method != new_fk->delete_opt || - fk->foreign_fields.elements != new_fk->columns.elements) + fk->foreign_fields.size() != new_fk->columns.elements) continue; if (cmp_table(fk->ref_db(), new_fk->ref_db.str ? new_fk->ref_db : table->s->db) || @@ -8685,17 +8696,14 @@ enum fk_column_change_type static enum fk_column_change_type fk_check_column_changes(THD *thd, Alter_info *alter_info, - List<Lex_cstring> &fk_columns, + st_::span<Lex_cstring> &fk_columns, const char **bad_column_name) { - List_iterator_fast<Lex_cstring> column_it(fk_columns); - Lex_cstring *column; - *bad_column_name= NULL; - while ((column= column_it++)) + for(Lex_cstring &column: fk_columns) { - Create_field *new_field= get_field_by_old_name(alter_info, column->str); + Create_field *new_field= get_field_by_old_name(alter_info, column.str); if (new_field) { @@ -8710,7 +8718,7 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info, SE that foreign keys should be updated to use new name of column like it happens in case of in-place algorithm. */ - *bad_column_name= column->str; + *bad_column_name= column.str; return FK_COLUMN_RENAMED; } @@ -8726,7 +8734,7 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info, means values in this column might be changed by ALTER and thus referential integrity might be broken, */ - *bad_column_name= column->str; + *bad_column_name= column.str; return FK_COLUMN_DATA_CHANGE; } } @@ -8742,7 +8750,7 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info, field being dropped since it is easy to break referential integrity in this case. */ - *bad_column_name= column->str; + *bad_column_name= column.str; return FK_COLUMN_DROPPED; } } @@ -11800,10 +11808,10 @@ bool fk_prepare_create_table(THD *thd, Alter_info &alter_info, FK_list &foreign_ for (FK_info &fk: foreign_keys) { - DBUG_ASSERT(fk.foreign_fields.elements == fk.referenced_fields.elements); - List_iterator_fast<Lex_cstring> rf_it(fk.referenced_fields); - for (Lex_cstring &ff: fk.foreign_fields) + DBUG_ASSERT(fk.foreign_fields.size() == fk.referenced_fields.size()); + for (size_t i= 0; i < fk.foreign_fields.size(); i++) { + Lex_cstring &ff= fk.foreign_fields[i]; TABLE_SHARE *ref_share= NULL; if (!fk.self_ref()) { @@ -11815,7 +11823,7 @@ bool fk_prepare_create_table(THD *thd, Alter_info &alter_info, FK_list &foreign_ ref_share= ref_it->second.share; DBUG_ASSERT(ref_share); } - Lex_cstring &rf= *(rf_it++); + Lex_cstring &rf= fk.referenced_fields[i]; Create_field *cf; cl_it.rewind(); while ((cf= cl_it++)) diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 9bf291a4cbb..7e67b7791d5 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -40,15 +40,13 @@ */ static bool fk_info_append_fields(THD *thd, String *str, - List<Lex_cstring> *fields) + st_::span<Lex_cstring> *fields) { bool res= FALSE; - Lex_cstring *field; - List_iterator_fast<Lex_cstring> it(*fields); - while ((field= it++)) + for (const Lex_cstring &field: *fields) { - res|= append_identifier(thd, str, field); + res|= append_identifier(thd, str, &field); res|= str->append(STRING_WITH_LEN(", ")); } diff --git a/sql/table.cc b/sql/table.cc index f635204d93a..01e041638f3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9461,11 +9461,22 @@ public: } }; +bool FK_info::alloc(MEM_ROOT *mem_root, size_t size) +{ + Lex_cstring *buf= (Lex_cstring*)alloc_root(mem_root, + sizeof (Lex_cstring) * size * 2); + if (!buf) + return false; + foreign_fields= {buf, size}; + referenced_fields= {buf + size, size}; -bool FK_info::assign(Foreign_key &src, Table_name table) + return true; +} +void FK_info::assign(Foreign_key &src, Table_name table) { DBUG_ASSERT(src.foreign); DBUG_ASSERT(src.type == Key::MULTIPLE); + DBUG_ASSERT(foreign_fields.data()); foreign_id= src.constraint_name.str ? src.constraint_name : src.name; foreign_db= table.db; @@ -9475,24 +9486,22 @@ bool FK_info::assign(Foreign_key &src, Table_name table) update_method= src.update_opt; delete_method= src.delete_opt; + List_iterator_fast<Key_part_spec> fk_it(src.columns); List_iterator_fast<Key_part_spec> ref_it(src.ref_columns); - - for (const Key_part_spec &kp: src.columns) + for (size_t i = 0; i < src.columns.elements; i++) { - if (foreign_fields.push_back((Lex_cstring *)(&kp.field_name))) - return true; - Key_part_spec *kp2= ref_it++; - if (referenced_fields.push_back((Lex_cstring *)(&kp2->field_name))) - return true; + auto *fkp= fk_it++; + auto *rkp= ref_it++; + foreign_fields[i]= fkp->field_name; + referenced_fields[i]= rkp->field_name; } - return false; } FK_info * FK_info::clone(MEM_ROOT *mem_root) const { FK_info *dst= new (mem_root) FK_info(); - if (!dst) + if (!dst || !dst->alloc(mem_root, foreign_fields.size())) return NULL; if (dst->foreign_id.strdup(mem_root, foreign_id)) @@ -9508,29 +9517,12 @@ FK_info * FK_info::clone(MEM_ROOT *mem_root) const dst->update_method= update_method; dst->delete_method= delete_method; - for (const Lex_cstring &src_f: foreign_fields) - { - Lex_cstring *dst_f= new (mem_root) Lex_cstring(); - if (!dst_f) - return NULL; - if (dst_f->strdup(mem_root, src_f)) - return NULL; - if (dst->foreign_fields.push_back(dst_f, mem_root)) - return NULL; - } + DBUG_ASSERT(foreign_fields.size() == referenced_fields.size()); - for (const Lex_cstring &src_f: referenced_fields) - { - Lex_cstring *dst_f= new (mem_root) Lex_cstring(); - if (!dst_f) - return NULL; - if (dst_f->strdup(mem_root, src_f)) - return NULL; - if (dst->referenced_fields.push_back(dst_f, mem_root)) - return NULL; - } + size_t bufsz= sizeof(Lex_cstring) * foreign_fields.size(); + memcpy(dst->foreign_fields.data(), foreign_fields.data(), bufsz); + memcpy(dst->referenced_fields.data(), referenced_fields.data(), bufsz); - DBUG_ASSERT(foreign_fields.elements == referenced_fields.elements); return dst; } @@ -9655,24 +9647,18 @@ bool TABLE_SHARE::fk_check_consistency(THD *thd) !::cmp_table(fk->referenced_table, table_name)) { found_table= true; - List_iterator_fast<Lex_cstring> rk_fld_it(rk.referenced_fields); - List_iterator_fast<Lex_cstring> fk_fld_it(fk->referenced_fields); - List_iterator_fast<Lex_cstring> rk_fld2_it(rk.foreign_fields); - List_iterator_fast<Lex_cstring> fk_fld2_it(fk->foreign_fields); - Lex_cstring *fk_fld; - while ((fk_fld= fk_fld_it++)) + if (rk.referenced_fields.size() != fk->foreign_fields.size()) + break; + DBUG_ASSERT(fk->foreign_fields.size() == fk->referenced_fields.size()); + DBUG_ASSERT(rk.foreign_fields.size() == rk.referenced_fields.size()); + + bool match= true; + for (uint i = 0; match && i < fk->referenced_fields.size(); i++) { - Lex_cstring *rk_fld= rk_fld_it++; - if (!rk_fld || cmp(fk_fld, rk_fld)) - break; - fk_fld= fk_fld2_it++; - DBUG_ASSERT(fk_fld); - rk_fld= rk_fld2_it++; - DBUG_ASSERT(rk_fld); - if (cmp(fk_fld, rk_fld)) - break; + match= cmp(fk->referenced_fields[i], rk.referenced_fields[i]) == 0 && + cmp(fk->foreign_fields[i], rk.foreign_fields[i]) == 0; } - if (!fk_fld) + if (!match) break; } } @@ -9747,24 +9733,19 @@ bool TABLE_SHARE::fk_check_consistency(THD *thd) !::cmp_table(rk->foreign_table, table_name)) { found_table= true; - List_iterator_fast<Lex_cstring> rk_fld_it(rk->referenced_fields); - List_iterator_fast<Lex_cstring> fk_fld_it(fk.referenced_fields); - List_iterator_fast<Lex_cstring> rk_fld2_it(rk->foreign_fields); - List_iterator_fast<Lex_cstring> fk_fld2_it(fk.foreign_fields); - Lex_cstring *fk_fld; - while ((fk_fld= fk_fld_it++)) + + if (rk->referenced_fields.size() != fk.foreign_fields.size()) + break; + DBUG_ASSERT(fk.foreign_fields.size() == fk.referenced_fields.size()); + DBUG_ASSERT(rk->foreign_fields.size() == rk->referenced_fields.size()); + + bool match= true; + for (uint i = 0; match && i < fk.referenced_fields.size(); i++) { - Lex_cstring *rk_fld= rk_fld_it++; - if (!rk_fld || cmp(fk_fld, rk_fld)) - break; - fk_fld= fk_fld2_it++; - DBUG_ASSERT(fk_fld); - rk_fld= rk_fld2_it++; - DBUG_ASSERT(rk_fld); - if (cmp(fk_fld, rk_fld)) - break; + match = cmp(fk.referenced_fields[i], rk->referenced_fields[i]) == 0 && + cmp(fk.foreign_fields[i], rk->foreign_fields[i]) == 0; } - if (!fk_fld) + if (!match) break; } } diff --git a/sql/table.h b/sql/table.h index b708ff11b4a..e72acf60a33 100644 --- a/sql/table.h +++ b/sql/table.h @@ -22,6 +22,7 @@ #include "datadict.h" #include "sql_string.h" /* String */ #include "lex_string.h" +#include "span.h" #ifndef MYSQL_CLIENT @@ -1864,8 +1865,8 @@ public: Lex_cstring referenced_table; enum_fk_option update_method; enum_fk_option delete_method; - List<Lex_cstring> foreign_fields; - List<Lex_cstring> referenced_fields; + st_::span<Lex_cstring> foreign_fields; + st_::span<Lex_cstring> referenced_fields; public: FK_info() : @@ -1887,7 +1888,8 @@ public: // TODO: keep NULL in referenced_table for self-refs return 0 == cmp_table(referenced_table, foreign_table); } - bool assign(Foreign_key &fk, Table_name table); + bool alloc(MEM_ROOT *mem_root, size_t size); + void assign(Foreign_key &fk, Table_name table); FK_info * clone(MEM_ROOT *mem_root) const; Table_name for_table(MEM_ROOT *mem_root, bool copy= false) const; Table_name ref_table(MEM_ROOT *mem_root, bool copy= false) const; diff --git a/sql/unireg.cc b/sql/unireg.cc index 61122177002..464cc9d8293 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1241,14 +1241,12 @@ ulonglong Foreign_key_io::fk_size(FK_info &fk) } store_size+= net_length_size(fk.update_method); store_size+= net_length_size(fk.delete_method); - store_size+= net_length_size(fk.foreign_fields.elements); - DBUG_ASSERT(fk.foreign_fields.elements == fk.referenced_fields.elements); - List_iterator_fast<Lex_cstring> ref_it(fk.referenced_fields); - for (Lex_cstring &fcol: fk.foreign_fields) + store_size+= net_length_size(fk.foreign_fields.size()); + DBUG_ASSERT(fk.foreign_fields.size() == fk.referenced_fields.size()); + for (size_t i= 0; i < fk.foreign_fields.size(); i++) { - store_size+= string_size(fcol); - Lex_cstring *ref_col= ref_it++; - store_size+= string_size(*ref_col); + store_size+= string_size(fk.foreign_fields[i]); + store_size+= string_size(fk.referenced_fields[i]); } return store_size; } @@ -1283,14 +1281,12 @@ void Foreign_key_io::store_fk(FK_info &fk, uchar *&pos) } pos= store_length(pos, fk.update_method); pos= store_length(pos, fk.delete_method); - pos= store_length(pos, fk.foreign_fields.elements); - DBUG_ASSERT(fk.foreign_fields.elements == fk.referenced_fields.elements); - List_iterator_fast<Lex_cstring> ref_it(fk.referenced_fields); - for (Lex_cstring &fcol: fk.foreign_fields) + pos= store_length(pos, fk.foreign_fields.size()); + DBUG_ASSERT(fk.foreign_fields.size() == fk.referenced_fields.size()); + for (size_t i= 0; i < fk.foreign_fields.size(); i++) { - pos= store_string(pos, fcol); - Lex_cstring *ref_col= ref_it++; - pos= store_string(pos, *ref_col); + pos= store_string(pos, fk.foreign_fields[i]); + pos= store_string(pos, fk.referenced_fields[i]); } DBUG_ASSERT(pos - old_pos == (long int)fk_size(fk)); } @@ -1419,25 +1415,16 @@ bool Foreign_key_io::parse(THD *thd, TABLE_SHARE *s, LEX_CUSTRING& image) size_t col_count; if (read_length(col_count, p)) return true; + if (!dst->alloc(&s->mem_root, col_count)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + return true; + } for (uint j= 0; j < col_count; ++j) { - Lex_cstring *field_name= new (&s->mem_root) Lex_cstring; - if (!field_name || - dst->foreign_fields.push_back(field_name, &s->mem_root)) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + if (read_string(dst->foreign_fields[j], &s->mem_root, p)) return true; - } - if (read_string(*field_name, &s->mem_root, p)) - return true; - field_name= new (&s->mem_root) Lex_cstring; - if (!field_name || - dst->referenced_fields.push_back(field_name, &s->mem_root)) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - return true; - } - if (read_string(*field_name, &s->mem_root, p)) + if (read_string(dst->referenced_fields[j], &s->mem_root, p)) return true; } /* If it is self-reference we also push to referenced_keys: */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 857ec9fc821..f61e22fd9ba 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11748,18 +11748,20 @@ public: return; } *(ptr++) = '('; - List_iterator_fast<Lex_cstring> it(key->foreign_fields); - while (Lex_cstring* field_name = it++) { + auto sz = key->foreign_fields.size(); + for (uint i = 0; i < sz; i++) { + Lex_cstring *field_name = &key->foreign_fields[i]; + bool last = i == sz - 1; /* 3 is etc continuation ("..."); 2 is comma separator (", ") in case of next exists; 1 is terminating ')' */ if (MAX_TEXT - (size_t)(ptr - buf) - >= (it.peek() ? 3 + 2 + 1 : 3 + 1) + >= (last ? 3 + 2 + 1 : 3 + 1) + field_name->length) { memcpy(ptr, field_name->str, field_name->length); ptr += field_name->length; - if (it.peek()) { + if (last) { *(ptr++) = ','; *(ptr++) = ' '; } @@ -11876,7 +11878,6 @@ create_table_info_t::create_foreign_keys() continue; } - LEX_CSTRING* col; bool success; dict_foreign_t* foreign = dict_mem_foreign_create(); @@ -11924,11 +11925,10 @@ create_table_info_t::create_foreign_keys() } - List_iterator_fast<Lex_cstring> col_it(fk->foreign_fields); unsigned i = 0, j = 0; - while ((col = col_it++)) { + for (Lex_cstring &col: fk->foreign_fields) { column_names[i] = mem_heap_strdupl( - foreign->heap, col->str, col->length); + foreign->heap, col.str, col.length); success = find_col(table, column_names + i); if (!success) { key_text k(fk); @@ -12029,10 +12029,9 @@ create_table_info_t::create_foreign_keys() return (DB_CANNOT_ADD_CONSTRAINT); } - col_it.init(fk->referenced_fields); - while ((col = col_it++)) { + for (Lex_cstring &col: fk->referenced_fields) { ref_column_names[j] = mem_heap_strdupl( - foreign->heap, col->str, col->length); + foreign->heap, col.str, col.length); if (foreign->referenced_table) { success = find_col(foreign->referenced_table, ref_column_names + j); @@ -20723,10 +20722,12 @@ struct fk_legacy_data { TABLE_SHARE* s; char ref_name[MAX_FULL_NAME_LEN + 1]; FK_info* fk; + uint col_num; dberr_t err; FK_list foreign_keys; fk_legacy_data(trx_t* _t, dict_table_t* _tab, TABLE_SHARE* _s) - : trx(_t), table(_tab), s(_s), fk(NULL), err(DB_SUCCESS){}; + : trx(_t), table(_tab), s(_s), fk(NULL), col_num(0), + err(DB_SUCCESS){}; }; static ibool @@ -20857,6 +20858,18 @@ fk_upgrade_create_fk( d.err = DB_OUT_OF_MEMORY; return 0; } + + // Get column count + exp = que_node_get_next(exp); + fld = que_node_get_val(exp); + + ut_a(fld); + ib_uint64_t col_num = row_parse_int( + static_cast<const byte*>(fld->data), + fld->len, + fld->type.mtype, + fld->type.prtype & DATA_UNSIGNED); + d.fk->alloc(&d.s->mem_root, col_num); d.err = DB_LEGACY_FK; return 1; } @@ -20877,39 +20890,24 @@ fk_upgrade_add_col( // Get FOR_COL_NAME dfield_t* fld = que_node_get_val(exp); ut_a(fld); - Lex_cstring* dst_f = new (&d.s->mem_root) Lex_cstring(); - if (!dst_f) { - d.err = DB_OUT_OF_MEMORY; - return 0; - } - dst_f->strdup(&d.s->mem_root, {(char*)fld->data, fld->len}); - if (!dst_f->str) { - d.err = DB_OUT_OF_MEMORY; - return 0; - } - if (d.fk->foreign_fields.push_back(dst_f, &d.s->mem_root)) { - d.err = DB_OUT_OF_MEMORY; - return 0; - } + d.fk->foreign_fields[d.col_num] = { + strmake_root(&d.s->mem_root, (char *)fld->data, fld->len), + fld->len + }; // Get REF_COL_NAME exp = que_node_get_next(exp); fld = que_node_get_val(exp); ut_a(exp); ut_a(fld); - dst_f = new (&d.s->mem_root) Lex_cstring(); - if (!dst_f) { - d.err = DB_OUT_OF_MEMORY; - return 0; - } - dst_f->strdup(&d.s->mem_root, {(char*)fld->data, fld->len}); - if (!dst_f->str) { - d.err = DB_OUT_OF_MEMORY; - return 0; - } + d.fk->referenced_fields[d.col_num] = { + strmake_root(&d.s->mem_root, (char *)fld->data, fld->len), + fld->len + }; - if (d.fk->referenced_fields.push_back(dst_f, &d.s->mem_root)) { + if (!d.fk->foreign_fields[d.col_num].str || + !d.fk->referenced_fields[d.col_num].str) { d.err = DB_OUT_OF_MEMORY; return 0; } @@ -20930,22 +20928,20 @@ fk_upgrade_push_fk( } // Check indexes on ref and on foreign FK_info& fk = *d.fk; - ut_ad(fk.foreign_fields.elements < MAX_NUM_FK_COLUMNS); - ut_ad(fk.foreign_fields.elements == fk.referenced_fields.elements); - uint i = 0; + ut_ad(fk.foreign_fields.size() < MAX_NUM_FK_COLUMNS); + ut_ad(fk.foreign_fields.size() == fk.referenced_fields.size()); char norm_name[FN_REFLEN]; const char* column_names[MAX_NUM_FK_COLUMNS]; const char* ref_column_names[MAX_NUM_FK_COLUMNS]; dict_index_t* index; - List_iterator_fast<Lex_cstring> it(fk.referenced_fields); - for (Lex_cstring& col : fk.foreign_fields) { - column_names[i] = col.str; - Lex_cstring* rcol = it++; - ref_column_names[i++] = rcol->str; + for (uint i = 0; i < fk.foreign_fields.size(); i++) { + column_names[i] = fk.foreign_fields[i].str; + ref_column_names[i] = fk.referenced_fields[i].str; + i++; } dict_sys.mutex_lock(); index = dict_foreign_find_index(d.table, NULL, column_names, - fk.foreign_fields.elements, NULL, true, + fk.foreign_fields.size(), NULL, true, false); if (!index) { dict_sys.mutex_unlock(); @@ -20971,7 +20967,7 @@ fk_upgrade_push_fk( return 0; } index = dict_foreign_find_index(ref_table, NULL, ref_column_names, - fk.foreign_fields.elements, NULL, true, + fk.foreign_fields.size(), NULL, true, false); dict_table_close(ref_table, true, false); dict_sys.mutex_unlock(); @@ -21088,7 +21084,7 @@ fk_upgrade_legacy_storage(dict_table_t* table, trx_t* trx, THD* thd, "DECLARE FUNCTION fk_upgrade_push_fk;\n" "DECLARE CURSOR c IS" - " SELECT ID, REF_NAME FROM SYS_FOREIGN" + " SELECT ID, REF_NAME, N_COLS FROM SYS_FOREIGN" " WHERE FOR_NAME = :for_name;" "DECLARE CURSOR c2 IS" @@ -21314,25 +21310,23 @@ dict_load_foreigns(THD* thd, dict_table_t* table, TABLE_SHARE* share, } // NB: see innobase_get_foreign_key_info() for index checks - ut_ad(fk.foreign_fields.elements - == fk.referenced_fields.elements); - ut_ad(fk.foreign_fields.elements <= MAX_NUM_FK_COLUMNS); - DBUG_ASSERT(fk.foreign_fields.elements <= 0x3ff); - foreign->n_fields = fk.foreign_fields.elements & 0x3ff; - - List_iterator_fast<Lex_cstring> ref_it(fk.referenced_fields); - uint i = 0; - for (Lex_cstring& fcol : fk.foreign_fields) { - Lex_cstring& ref_col = *(ref_it++); - column_names[i] = mem_heap_strdupl( - foreign->heap, LEX_STRING_WITH_LEN(fcol)); + ut_ad(fk.foreign_fields.size() + == fk.referenced_fields.size()); + ut_ad(fk.foreign_fields.size() <= MAX_NUM_FK_COLUMNS); + DBUG_ASSERT(fk.foreign_fields.size() <= 0x3ff); + foreign->n_fields = fk.foreign_fields.size() & 0x3ff; + + for (uint i = 0; i < fk.foreign_fields.size(); i++) { + column_names[i] = mem_heap_strdupl( + foreign->heap, + LEX_STRING_WITH_LEN(fk.foreign_fields[i])); if (!column_names[i]) return DB_OUT_OF_MEMORY; ref_column_names[i] = mem_heap_strdupl( - foreign->heap, LEX_STRING_WITH_LEN(ref_col)); + foreign->heap, + LEX_STRING_WITH_LEN(fk.referenced_fields[i])); if (!ref_column_names[i]) return DB_OUT_OF_MEMORY; - ++i; } size_t dblen = table->name.dblen() + 1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 7bf3ffbd75a..75350f4a69c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2953,7 +2953,7 @@ innobase_get_foreign_key_info( ulint referenced_num_col = 0; bool correct_option; - if (fk_key.foreign_fields.elements > 0) { + if (fk_key.foreign_fields.size() > 0) { ulint i = 0; /* Get all the foreign key column info for the @@ -3019,7 +3019,7 @@ innobase_get_foreign_key_info( goto err_exit; } - if (fk_key.referenced_fields.elements > 0) { + if (fk_key.referenced_fields.size() > 0) { ulint i = 0; for (Lex_cstring &column: fk_key.referenced_fields) { |