diff options
Diffstat (limited to 'sql')
-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 |
7 files changed, 96 insertions, 120 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: */ |