summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-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
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: */