diff options
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 107 |
1 files changed, 44 insertions, 63 deletions
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; } } |