summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2021-03-02 00:15:50 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2021-03-02 00:15:50 +0300
commit32147cff6cd6550bf929b260e5c32c12490bfa37 (patch)
tree0bb84566a28c7724252b120ce6d43eed42fab5e1
parent99cb1fe51e3ead519bc7f62cd6bdaafda2c8e2be (diff)
downloadmariadb-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.cc2
-rw-r--r--sql/sql_show.cc8
-rw-r--r--sql/sql_table.cc36
-rw-r--r--sql/sql_truncate.cc8
-rw-r--r--sql/table.cc107
-rw-r--r--sql/table.h8
-rw-r--r--sql/unireg.cc47
-rw-r--r--storage/innobase/handler/ha_innodb.cc118
-rw-r--r--storage/innobase/handler/handler0alter.cc4
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) {