mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-35854 dict_get_referenced_table() got too many parameters
dict_get_referenced_table(): Make the callers responsible for converting the database and table names.
This commit is contained in:
parent
d5a417b9d5
commit
301ee7bccb
4 changed files with 180 additions and 133 deletions
|
@ -3222,66 +3222,17 @@ foreign constraint parser to get the referenced table.
|
||||||
heap memory passed in */
|
heap memory passed in */
|
||||||
char*
|
char*
|
||||||
dict_get_referenced_table(
|
dict_get_referenced_table(
|
||||||
const char* name, /*!< in: foreign key table name */
|
LEX_CSTRING database_name, /*!< in: table db name */
|
||||||
const char* database_name, /*!< in: table db name */
|
LEX_CSTRING table_name, /*!< in: table name */
|
||||||
ulint database_name_len, /*!< in: db name length */
|
dict_table_t** table, /*!< out: table object or NULL */
|
||||||
const char* table_name, /*!< in: table name */
|
mem_heap_t* heap) noexcept /*!< in/out: heap memory */
|
||||||
ulint table_name_len, /*!< in: table name length */
|
|
||||||
dict_table_t** table, /*!< out: table object or NULL */
|
|
||||||
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
||||||
CHARSET_INFO* from_cs) /*!< in: table name charset */
|
|
||||||
{
|
{
|
||||||
char* ref;
|
const size_t len = database_name.length + table_name.length + 1;
|
||||||
char db_name[MAX_DATABASE_NAME_LEN];
|
char* ref = static_cast<char*>(mem_heap_alloc(heap, len + 1));
|
||||||
char tbl_name[MAX_TABLE_NAME_LEN];
|
memcpy(ref, database_name.str, database_name.length);
|
||||||
CHARSET_INFO* to_cs = &my_charset_filename;
|
ref[database_name.length] = '/';
|
||||||
uint errors;
|
memcpy(ref + database_name.length + 1, table_name.str,
|
||||||
ut_ad(database_name || name);
|
table_name.length + 1);
|
||||||
ut_ad(table_name);
|
|
||||||
|
|
||||||
if (!strncmp(table_name, srv_mysql50_table_name_prefix,
|
|
||||||
sizeof(srv_mysql50_table_name_prefix) - 1)) {
|
|
||||||
/* This is a pre-5.1 table name
|
|
||||||
containing chars other than [A-Za-z0-9].
|
|
||||||
Discard the prefix and use raw UTF-8 encoding. */
|
|
||||||
table_name += sizeof(srv_mysql50_table_name_prefix) - 1;
|
|
||||||
table_name_len -= sizeof(srv_mysql50_table_name_prefix) - 1;
|
|
||||||
|
|
||||||
to_cs = system_charset_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
table_name_len = strconvert(from_cs, table_name, table_name_len, to_cs,
|
|
||||||
tbl_name, MAX_TABLE_NAME_LEN, &errors);
|
|
||||||
table_name = tbl_name;
|
|
||||||
|
|
||||||
if (database_name) {
|
|
||||||
to_cs = &my_charset_filename;
|
|
||||||
if (!strncmp(database_name, srv_mysql50_table_name_prefix,
|
|
||||||
sizeof(srv_mysql50_table_name_prefix) - 1)) {
|
|
||||||
database_name
|
|
||||||
+= sizeof(srv_mysql50_table_name_prefix) - 1;
|
|
||||||
database_name_len
|
|
||||||
-= sizeof(srv_mysql50_table_name_prefix) - 1;
|
|
||||||
to_cs = system_charset_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
database_name_len = strconvert(
|
|
||||||
from_cs, database_name, database_name_len, to_cs,
|
|
||||||
db_name, MAX_DATABASE_NAME_LEN, &errors);
|
|
||||||
database_name = db_name;
|
|
||||||
} else {
|
|
||||||
/* Use the database name of the foreign key table */
|
|
||||||
|
|
||||||
database_name = name;
|
|
||||||
database_name_len = dict_get_db_name_len(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy database_name, '/', table_name, '\0' */
|
|
||||||
const size_t len = database_name_len + table_name_len + 1;
|
|
||||||
ref = static_cast<char*>(mem_heap_alloc(heap, len + 1));
|
|
||||||
memcpy(ref, database_name, database_name_len);
|
|
||||||
ref[database_name_len] = '/';
|
|
||||||
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
|
||||||
|
|
||||||
/* Values; 0 = Store and compare as given; case sensitive
|
/* Values; 0 = Store and compare as given; case sensitive
|
||||||
1 = Store and compare in lower; case insensitive
|
1 = Store and compare in lower; case insensitive
|
||||||
|
@ -3289,10 +3240,10 @@ dict_get_referenced_table(
|
||||||
if (lower_case_table_names == 2) {
|
if (lower_case_table_names == 2) {
|
||||||
innobase_casedn_str(ref);
|
innobase_casedn_str(ref);
|
||||||
*table = dict_sys.load_table({ref, len});
|
*table = dict_sys.load_table({ref, len});
|
||||||
memcpy(ref, database_name, database_name_len);
|
memcpy(ref, database_name.str, database_name.length);
|
||||||
ref[database_name_len] = '/';
|
ref[database_name.length] = '/';
|
||||||
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
memcpy(ref + database_name.length + 1,
|
||||||
|
table_name.str, table_name.length + 1);
|
||||||
} else {
|
} else {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (lower_case_table_names == 1) {
|
if (lower_case_table_names == 1) {
|
||||||
|
|
|
@ -12404,6 +12404,8 @@ create_table_info_t::create_foreign_keys()
|
||||||
const char* ref_column_names[MAX_COLS_PER_FK];
|
const char* ref_column_names[MAX_COLS_PER_FK];
|
||||||
char create_name[MAX_DATABASE_NAME_LEN + 1 +
|
char create_name[MAX_DATABASE_NAME_LEN + 1 +
|
||||||
MAX_TABLE_NAME_LEN + 1];
|
MAX_TABLE_NAME_LEN + 1];
|
||||||
|
char db_name[MAX_DATABASE_NAME_LEN + 1];
|
||||||
|
char t_name[MAX_TABLE_NAME_LEN + 1];
|
||||||
dict_index_t* index = NULL;
|
dict_index_t* index = NULL;
|
||||||
fkerr_t index_error = FK_SUCCESS;
|
fkerr_t index_error = FK_SUCCESS;
|
||||||
dict_index_t* err_index = NULL;
|
dict_index_t* err_index = NULL;
|
||||||
|
@ -12411,59 +12413,84 @@ create_table_info_t::create_foreign_keys()
|
||||||
const bool tmp_table = m_flags2 & DICT_TF2_TEMPORARY;
|
const bool tmp_table = m_flags2 & DICT_TF2_TEMPORARY;
|
||||||
const CHARSET_INFO* cs = thd_charset(m_thd);
|
const CHARSET_INFO* cs = thd_charset(m_thd);
|
||||||
const char* operation = "Create ";
|
const char* operation = "Create ";
|
||||||
const char* name = m_table_name;
|
|
||||||
|
|
||||||
enum_sql_command sqlcom = enum_sql_command(thd_sql_command(m_thd));
|
enum_sql_command sqlcom = enum_sql_command(thd_sql_command(m_thd));
|
||||||
|
LEX_CSTRING name= {m_table_name, strlen(m_table_name)};
|
||||||
|
|
||||||
if (sqlcom == SQLCOM_ALTER_TABLE) {
|
if (sqlcom == SQLCOM_ALTER_TABLE) {
|
||||||
dict_table_t* table_to_alter;
|
|
||||||
mem_heap_t* heap = mem_heap_create(10000);
|
mem_heap_t* heap = mem_heap_create(10000);
|
||||||
ulint highest_id_so_far;
|
LEX_CSTRING table_name = m_form->s->table_name;
|
||||||
char* n = dict_get_referenced_table(
|
CHARSET_INFO* to_cs = &my_charset_filename;
|
||||||
name, LEX_STRING_WITH_LEN(m_form->s->db),
|
|
||||||
LEX_STRING_WITH_LEN(m_form->s->table_name),
|
if (!strncmp(table_name.str, srv_mysql50_table_name_prefix,
|
||||||
&table_to_alter, heap, cs);
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
table_name.str
|
||||||
|
+= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
table_name.length
|
||||||
|
-= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint errors;
|
||||||
|
LEX_CSTRING t;
|
||||||
|
t.str = t_name;
|
||||||
|
t.length = strconvert(cs, LEX_STRING_WITH_LEN(table_name),
|
||||||
|
to_cs, t_name, MAX_TABLE_NAME_LEN,
|
||||||
|
&errors);
|
||||||
|
LEX_CSTRING d = m_form->s->db;
|
||||||
|
|
||||||
|
if (!strncmp(d.str, srv_mysql50_table_name_prefix,
|
||||||
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
d.str += sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
d.length -= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
} else {
|
||||||
|
to_cs = &my_charset_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.length = strconvert(cs, LEX_STRING_WITH_LEN(d), to_cs,
|
||||||
|
db_name, MAX_DATABASE_NAME_LEN,
|
||||||
|
&errors);
|
||||||
|
d.str = db_name;
|
||||||
|
|
||||||
|
dict_table_t* alter_table;
|
||||||
|
char* n = dict_get_referenced_table(d, t, &alter_table, heap);
|
||||||
|
|
||||||
/* Starting from 4.0.18 and 4.1.2, we generate foreign key id's
|
/* Starting from 4.0.18 and 4.1.2, we generate foreign key id's
|
||||||
in the format databasename/tablename_ibfk_[number], where
|
in the format databasename/tablename_ibfk_[number], where
|
||||||
[number] is local to the table; look for the highest [number]
|
[number] is local to the table; look for the highest [number]
|
||||||
for table_to_alter, so that we can assign to new constraints
|
for alter_table, so that we can assign to new constraints
|
||||||
higher numbers. */
|
higher numbers. */
|
||||||
|
|
||||||
/* If we are altering a temporary table, the table name after
|
/* If we are altering a temporary table, the table name after
|
||||||
ALTER TABLE does not correspond to the internal table name, and
|
ALTER TABLE does not correspond to the internal table name, and
|
||||||
table_to_alter is NULL. TODO: should we fix this somehow? */
|
alter_table=nullptr. But, we do not support FOREIGN KEY
|
||||||
|
constraints for temporary tables. */
|
||||||
|
|
||||||
if (table_to_alter) {
|
if (alter_table) {
|
||||||
n = table_to_alter->name.m_name;
|
n = alter_table->name.m_name;
|
||||||
highest_id_so_far = dict_table_get_highest_foreign_id(
|
number = 1 + dict_table_get_highest_foreign_id(
|
||||||
table_to_alter);
|
alter_table);
|
||||||
} else {
|
|
||||||
highest_id_so_far = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* bufend = innobase_convert_name(
|
*innobase_convert_name(create_name, sizeof create_name,
|
||||||
create_name, sizeof create_name, n, strlen(n), m_thd);
|
n, strlen(n), m_thd) = '\0';
|
||||||
create_name[bufend - create_name] = '\0';
|
|
||||||
number = highest_id_so_far + 1;
|
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
operation = "Alter ";
|
operation = "Alter ";
|
||||||
} else if (strstr(name, "#P#") || strstr(name, "#p#")) {
|
} else if (strstr(m_table_name, "#P#")
|
||||||
|
|| strstr(m_table_name, "#p#")) {
|
||||||
/* Partitioned table */
|
/* Partitioned table */
|
||||||
create_name[0] = '\0';
|
create_name[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
char* bufend = innobase_convert_name(create_name,
|
*innobase_convert_name(create_name, sizeof create_name,
|
||||||
sizeof create_name,
|
LEX_STRING_WITH_LEN(name), m_thd)= '\0';
|
||||||
name,
|
|
||||||
strlen(name), m_thd);
|
|
||||||
create_name[bufend - create_name] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Alter_info* alter_info = m_create_info->alter_info;
|
Alter_info* alter_info = m_create_info->alter_info;
|
||||||
ut_ad(alter_info);
|
ut_ad(alter_info);
|
||||||
List_iterator_fast<Key> key_it(alter_info->key_list);
|
List_iterator_fast<Key> key_it(alter_info->key_list);
|
||||||
|
|
||||||
dict_table_t* table = dict_sys.find_table({name,strlen(name)});
|
dict_table_t* table = dict_sys.find_table({name.str, name.length});
|
||||||
if (!table) {
|
if (!table) {
|
||||||
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name,
|
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name,
|
||||||
"%s table %s foreign key constraint"
|
"%s table %s foreign key constraint"
|
||||||
|
@ -12510,27 +12537,27 @@ create_table_info_t::create_foreign_keys()
|
||||||
col->field_name.length);
|
col->field_name.length);
|
||||||
success = find_col(table, column_names + i);
|
success = find_col(table, column_names + i);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
key_text k(fk);
|
|
||||||
ib_foreign_warn(
|
ib_foreign_warn(
|
||||||
m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
||||||
create_name,
|
create_name,
|
||||||
"%s table %s foreign key %s constraint"
|
"%s table %s foreign key %s constraint"
|
||||||
" failed. Column %s was not found.",
|
" failed. Column %s was not found.",
|
||||||
operation, create_name, k.str(),
|
operation, create_name,
|
||||||
|
key_text(fk).str(),
|
||||||
column_names[i]);
|
column_names[i]);
|
||||||
dict_foreign_free(foreign);
|
dict_foreign_free(foreign);
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
return (DB_CANNOT_ADD_CONSTRAINT);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
if (i >= MAX_COLS_PER_FK) {
|
if (i >= MAX_COLS_PER_FK) {
|
||||||
key_text k(fk);
|
|
||||||
ib_foreign_warn(
|
ib_foreign_warn(
|
||||||
m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
||||||
create_name,
|
create_name,
|
||||||
"%s table %s foreign key %s constraint"
|
"%s table %s foreign key %s constraint"
|
||||||
" failed. Too many columns: %u (%u "
|
" failed. Too many columns: %u (%u "
|
||||||
"allowed).",
|
"allowed).",
|
||||||
operation, create_name, k.str(), i,
|
operation, create_name,
|
||||||
|
key_text(fk).str(), i,
|
||||||
MAX_COLS_PER_FK);
|
MAX_COLS_PER_FK);
|
||||||
dict_foreign_free(foreign);
|
dict_foreign_free(foreign);
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
return (DB_CANNOT_ADD_CONSTRAINT);
|
||||||
|
@ -12542,9 +12569,9 @@ create_table_info_t::create_foreign_keys()
|
||||||
&index_error, &err_col, &err_index);
|
&index_error, &err_col, &err_index);
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
key_text k(fk);
|
|
||||||
foreign_push_index_error(m_trx, operation, create_name,
|
foreign_push_index_error(m_trx, operation, create_name,
|
||||||
k.str(), column_names,
|
key_text(fk).str(),
|
||||||
|
column_names,
|
||||||
index_error, err_col,
|
index_error, err_col,
|
||||||
err_index, table);
|
err_index, table);
|
||||||
dict_foreign_free(foreign);
|
dict_foreign_free(foreign);
|
||||||
|
@ -12610,32 +12637,68 @@ create_table_info_t::create_foreign_keys()
|
||||||
memcpy(foreign->foreign_col_names, column_names,
|
memcpy(foreign->foreign_col_names, column_names,
|
||||||
i * sizeof(void*));
|
i * sizeof(void*));
|
||||||
|
|
||||||
foreign->referenced_table_name = dict_get_referenced_table(
|
LEX_CSTRING table_name = fk->ref_table;
|
||||||
name, LEX_STRING_WITH_LEN(fk->ref_db),
|
CHARSET_INFO* to_cs = &my_charset_filename;
|
||||||
LEX_STRING_WITH_LEN(fk->ref_table),
|
uint errors;
|
||||||
&foreign->referenced_table, foreign->heap, cs);
|
LEX_CSTRING t = table_name;
|
||||||
|
LEX_CSTRING d = fk->ref_db;
|
||||||
|
|
||||||
if (!foreign->referenced_table_name) {
|
if (!d.str) {
|
||||||
return (DB_OUT_OF_MEMORY);
|
d = {table->name.m_name, table->name.dblen()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strncmp(table_name.str, srv_mysql50_table_name_prefix,
|
||||||
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
table_name.str
|
||||||
|
+= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
table_name.length
|
||||||
|
-= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.str = t_name;
|
||||||
|
t.length = strconvert(cs, LEX_STRING_WITH_LEN(table_name),
|
||||||
|
to_cs, t_name,
|
||||||
|
MAX_TABLE_NAME_LEN, &errors);
|
||||||
|
|
||||||
|
if (!strncmp(d.str, srv_mysql50_table_name_prefix,
|
||||||
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
d.str += sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
d.length -= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
} else if (d.str == table->name.m_name) {
|
||||||
|
goto name_converted;
|
||||||
|
} else {
|
||||||
|
to_cs = &my_charset_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.str != table->name.m_name) {
|
||||||
|
d.length = strconvert(cs, LEX_STRING_WITH_LEN(d),
|
||||||
|
to_cs, db_name,
|
||||||
|
MAX_DATABASE_NAME_LEN,
|
||||||
|
&errors);
|
||||||
|
d.str = db_name;
|
||||||
|
}
|
||||||
|
name_converted:
|
||||||
|
foreign->referenced_table_name = dict_get_referenced_table(
|
||||||
|
d, t, &foreign->referenced_table, foreign->heap);
|
||||||
|
|
||||||
if (!foreign->referenced_table && m_trx->check_foreigns) {
|
if (!foreign->referenced_table && m_trx->check_foreigns) {
|
||||||
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||||
char* bufend;
|
|
||||||
|
|
||||||
bufend = innobase_convert_name(
|
*innobase_convert_name(
|
||||||
buf, MAX_TABLE_NAME_LEN,
|
buf, MAX_TABLE_NAME_LEN,
|
||||||
foreign->referenced_table_name,
|
foreign->referenced_table_name,
|
||||||
strlen(foreign->referenced_table_name), m_thd);
|
strlen(foreign->referenced_table_name), m_thd)
|
||||||
buf[bufend - buf] = '\0';
|
= '\0';
|
||||||
key_text k(fk);
|
|
||||||
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT,
|
||||||
create_name,
|
create_name,
|
||||||
"%s table %s with foreign key %s "
|
"%s table %s with foreign key %s "
|
||||||
"constraint failed. Referenced table "
|
"constraint failed. Referenced table "
|
||||||
"%s not found in the data dictionary.",
|
"%s not found in the data dictionary.",
|
||||||
operation, create_name, k.str(), buf);
|
operation, create_name,
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
key_text(fk).str(), buf);
|
||||||
|
return DB_CANNOT_ADD_CONSTRAINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't allow foreign keys on partitioned tables yet. */
|
/* Don't allow foreign keys on partitioned tables yet. */
|
||||||
|
@ -12658,7 +12721,6 @@ create_table_info_t::create_foreign_keys()
|
||||||
success = find_col(foreign->referenced_table,
|
success = find_col(foreign->referenced_table,
|
||||||
ref_column_names + j);
|
ref_column_names + j);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
key_text k(fk);
|
|
||||||
ib_foreign_warn(
|
ib_foreign_warn(
|
||||||
m_trx,
|
m_trx,
|
||||||
DB_CANNOT_ADD_CONSTRAINT,
|
DB_CANNOT_ADD_CONSTRAINT,
|
||||||
|
@ -12667,9 +12729,9 @@ create_table_info_t::create_foreign_keys()
|
||||||
"constraint failed. "
|
"constraint failed. "
|
||||||
"Column %s was not found.",
|
"Column %s was not found.",
|
||||||
operation, create_name,
|
operation, create_name,
|
||||||
k.str(), ref_column_names[j]);
|
key_text(fk).str(),
|
||||||
|
ref_column_names[j]);
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
return DB_CANNOT_ADD_CONSTRAINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++j;
|
++j;
|
||||||
|
@ -12689,16 +12751,15 @@ create_table_info_t::create_foreign_keys()
|
||||||
&err_index);
|
&err_index);
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
key_text k(fk);
|
|
||||||
foreign_push_index_error(
|
foreign_push_index_error(
|
||||||
m_trx, operation, create_name, k.str(),
|
m_trx, operation, create_name,
|
||||||
|
key_text(fk).str(),
|
||||||
column_names, index_error, err_col,
|
column_names, index_error, err_col,
|
||||||
err_index, foreign->referenced_table);
|
err_index, foreign->referenced_table);
|
||||||
|
return DB_CANNOT_ADD_CONSTRAINT;
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ut_a(m_trx->check_foreigns == FALSE);
|
ut_a(!m_trx->check_foreigns);
|
||||||
index = NULL;
|
index = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12735,7 +12796,6 @@ create_table_info_t::create_foreign_keys()
|
||||||
NULL
|
NULL
|
||||||
if the column is not allowed to be
|
if the column is not allowed to be
|
||||||
NULL! */
|
NULL! */
|
||||||
key_text k(fk);
|
|
||||||
ib_foreign_warn(
|
ib_foreign_warn(
|
||||||
m_trx,
|
m_trx,
|
||||||
DB_CANNOT_ADD_CONSTRAINT,
|
DB_CANNOT_ADD_CONSTRAINT,
|
||||||
|
@ -12746,9 +12806,9 @@ create_table_info_t::create_foreign_keys()
|
||||||
"but column '%s' is defined as "
|
"but column '%s' is defined as "
|
||||||
"NOT NULL.",
|
"NOT NULL.",
|
||||||
operation, create_name,
|
operation, create_name,
|
||||||
k.str(), col_name);
|
key_text(fk).str(), col_name);
|
||||||
|
|
||||||
return (DB_CANNOT_ADD_CONSTRAINT);
|
return DB_CANNOT_ADD_CONSTRAINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ Smart ALTER TABLE
|
||||||
#include <sql_class.h>
|
#include <sql_class.h>
|
||||||
#include <sql_table.h>
|
#include <sql_table.h>
|
||||||
#include <mysql/plugin.h>
|
#include <mysql/plugin.h>
|
||||||
|
#include <strfunc.h>
|
||||||
|
|
||||||
/* Include necessary InnoDB headers */
|
/* Include necessary InnoDB headers */
|
||||||
#include "btr0sea.h"
|
#include "btr0sea.h"
|
||||||
|
@ -3231,6 +3232,8 @@ innobase_get_foreign_key_info(
|
||||||
ulint num_fk = 0;
|
ulint num_fk = 0;
|
||||||
Alter_info* alter_info = ha_alter_info->alter_info;
|
Alter_info* alter_info = ha_alter_info->alter_info;
|
||||||
const CHARSET_INFO* cs = thd_charset(trx->mysql_thd);
|
const CHARSET_INFO* cs = thd_charset(trx->mysql_thd);
|
||||||
|
char db_name[MAX_DATABASE_NAME_LEN + 1];
|
||||||
|
char t_name[MAX_TABLE_NAME_LEN + 1];
|
||||||
|
|
||||||
DBUG_ENTER("innobase_get_foreign_key_info");
|
DBUG_ENTER("innobase_get_foreign_key_info");
|
||||||
|
|
||||||
|
@ -3295,14 +3298,51 @@ innobase_get_foreign_key_info(
|
||||||
|
|
||||||
add_fk[num_fk] = dict_mem_foreign_create();
|
add_fk[num_fk] = dict_mem_foreign_create();
|
||||||
|
|
||||||
|
LEX_CSTRING table_name = fk_key->ref_table;
|
||||||
|
CHARSET_INFO* to_cs = &my_charset_filename;
|
||||||
|
|
||||||
|
if (!strncmp(table_name.str, srv_mysql50_table_name_prefix,
|
||||||
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
table_name.str
|
||||||
|
+= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
table_name.length
|
||||||
|
-= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint errors;
|
||||||
|
LEX_CSTRING t;
|
||||||
|
t.str = t_name;
|
||||||
|
t.length = strconvert(cs, LEX_STRING_WITH_LEN(table_name),
|
||||||
|
to_cs, t_name, MAX_TABLE_NAME_LEN,
|
||||||
|
&errors);
|
||||||
|
LEX_CSTRING d = fk_key->ref_db;
|
||||||
|
if (!d.str) {
|
||||||
|
d.str = table->name.m_name;
|
||||||
|
d.length = table->name.dblen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(d.str, srv_mysql50_table_name_prefix,
|
||||||
|
sizeof srv_mysql50_table_name_prefix - 1)) {
|
||||||
|
d.str += sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
d.length -= sizeof srv_mysql50_table_name_prefix - 1;
|
||||||
|
to_cs = system_charset_info;
|
||||||
|
} else if (d.str == table->name.m_name) {
|
||||||
|
goto name_converted;
|
||||||
|
} else {
|
||||||
|
to_cs = &my_charset_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.length = strconvert(cs, LEX_STRING_WITH_LEN(d), to_cs,
|
||||||
|
db_name, MAX_DATABASE_NAME_LEN,
|
||||||
|
&errors);
|
||||||
|
d.str = db_name;
|
||||||
|
|
||||||
|
name_converted:
|
||||||
dict_sys.lock(SRW_LOCK_CALL);
|
dict_sys.lock(SRW_LOCK_CALL);
|
||||||
|
|
||||||
referenced_table_name = dict_get_referenced_table(
|
referenced_table_name = dict_get_referenced_table(
|
||||||
table->name.m_name,
|
d, t, &referenced_table, add_fk[num_fk]->heap);
|
||||||
LEX_STRING_WITH_LEN(fk_key->ref_db),
|
|
||||||
LEX_STRING_WITH_LEN(fk_key->ref_table),
|
|
||||||
&referenced_table,
|
|
||||||
add_fk[num_fk]->heap, cs);
|
|
||||||
|
|
||||||
/* Test the case when referenced_table failed to
|
/* Test the case when referenced_table failed to
|
||||||
open, if trx->check_foreigns is not set, we should
|
open, if trx->check_foreigns is not set, we should
|
||||||
|
|
|
@ -62,15 +62,11 @@ foreign constraint parser to get the referenced table.
|
||||||
heap memory passed in */
|
heap memory passed in */
|
||||||
char*
|
char*
|
||||||
dict_get_referenced_table(
|
dict_get_referenced_table(
|
||||||
/*======================*/
|
LEX_CSTRING database_name, /*!< in: table db name */
|
||||||
const char* name, /*!< in: foreign key table name */
|
LEX_CSTRING table_name, /*!< in: table name */
|
||||||
const char* database_name, /*!< in: table db name */
|
|
||||||
ulint database_name_len,/*!< in: db name length */
|
|
||||||
const char* table_name, /*!< in: table name */
|
|
||||||
ulint table_name_len, /*!< in: table name length */
|
|
||||||
dict_table_t** table, /*!< out: table object or NULL */
|
dict_table_t** table, /*!< out: table object or NULL */
|
||||||
mem_heap_t* heap, /*!< in: heap memory */
|
mem_heap_t* heap) /*!< in/out: heap memory */
|
||||||
CHARSET_INFO* from_cs); /*!< in: table name charset */
|
noexcept MY_ATTRIBUTE((nonnull));
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Frees a foreign key struct. */
|
Frees a foreign key struct. */
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue