mirror of
https://github.com/MariaDB/server.git
synced 2026-05-18 21:07:24 +02:00
FOREIGN_KEY_INFO: Store Lex_* strings without extra pointer indirection.
Made as a part of MDEV-34309
This commit is contained in:
parent
12ef85c4ac
commit
aa3000fe58
11 changed files with 142 additions and 160 deletions
|
|
@ -20,6 +20,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include "mysql/service_thd_alloc.h"
|
||||
|
||||
namespace st_
|
||||
{
|
||||
|
|
@ -153,6 +154,12 @@ public:
|
|||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
|
||||
void alloc(const THD *thd, size_t elements)
|
||||
{
|
||||
data_= (element_type*) thd_alloc(thd, sizeof (element_type) * elements);
|
||||
size_= elements;
|
||||
}
|
||||
|
||||
private:
|
||||
pointer data_;
|
||||
size_type size_;
|
||||
|
|
|
|||
|
|
@ -130,6 +130,22 @@ class Lex_cstring : public LEX_CSTRING
|
|||
DBUG_ASSERT(rhs.str);
|
||||
return length >= rhs.length && !memcmp(str, rhs.str, rhs.length);
|
||||
}
|
||||
|
||||
void set_dup(const THD *thd, const char *ptr, size_t len)
|
||||
{
|
||||
str= thd_strmake(thd, ptr, len);
|
||||
length = len;
|
||||
}
|
||||
|
||||
void set_dup(const THD *thd, const char *ptr)
|
||||
{
|
||||
set_dup(thd, ptr, strlen(ptr));
|
||||
}
|
||||
|
||||
void set_dup(const THD *thd, const LEX_CSTRING &other)
|
||||
{
|
||||
set_dup(thd, other.str, other.length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -403,8 +403,8 @@ public:
|
|||
void set_fk_error_if_delete_row(FOREIGN_KEY_INFO *fk)
|
||||
{
|
||||
fk_error_if_delete_row= true;
|
||||
fk_error_id= fk->foreign_id->str;
|
||||
fk_error_table= fk->foreign_table->str;
|
||||
fk_error_id= fk->foreign_id.str;
|
||||
fk_error_table= fk->foreign_table.str;
|
||||
}
|
||||
|
||||
void report_implicit_default_value_error(THD *thd, const TABLE_SHARE *) const;
|
||||
|
|
|
|||
|
|
@ -5072,11 +5072,11 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
|
|||
lock_type= TL_READ;
|
||||
|
||||
if (table_already_fk_prelocked(prelocking_ctx->query_tables,
|
||||
fk->foreign_db, fk->foreign_table, lock_type))
|
||||
&fk->foreign_db, &fk->foreign_table, lock_type))
|
||||
continue;
|
||||
|
||||
TABLE_LIST *tl= thd->alloc<TABLE_LIST>(1);
|
||||
tl->init_one_table_for_prelocking(fk->foreign_db, fk->foreign_table,
|
||||
tl->init_one_table_for_prelocking(&fk->foreign_db, &fk->foreign_table,
|
||||
NULL, lock_type, TABLE_LIST::PRELOCK_FK, table_list->belong_to_view,
|
||||
op, &prelocking_ctx->query_tables_last, table_list->for_insert_data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7691,8 +7691,8 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
|
|||
while ((f_key_info=it++))
|
||||
{
|
||||
if (store_constraints(thd, table, db_name, table_name,
|
||||
f_key_info->foreign_id->str,
|
||||
strlen(f_key_info->foreign_id->str),
|
||||
f_key_info->foreign_id.str,
|
||||
f_key_info->foreign_id.length,
|
||||
STRING_WITH_LEN("FOREIGN KEY")))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
|
@ -7879,50 +7879,47 @@ get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables,
|
|||
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
|
||||
while ((f_key_info= fkey_it++))
|
||||
{
|
||||
LEX_CSTRING *f_info;
|
||||
LEX_CSTRING *r_info;
|
||||
List_iterator_fast<LEX_CSTRING> it(f_key_info->foreign_fields),
|
||||
it1(f_key_info->referenced_fields);
|
||||
uint f_idx= 0;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (need_column_checks)
|
||||
{
|
||||
while ((r_info= it1++))
|
||||
uint r_idx= 0;
|
||||
for (const Lex_ident_column &r_info: f_key_info->referenced_fields)
|
||||
{
|
||||
auto access= get_column_grant(thd, &tables->grant, db_name->str,
|
||||
table_name->str,
|
||||
Lex_ident_column(*r_info));
|
||||
table_name->str, r_info);
|
||||
|
||||
if (!access)
|
||||
break;
|
||||
r_idx++;
|
||||
}
|
||||
if (!it1.at_end())
|
||||
if (r_idx < f_key_info->referenced_fields.size())
|
||||
continue;
|
||||
it1.rewind();
|
||||
}
|
||||
#endif
|
||||
while ((f_info= it++))
|
||||
for (uint r_idx= 0; r_idx < f_key_info->foreign_fields.size(); r_idx++)
|
||||
{
|
||||
r_info= it1++;
|
||||
const Lex_ident_column &f_info= f_key_info->foreign_fields[r_idx];
|
||||
const Lex_ident_column &r_info= f_key_info->referenced_fields[r_idx];
|
||||
f_idx++;
|
||||
restore_record(table, s->default_values);
|
||||
store_key_column_usage(table, db_name, table_name,
|
||||
f_key_info->foreign_id->str,
|
||||
f_key_info->foreign_id->length,
|
||||
f_info->str, f_info->length,
|
||||
f_key_info->foreign_id.str,
|
||||
f_key_info->foreign_id.length,
|
||||
f_info.str, f_info.length,
|
||||
(longlong) f_idx);
|
||||
table->field[8]->store((longlong) f_idx, TRUE);
|
||||
table->field[8]->set_notnull();
|
||||
table->field[9]->store(f_key_info->referenced_db->str,
|
||||
f_key_info->referenced_db->length,
|
||||
table->field[9]->store(f_key_info->referenced_db.str,
|
||||
f_key_info->referenced_db.length,
|
||||
system_charset_info);
|
||||
table->field[9]->set_notnull();
|
||||
table->field[10]->store(f_key_info->referenced_table->str,
|
||||
f_key_info->referenced_table->length,
|
||||
table->field[10]->store(f_key_info->referenced_table.str,
|
||||
f_key_info->referenced_table.length,
|
||||
system_charset_info);
|
||||
table->field[10]->set_notnull();
|
||||
table->field[11]->store(r_info->str, r_info->length,
|
||||
table->field[11]->store(r_info.str, r_info.length,
|
||||
system_charset_info);
|
||||
table->field[11]->set_notnull();
|
||||
if (schema_table_store_record(thd, table))
|
||||
|
|
@ -8734,11 +8731,11 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
|
|||
table->field[0]->store(STRING_WITH_LEN("def"), cs);
|
||||
table->field[1]->store(db_name->str, db_name->length, cs);
|
||||
table->field[9]->store(table_name->str, table_name->length, cs);
|
||||
table->field[2]->store(f_key_info->foreign_id->str,
|
||||
f_key_info->foreign_id->length, cs);
|
||||
table->field[2]->store(f_key_info->foreign_id.str,
|
||||
f_key_info->foreign_id.length, cs);
|
||||
table->field[3]->store(STRING_WITH_LEN("def"), cs);
|
||||
table->field[4]->store(f_key_info->referenced_db->str,
|
||||
f_key_info->referenced_db->length, cs);
|
||||
table->field[4]->store(f_key_info->referenced_db.str,
|
||||
f_key_info->referenced_db.length, cs);
|
||||
bool show_ref_table= true;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* need any non-SELECT privilege on the table or any of its columns */
|
||||
|
|
@ -8746,8 +8743,8 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
|
|||
{
|
||||
TABLE_LIST table_acl_check;
|
||||
bzero((char*) &table_acl_check, sizeof(table_acl_check));
|
||||
table_acl_check.db= Lex_ident_db(*f_key_info->referenced_db);
|
||||
table_acl_check.table_name= Lex_ident_table(*f_key_info->referenced_table);
|
||||
table_acl_check.db= f_key_info->referenced_db;
|
||||
table_acl_check.table_name= f_key_info->referenced_table;
|
||||
table_acl_check.grant.privilege= thd->col_access;
|
||||
check_grant(thd, SELECT_ACL, &table_acl_check, 0, 1, 1);
|
||||
|
||||
|
|
@ -8758,13 +8755,13 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
|
|||
if (show_ref_table)
|
||||
{
|
||||
table->field[10]->set_notnull();
|
||||
table->field[10]->store(f_key_info->referenced_table->str,
|
||||
f_key_info->referenced_table->length, cs);
|
||||
table->field[10]->store(f_key_info->referenced_table.str,
|
||||
f_key_info->referenced_table.length, cs);
|
||||
}
|
||||
if (f_key_info->referenced_key_name)
|
||||
{
|
||||
table->field[5]->store(f_key_info->referenced_key_name->str,
|
||||
f_key_info->referenced_key_name->length, cs);
|
||||
table->field[5]->store(f_key_info->referenced_key_name.str,
|
||||
f_key_info->referenced_key_name.length, cs);
|
||||
table->field[5]->set_notnull();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -6250,7 +6250,7 @@ drop_create_field:
|
|||
List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
|
||||
while ((f_key= fk_key_it++))
|
||||
{
|
||||
if (Lex_ident_column(*f_key->foreign_id).streq(drop->name))
|
||||
if (f_key->foreign_id.streq(drop->name))
|
||||
{
|
||||
remove_drop= FALSE;
|
||||
break;
|
||||
|
|
@ -6403,7 +6403,7 @@ drop_create_field:
|
|||
List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
|
||||
while ((f_key= fk_key_it++))
|
||||
{
|
||||
if (Lex_ident_column(*f_key->foreign_id).streq(keyname))
|
||||
if (f_key->foreign_id.streq(keyname))
|
||||
goto remove_key;
|
||||
}
|
||||
}
|
||||
|
|
@ -8437,9 +8437,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
|
||||
restore_record(table, s->default_values); // Empty record for DEFAULT
|
||||
|
||||
if ((create_info->fields_option_struct=
|
||||
if ((create_info->fields_option_struct=
|
||||
thd->calloc<ha_field_option_struct*>(table->s->fields)) == NULL ||
|
||||
(create_info->indexes_option_struct=
|
||||
(create_info->indexes_option_struct=
|
||||
thd->calloc<ha_index_option_struct*>(table->s->total_keys)) == NULL)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
|
|
@ -9152,7 +9152,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
Alter_drop *drop;
|
||||
for(drop_it.rewind(); (drop=drop_it++); )
|
||||
if (drop->type == Alter_drop::FOREIGN_KEY &&
|
||||
drop->name.streq(*fk.foreign_id))
|
||||
drop->name.streq(fk.foreign_id))
|
||||
break;
|
||||
if (drop)
|
||||
continue;
|
||||
|
|
@ -9162,8 +9162,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
for (LEX_CSTRING &c : fk.referenced_fields)
|
||||
ref_cols.push_back(new (root) Key_part_spec(&c, 0));
|
||||
auto key= new (root)
|
||||
Foreign_key(fk.foreign_id, &cols, fk.foreign_id, fk.referenced_db,
|
||||
fk.referenced_table, &ref_cols, fk.delete_method, fk.update_method,
|
||||
Foreign_key(&fk.foreign_id, &cols, &fk.foreign_id, &fk.referenced_db,
|
||||
&fk.referenced_table, &ref_cols, fk.delete_method, fk.update_method,
|
||||
Foreign_key::FK_MATCH_UNDEF, DDL_options());
|
||||
key->old= true;
|
||||
new_key_list.push_back(key, root);
|
||||
|
|
@ -9304,7 +9304,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
if (!check->name.length || check->automatic_name)
|
||||
continue;
|
||||
|
||||
if (check->name.streq(*f_key->foreign_id))
|
||||
if (check->name.streq(f_key->foreign_id))
|
||||
{
|
||||
my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str);
|
||||
goto err;
|
||||
|
|
@ -9347,7 +9347,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||
List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
|
||||
while (FOREIGN_KEY_INFO *f_key= fk_key_it++)
|
||||
{
|
||||
if (Lex_ident_column(*f_key->foreign_id).streq(drop->name))
|
||||
if (Lex_ident_column(f_key->foreign_id).streq(drop->name))
|
||||
goto fk_found;
|
||||
}
|
||||
goto fk_not_found;
|
||||
|
|
@ -9479,20 +9479,19 @@ fk_check_column_changes(THD *thd, const TABLE *table,
|
|||
const char **bad_column_name,
|
||||
bool referenced=false)
|
||||
{
|
||||
List<LEX_CSTRING> &fk_columns= referenced
|
||||
? fk->referenced_fields
|
||||
: fk->foreign_fields;
|
||||
List_iterator_fast<LEX_CSTRING> column_it(fk_columns);
|
||||
LEX_CSTRING *column;
|
||||
auto &fk_columns= referenced ? fk->referenced_fields
|
||||
: fk->foreign_fields;
|
||||
int n_col= 0;
|
||||
|
||||
*bad_column_name= NULL;
|
||||
enum fk_column_change_type result= FK_COLUMN_NO_CHANGE;
|
||||
const char *last_column_name;
|
||||
|
||||
while ((column= column_it++))
|
||||
for(const Lex_ident_column &column: fk_columns)
|
||||
{
|
||||
Create_field *new_field= get_field_by_old_name(alter_info, *column);
|
||||
Create_field *new_field= get_field_by_old_name(alter_info, column);
|
||||
|
||||
last_column_name= column.str;
|
||||
if (new_field)
|
||||
{
|
||||
Field *old_field= new_field->field;
|
||||
|
|
@ -9588,7 +9587,7 @@ fk_check_column_changes(THD *thd, const TABLE *table,
|
|||
}
|
||||
return FK_COLUMN_NO_CHANGE;
|
||||
func_exit:
|
||||
*bad_column_name= column->str;
|
||||
*bad_column_name= last_column_name;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -9655,9 +9654,9 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
l_c_t_n > 0 modes case-insensitive comparison is used.
|
||||
*/
|
||||
if ((drop->type == Alter_drop::FOREIGN_KEY) &&
|
||||
drop->name.streq(*f_key->foreign_id) &&
|
||||
table->s->db.streq(*f_key->foreign_db) &&
|
||||
table->s->table_name.streq(*f_key->foreign_table))
|
||||
drop->name.streq(f_key->foreign_id) &&
|
||||
table->s->db.streq(f_key->foreign_db) &&
|
||||
table->s->table_name.streq(f_key->foreign_table))
|
||||
fk_parent_key_it.remove();
|
||||
}
|
||||
}
|
||||
|
|
@ -9689,10 +9688,10 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
case FK_COLUMN_DATA_CHANGE:
|
||||
{
|
||||
char buff[NAME_LEN*2+2];
|
||||
strxnmov(buff, sizeof(buff)-1, f_key->foreign_db->str, ".",
|
||||
f_key->foreign_table->str, NullS);
|
||||
strxnmov(buff, sizeof(buff)-1, f_key->foreign_db.str, ".",
|
||||
f_key->foreign_table.str, NullS);
|
||||
my_error(ER_FK_COLUMN_CANNOT_CHANGE_CHILD, MYF(0), bad_column_name,
|
||||
f_key->foreign_id->str, buff);
|
||||
f_key->foreign_id.str, buff);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
case FK_COLUMN_RENAMED:
|
||||
|
|
@ -9704,13 +9703,13 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
case FK_COLUMN_DROPPED:
|
||||
{
|
||||
StringBuffer<NAME_LEN*2+2> buff(system_charset_info);
|
||||
LEX_CSTRING *db= f_key->foreign_db, *tbl= f_key->foreign_table;
|
||||
const LEX_CSTRING *db= &f_key->foreign_db, *tbl= &f_key->foreign_table;
|
||||
|
||||
append_identifier(thd, &buff, db);
|
||||
buff.append('.');
|
||||
append_identifier(thd, &buff, tbl);
|
||||
my_error(ER_FK_COLUMN_CANNOT_DROP_CHILD, MYF(0), bad_column_name,
|
||||
f_key->foreign_id->str, buff.c_ptr());
|
||||
f_key->foreign_id.str, buff.c_ptr());
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
/* FK_COLUMN_NOT_NULL error happens only when changing
|
||||
|
|
@ -9742,7 +9741,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
{
|
||||
/* Names of foreign keys in InnoDB are case-insensitive. */
|
||||
if ((drop->type == Alter_drop::FOREIGN_KEY) &&
|
||||
(Lex_ident_column(*f_key->foreign_id).streq(drop->name)))
|
||||
(Lex_ident_column(f_key->foreign_id).streq(drop->name)))
|
||||
fk_key_it.remove();
|
||||
}
|
||||
}
|
||||
|
|
@ -9763,7 +9762,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
break;
|
||||
case FK_COLUMN_DATA_CHANGE:
|
||||
my_error(ER_FK_COLUMN_CANNOT_CHANGE, MYF(0), bad_column_name,
|
||||
f_key->foreign_id->str);
|
||||
f_key->foreign_id.str);
|
||||
DBUG_RETURN(true);
|
||||
case FK_COLUMN_RENAMED:
|
||||
my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
|
||||
|
|
@ -9773,11 +9772,11 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
|
|||
DBUG_RETURN(true);
|
||||
case FK_COLUMN_DROPPED:
|
||||
my_error(ER_FK_COLUMN_CANNOT_DROP, MYF(0), bad_column_name,
|
||||
f_key->foreign_id->str);
|
||||
f_key->foreign_id.str);
|
||||
DBUG_RETURN(true);
|
||||
case FK_COLUMN_NOT_NULL:
|
||||
my_error(ER_FK_COLUMN_NOT_NULL, MYF(0), bad_column_name,
|
||||
f_key->foreign_id->str);
|
||||
f_key->foreign_id.str);
|
||||
DBUG_RETURN(true);
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
|
|
@ -10932,7 +10931,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
|||
|
||||
while ((f_key= fk_key_it++))
|
||||
{
|
||||
if (Lex_ident_column(*f_key->foreign_id).streq(drop->name))
|
||||
if (f_key->foreign_id.streq(drop->name))
|
||||
{
|
||||
drop->type= Alter_drop::FOREIGN_KEY;
|
||||
alter_info->flags|= ALTER_DROP_FOREIGN_KEY;
|
||||
|
|
|
|||
|
|
@ -40,15 +40,13 @@
|
|||
*/
|
||||
|
||||
static bool fk_info_append_fields(THD *thd, String *str,
|
||||
List<LEX_CSTRING> *fields)
|
||||
const st_::span<Lex_ident_column> &fields)
|
||||
{
|
||||
bool res= FALSE;
|
||||
LEX_CSTRING *field;
|
||||
List_iterator_fast<LEX_CSTRING> it(*fields);
|
||||
|
||||
while ((field= it++))
|
||||
for (Lex_ident_column &field: fields)
|
||||
{
|
||||
res|= append_identifier(thd, str, field);
|
||||
res|= append_identifier(thd, str, &field);
|
||||
res|= str->append(STRING_WITH_LEN(", "));
|
||||
}
|
||||
|
||||
|
|
@ -80,19 +78,19 @@ static const char *fk_info_str(THD *thd, FOREIGN_KEY_INFO *fk_info)
|
|||
`db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`)
|
||||
*/
|
||||
|
||||
res|= append_identifier(thd, &str, fk_info->foreign_db);
|
||||
res|= append_identifier(thd, &str, &fk_info->foreign_db);
|
||||
res|= str.append('.');
|
||||
res|= append_identifier(thd, &str, fk_info->foreign_table);
|
||||
res|= append_identifier(thd, &str, &fk_info->foreign_table);
|
||||
res|= str.append(STRING_WITH_LEN(", CONSTRAINT "));
|
||||
res|= append_identifier(thd, &str, fk_info->foreign_id);
|
||||
res|= append_identifier(thd, &str, &fk_info->foreign_id);
|
||||
res|= str.append(STRING_WITH_LEN(" FOREIGN KEY ("));
|
||||
res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields);
|
||||
res|= fk_info_append_fields(thd, &str, fk_info->foreign_fields);
|
||||
res|= str.append(STRING_WITH_LEN(") REFERENCES "));
|
||||
res|= append_identifier(thd, &str, fk_info->referenced_db);
|
||||
res|= append_identifier(thd, &str, &fk_info->referenced_db);
|
||||
res|= str.append('.');
|
||||
res|= append_identifier(thd, &str, fk_info->referenced_table);
|
||||
res|= append_identifier(thd, &str, &fk_info->referenced_table);
|
||||
res|= str.append(STRING_WITH_LEN(" ("));
|
||||
res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields);
|
||||
res|= fk_info_append_fields(thd, &str, fk_info->referenced_fields);
|
||||
res|= str.append(')');
|
||||
|
||||
return res ? NULL : thd->strmake(str.ptr(), str.length());
|
||||
|
|
@ -147,10 +145,10 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table)
|
|||
/* Loop over the set of foreign keys for which this table is a parent. */
|
||||
while ((fk_info= it++))
|
||||
{
|
||||
if (!table->s->db.streq(*fk_info->referenced_db) ||
|
||||
!table->s->table_name.streq(*fk_info->referenced_table) ||
|
||||
!table->s->db.streq(*fk_info->foreign_db) ||
|
||||
!table->s->table_name.streq(*fk_info->foreign_table))
|
||||
if (!table->s->db.streq(fk_info->referenced_db) ||
|
||||
!table->s->table_name.streq(fk_info->referenced_table) ||
|
||||
!table->s->db.streq(fk_info->foreign_db) ||
|
||||
!table->s->table_name.streq(fk_info->foreign_table))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
26
sql/table.h
26
sql/table.h
|
|
@ -37,6 +37,7 @@
|
|||
#include "sql_type.h" /* vers_kind_t */
|
||||
#include "privilege.h" /* privilege_t */
|
||||
#include "my_bit.h"
|
||||
#include "span.h"
|
||||
|
||||
/*
|
||||
Buffer for unix timestamp in microseconds:
|
||||
|
|
@ -2035,27 +2036,27 @@ enum enum_fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_NO_ACTION,
|
|||
|
||||
typedef struct st_foreign_key_info
|
||||
{
|
||||
LEX_CSTRING *foreign_id;
|
||||
LEX_CSTRING *foreign_db;
|
||||
LEX_CSTRING *foreign_table;
|
||||
LEX_CSTRING *referenced_db;
|
||||
LEX_CSTRING *referenced_table;
|
||||
Lex_ident_column foreign_id;
|
||||
Lex_ident_db foreign_db;
|
||||
Lex_ident_table foreign_table;
|
||||
Lex_ident_db referenced_db;
|
||||
Lex_ident_table referenced_table;
|
||||
enum_fk_option update_method;
|
||||
enum_fk_option delete_method;
|
||||
LEX_CSTRING *referenced_key_name;
|
||||
List<LEX_CSTRING> foreign_fields;
|
||||
List<LEX_CSTRING> referenced_fields;
|
||||
Lex_ident_column referenced_key_name;
|
||||
st_::span<Lex_ident_column> foreign_fields;
|
||||
st_::span<Lex_ident_column> referenced_fields;
|
||||
private:
|
||||
unsigned char *fields_nullable= nullptr;
|
||||
|
||||
/**
|
||||
Get the number of fields exist in foreign key relationship
|
||||
*/
|
||||
unsigned get_n_fields() const noexcept
|
||||
size_t get_n_fields() const noexcept
|
||||
{
|
||||
unsigned n_fields= foreign_fields.elements;
|
||||
size_t n_fields= foreign_fields.size();
|
||||
if (n_fields == 0)
|
||||
n_fields= referenced_fields.elements;
|
||||
n_fields= referenced_fields.size();
|
||||
return n_fields;
|
||||
}
|
||||
|
||||
|
|
@ -2110,12 +2111,11 @@ public:
|
|||
{
|
||||
if (!fields_nullable)
|
||||
return false;
|
||||
unsigned n_field= get_n_fields();
|
||||
size_t n_field= get_n_fields();
|
||||
DBUG_ASSERT(field < n_field);
|
||||
size_t bit= size_t{field} + referenced * n_field;
|
||||
return fields_nullable[bit / 8] & (1U << (bit % 8));
|
||||
}
|
||||
|
||||
} FOREIGN_KEY_INFO;
|
||||
|
||||
LEX_CSTRING *fk_option_name(enum_fk_option opt);
|
||||
|
|
|
|||
|
|
@ -1805,9 +1805,9 @@ wsrep_append_fk_parent_table(THD* thd, TABLE_LIST* tables, wsrep::key_array* key
|
|||
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
|
||||
while ((f_key_info=it++))
|
||||
{
|
||||
WSREP_DEBUG("appended fkey %s", f_key_info->referenced_table->str);
|
||||
keys->push_back(wsrep_prepare_key_for_toi(f_key_info->referenced_db->str,
|
||||
f_key_info->referenced_table->str,
|
||||
WSREP_DEBUG("appended fkey %s", f_key_info->referenced_table.str);
|
||||
keys->push_back(wsrep_prepare_key_for_toi(f_key_info->referenced_db.str,
|
||||
f_key_info->referenced_table.str,
|
||||
wsrep::key::shared));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15421,15 +15421,13 @@ get_foreign_key_info(
|
|||
char tmp_buff[NAME_LEN+1];
|
||||
char name_buff[NAME_LEN+1];
|
||||
const char* ptr;
|
||||
LEX_CSTRING* name = NULL;
|
||||
|
||||
if (dict_table_t::is_temporary_name(foreign->foreign_table_name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = dict_remove_db_name(foreign->id);
|
||||
f_key_info.foreign_id = thd_make_lex_string(
|
||||
thd, 0, ptr, strlen(ptr), 1);
|
||||
f_key_info.foreign_id.set_dup(thd, ptr);
|
||||
|
||||
/* Name format: database name, '/', table name, '\0' */
|
||||
|
||||
|
|
@ -15440,14 +15438,12 @@ get_foreign_key_info(
|
|||
tmp_buff[len] = 0;
|
||||
|
||||
len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff));
|
||||
f_key_info.referenced_db = thd_make_lex_string(
|
||||
thd, 0, name_buff, len, 1);
|
||||
f_key_info.referenced_db.set_dup(thd, name_buff, len);
|
||||
|
||||
/* Referenced (parent) table name */
|
||||
ptr = dict_remove_db_name(foreign->referenced_table_name);
|
||||
len = filename_to_tablename(ptr, name_buff, sizeof(name_buff), 1);
|
||||
f_key_info.referenced_table = thd_make_lex_string(
|
||||
thd, 0, name_buff, len, 1);
|
||||
f_key_info.referenced_table.set_dup(thd, name_buff, len);
|
||||
|
||||
/* Dependent (child) database name */
|
||||
len = dict_get_db_name_len(foreign->foreign_table_name);
|
||||
|
|
@ -15456,20 +15452,21 @@ get_foreign_key_info(
|
|||
tmp_buff[len] = 0;
|
||||
|
||||
len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff));
|
||||
f_key_info.foreign_db = thd_make_lex_string(
|
||||
thd, 0, name_buff, len, 1);
|
||||
f_key_info.foreign_db.set_dup(thd, name_buff, len);
|
||||
|
||||
/* Dependent (child) table name */
|
||||
ptr = dict_remove_db_name(foreign->foreign_table_name);
|
||||
len = filename_to_tablename(ptr, name_buff, sizeof(name_buff), 1);
|
||||
f_key_info.foreign_table = thd_make_lex_string(
|
||||
thd, 0, name_buff, len, 1);
|
||||
f_key_info.foreign_table.set_dup(thd, name_buff, len);
|
||||
|
||||
f_key_info.foreign_fields.alloc(thd, foreign->n_fields);
|
||||
f_key_info.referenced_fields.alloc(thd, foreign->n_fields);
|
||||
|
||||
do {
|
||||
ptr = foreign->foreign_col_names[i];
|
||||
name = thd_make_lex_string(thd, name, ptr,
|
||||
strlen(ptr), 1);
|
||||
f_key_info.foreign_fields.push_back(name);
|
||||
f_key_info.foreign_fields[i].set_dup(thd,
|
||||
foreign->foreign_col_names[i]);
|
||||
f_key_info.referenced_fields[i].set_dup(thd,
|
||||
foreign->referenced_col_names[i]);
|
||||
|
||||
if (dict_index_t* fidx = foreign->foreign_index) {
|
||||
if (fidx->fields[i].col->is_nullable()) {
|
||||
|
|
@ -15477,18 +15474,12 @@ get_foreign_key_info(
|
|||
foreign->n_fields);
|
||||
}
|
||||
}
|
||||
ptr = foreign->referenced_col_names[i];
|
||||
name = thd_make_lex_string(thd, name, ptr,
|
||||
strlen(ptr), 1);
|
||||
f_key_info.referenced_fields.push_back(name);
|
||||
|
||||
if (dict_index_t* ref_idx = foreign->referenced_index) {
|
||||
if (ref_idx->fields[i].col->is_nullable()) {
|
||||
f_key_info.set_nullable(thd, true, i,
|
||||
foreign->n_fields);
|
||||
}
|
||||
}
|
||||
|
||||
} while (++i < foreign->n_fields);
|
||||
|
||||
if (foreign->type & foreign->DELETE_CASCADE) {
|
||||
|
|
@ -15534,17 +15525,9 @@ get_foreign_key_info(
|
|||
}
|
||||
}
|
||||
|
||||
if (foreign->referenced_index
|
||||
&& foreign->referenced_index->name != NULL) {
|
||||
f_key_info.referenced_key_name = thd_make_lex_string(
|
||||
thd,
|
||||
nullptr,
|
||||
foreign->referenced_index->name,
|
||||
strlen(foreign->referenced_index->name),
|
||||
1);
|
||||
} else {
|
||||
f_key_info.referenced_key_name = NULL;
|
||||
}
|
||||
if (foreign->referenced_index && foreign->referenced_index->name)
|
||||
f_key_info.referenced_key_name.set_dup(thd,
|
||||
foreign->referenced_index->name);
|
||||
|
||||
pf_key_info = (FOREIGN_KEY_INFO*) thd_memdup(thd, &f_key_info,
|
||||
sizeof(FOREIGN_KEY_INFO));
|
||||
|
|
|
|||
|
|
@ -16693,19 +16693,9 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
|
|||
grn_id ref_table_id = grn_obj_get_range(ctx, column);
|
||||
grn_obj *ref_table = grn_ctx_at(ctx, ref_table_id);
|
||||
FOREIGN_KEY_INFO f_key_info;
|
||||
f_key_info.foreign_id = thd_make_lex_string(thd,
|
||||
NULL,
|
||||
column_name.c_str(),
|
||||
column_name.length(),
|
||||
TRUE);
|
||||
f_key_info.foreign_db = thd_make_lex_string(thd, NULL,
|
||||
table_share->db.str,
|
||||
table_share->db.length,
|
||||
TRUE);
|
||||
f_key_info.foreign_table = thd_make_lex_string(thd, NULL,
|
||||
table_share->table_name.str,
|
||||
table_share->table_name.length,
|
||||
TRUE);
|
||||
f_key_info.foreign_id.set_dup(thd, field->field_name);
|
||||
f_key_info.foreign_db.set_dup(thd, table_share->db);
|
||||
f_key_info.foreign_table.set_dup(thd, table_share->table_name);
|
||||
f_key_info.referenced_db = f_key_info.foreign_db;
|
||||
|
||||
char ref_table_buff[NAME_LEN + 1];
|
||||
|
|
@ -16714,20 +16704,16 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
|
|||
ref_table_buff[ref_table_name_length] = '\0';
|
||||
DBUG_PRINT("info", ("mroonga: ref_table_buff=%s", ref_table_buff));
|
||||
DBUG_PRINT("info", ("mroonga: ref_table_name_length=%d", ref_table_name_length));
|
||||
f_key_info.referenced_table = thd_make_lex_string(thd, NULL,
|
||||
ref_table_buff,
|
||||
ref_table_name_length,
|
||||
TRUE);
|
||||
|
||||
f_key_info.referenced_table.set_dup(thd, ref_table_buff,
|
||||
ref_table_name_length);
|
||||
f_key_info.update_method = FK_OPTION_RESTRICT;
|
||||
f_key_info.delete_method = FK_OPTION_RESTRICT;
|
||||
f_key_info.referenced_key_name = thd_make_lex_string(thd, NULL, "PRIMARY",
|
||||
7, TRUE);
|
||||
LEX_CSTRING *field_name = thd_make_lex_string(thd,
|
||||
NULL,
|
||||
column_name.c_str(),
|
||||
column_name.length(),
|
||||
TRUE);
|
||||
f_key_info.foreign_fields.push_back(field_name);
|
||||
f_key_info.referenced_key_name = "PRIMARY"_Lex_ident_column;
|
||||
|
||||
f_key_info.foreign_fields.alloc(thd, 1);
|
||||
f_key_info.referenced_fields.alloc(thd, 1);
|
||||
f_key_info.foreign_fields[0].set_dup(thd, field->field_name);
|
||||
|
||||
char ref_path[FN_REFLEN + 1];
|
||||
TABLE_LIST table_list;
|
||||
|
|
@ -16736,7 +16722,7 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
|
|||
table_share->db.str, ref_table_buff, "", 0);
|
||||
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
|
||||
|
||||
LEX_CSTRING table_name= { ref_table_buff, (size_t) ref_table_name_length };
|
||||
LEX_CSTRING table_name { ref_table_buff, (size_t) ref_table_name_length };
|
||||
table_list.init_one_table(&table_share->db, &table_name, 0, TL_WRITE);
|
||||
mrn_open_mutex_lock(table_share);
|
||||
tmp_ref_table_share =
|
||||
|
|
@ -16748,11 +16734,7 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
|
|||
uint ref_pkey_nr = tmp_ref_table_share->primary_key;
|
||||
KEY *ref_key_info = &tmp_ref_table_share->key_info[ref_pkey_nr];
|
||||
Field *ref_field = &ref_key_info->key_part->field[0];
|
||||
LEX_CSTRING *ref_col_name = thd_make_lex_string(thd, NULL,
|
||||
ref_field->field_name.str,
|
||||
ref_field->field_name.length,
|
||||
TRUE);
|
||||
f_key_info.referenced_fields.push_back(ref_col_name);
|
||||
f_key_info.referenced_fields[0].set_dup(thd, ref_field->field_name);
|
||||
mrn_open_mutex_lock(table_share);
|
||||
mrn_free_tmp_table_share(tmp_ref_table_share);
|
||||
mrn_open_mutex_unlock(table_share);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue