Commit be8f5a6b authored by Murthy Narkedimilli's avatar Murthy Narkedimilli

Merging the changes from 5.1 branch to release branch.

Includes bug fixes for:
Bug #16722314 FOREIGN KEY ID MODIFIED DURING EXPORT
Bug #16754901 PARS_INFO_FREE NOT CALLED IN DICT_CREATE_ADD_FOREIGN_TO_DICTIONARY
parent 92989fde
......@@ -27,6 +27,21 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0vec.h"
#include "ha_prototypes.h"
/*************************************************************************
Checks if a table name contains the string TEMP_TABLE_PATH_PREFIX which
denotes temporary tables in MySQL. */
static
ibool
row_is_mysql_tmp_table_name(
/*========================*/
/* out: TRUE if temporary table */
const char* name) /* in: table name in the form
'database/tablename' */
{
return(strstr(name, TEMP_TABLE_PATH_PREFIX) != NULL);
}
/*********************************************************************
Based on a table object, this function builds the entry to be inserted
in the SYS_TABLES system table. */
......@@ -1347,26 +1362,47 @@ dict_create_add_foreign_to_dictionary(
{
ulint error;
ulint i;
pars_info_t* info = pars_info_create();
pars_info_t* info;
if (foreign->id == NULL) {
char* stripped_name;
/* Generate a new constraint id */
ulint namelen = strlen(table->name);
char* id = mem_heap_alloc(foreign->heap, namelen + 20);
/* no overflow if number < 1e13 */
sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++);
foreign->id = id;
stripped_name = strchr(foreign->id, '/') + 1;
if (innobase_check_identifier_length(stripped_name)) {
fprintf(stderr, "InnoDB: Generated foreign key "
"name (%s) is too long\n", foreign->id);
return(DB_IDENTIFIER_TOO_LONG);
if (row_is_mysql_tmp_table_name(table->name)) {
sprintf(id, "%s_ibfk_%lu", table->name,
(ulong) (*id_nr)++);
} else {
char table_name[MAX_TABLE_NAME_LEN + 20] = "";
uint errors = 0;
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN + 20);
innobase_convert_to_system_charset(
strchr(table_name, '/') + 1,
strchr(table->name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN + 20);
}
sprintf(id, "%s_ibfk_%lu", table_name,
(ulong) (*id_nr)++);
if (innobase_check_identifier_length(
strchr(id,'/') + 1)) {
return(DB_IDENTIFIER_TOO_LONG);
}
}
foreign->id = id;
}
info = pars_info_create();
pars_info_add_str_literal(info, "id", foreign->id);
pars_info_add_str_literal(info, "for_name", table->name);
......
......@@ -1052,6 +1052,7 @@ dict_table_rename_in_cache(
foreign = UT_LIST_GET_FIRST(table->foreign_list);
while (foreign != NULL) {
if (ut_strlen(foreign->foreign_table_name)
< ut_strlen(table->name)) {
/* Allocate a longer name buffer;
......@@ -1065,34 +1066,115 @@ dict_table_rename_in_cache(
strcpy(foreign->foreign_table_name, table->name);
if (strchr(foreign->id, '/')) {
/* This is a >= 4.0.18 format id */
ulint db_len;
char* old_id;
char old_name_cs_filename[MAX_TABLE_NAME_LEN+20];
uint errors = 0;
/* All table names are internally stored in charset
my_charset_filename (except the temp tables and the
partition identifier suffix in partition tables). The
foreign key constraint names are internally stored
in UTF-8 charset. The variable fkid here is used
to store foreign key constraint name in charset
my_charset_filename for comparison further below. */
char fkid[MAX_TABLE_NAME_LEN+20];
ibool on_tmp = FALSE;
/* The old table name in my_charset_filename is stored
in old_name_cs_filename */
strncpy(old_name_cs_filename, old_name,
MAX_TABLE_NAME_LEN);
if (strstr(old_name, TEMP_TABLE_PATH_PREFIX) == NULL) {
innobase_convert_to_system_charset(
strchr(old_name_cs_filename, '/') + 1,
strchr(old_name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* There has been an error to convert
old table into UTF-8. This probably
means that the old table name is
actually in UTF-8. */
innobase_convert_to_filename_charset(
strchr(old_name_cs_filename,
'/') + 1,
strchr(old_name, '/') + 1,
MAX_TABLE_NAME_LEN);
} else {
/* Old name already in
my_charset_filename */
strncpy(old_name_cs_filename, old_name,
MAX_TABLE_NAME_LEN);
}
}
/* This is a >= 4.0.18 format id */
strncpy(fkid, foreign->id, MAX_TABLE_NAME_LEN);
if (strstr(fkid, TEMP_TABLE_PATH_PREFIX) == NULL) {
innobase_convert_to_filename_charset(
strchr(fkid, '/') + 1,
strchr(foreign->id, '/') + 1,
MAX_TABLE_NAME_LEN+20);
} else {
on_tmp = TRUE;
}
old_id = mem_strdup(foreign->id);
if (ut_strlen(foreign->id) > ut_strlen(old_name)
if (ut_strlen(fkid) > ut_strlen(old_name_cs_filename)
+ ((sizeof dict_ibfk) - 1)
&& !memcmp(foreign->id, old_name,
ut_strlen(old_name))
&& !memcmp(foreign->id + ut_strlen(old_name),
&& !memcmp(fkid, old_name_cs_filename,
ut_strlen(old_name_cs_filename))
&& !memcmp(fkid + ut_strlen(old_name_cs_filename),
dict_ibfk, (sizeof dict_ibfk) - 1)) {
char table_name[MAX_TABLE_NAME_LEN] = "";
uint errors = 0;
/* This is a generated >= 4.0.18 format id */
if (strlen(table->name) > strlen(old_name)) {
foreign->id = mem_heap_alloc(
foreign->id = mem_heap_zalloc(
foreign->heap,
strlen(table->name)
+ strlen(old_id) + 1);
}
/* Convert the table name to UTF-8 */
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN);
innobase_convert_to_system_charset(
strchr(table_name, '/') + 1,
strchr(table->name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* Table name could not be converted
from charset my_charset_filename to
UTF-8. This means that the table name
is already in UTF-8 (#mysql#50). */
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN);
}
/* Replace the prefix 'databasename/tablename'
with the new names */
strcpy(foreign->id, table->name);
strcat(foreign->id,
old_id + ut_strlen(old_name));
strcpy(foreign->id, table_name);
if (on_tmp) {
strcat(foreign->id,
old_id + ut_strlen(old_name));
} else {
sprintf(strchr(foreign->id, '/') + 1,
"%s%s",
strchr(table_name, '/') +1,
strstr(old_id, "_ibfk_") );
}
} else {
/* This is a >= 4.0.18 format id where the user
gave the id name */
......@@ -4108,7 +4190,6 @@ dict_print_info_on_foreign_key_in_create_format(
dict_foreign_t* foreign, /* in: foreign key constraint */
ibool add_newline) /* in: whether to add a newline */
{
char constraint_name[MAX_TABLE_NAME_LEN];
const char* stripped_id;
ulint i;
......@@ -4130,9 +4211,7 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(" CONSTRAINT ", file);
innobase_convert_to_system_charset(constraint_name, stripped_id,
MAX_TABLE_NAME_LEN);
ut_print_name(file, trx, FALSE, constraint_name);
ut_print_name(file, trx, FALSE, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
......
......@@ -901,33 +901,27 @@ innobase_convert_from_table_id(
/**********************************************************************
Check if the length of the identifier exceeds the maximum allowed.
The input to this function is an identifier in charset my_charset_filename.
return true when length of identifier is too long. */
extern "C"
my_bool
innobase_check_identifier_length(
/*=============================*/
const char* id) /* in: identifier to check. it must belong
to charset my_charset_filename */
const char* id) /* in: FK identifier to check excluding the
database portion. */
{
char tmp[MAX_TABLE_NAME_LEN + 10];
uint errors;
uint len;
int well_formed_error = 0;
CHARSET_INFO *cs1 = &my_charset_filename;
CHARSET_INFO *cs2 = thd_charset(current_thd);
CHARSET_INFO *cs = system_charset_info;
DBUG_ENTER("innobase_check_identifier_length");
len = strconvert(cs1, id, cs2, tmp, MAX_TABLE_NAME_LEN + 10, &errors);
uint res = cs->cset->well_formed_len(cs, id, id + strlen(id),
NAME_CHAR_LEN,
&well_formed_error);
uint res = cs2->cset->well_formed_len(cs2, tmp, tmp + len,
NAME_CHAR_LEN,
&well_formed_error);
if (well_formed_error || res != len) {
my_error(ER_TOO_LONG_IDENT, MYF(0), tmp);
return(true);
if (well_formed_error || res == NAME_CHAR_LEN) {
my_error(ER_TOO_LONG_IDENT, MYF(0), id);
DBUG_RETURN(true);
}
return(false);
DBUG_RETURN(false);
}
/**********************************************************************
......@@ -957,17 +951,17 @@ innobase_convert_to_system_charset(
/*===============================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len) /* in: length of 'to', in bytes */
ulint len, /* in: length of 'to', in bytes */
uint* errors) /* out: error return */
{
uint errors;
uint rlen;
CHARSET_INFO* cs1 = &my_charset_filename;
CHARSET_INFO* cs2 = system_charset_info;
rlen = strconvert(cs1, from, cs2, to, len, &errors);
rlen = strconvert(cs1, from, cs2, to, len, errors);
if (errors) {
fprintf(stderr, " InnoDB: There was a problem in converting"
if (*errors) {
fprintf(stderr, "InnoDB: There was a problem in converting"
"'%s' in charset %s to charset %s", from, cs1->name,
cs2->name);
}
......@@ -975,6 +969,32 @@ innobase_convert_to_system_charset(
return(rlen);
}
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset. */
extern "C"
uint
innobase_convert_to_filename_charset(
/*=================================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len) /* in: length of 'to', in bytes */
{
uint errors;
uint rlen;
CHARSET_INFO* cs_to = &my_charset_filename;
CHARSET_INFO* cs_from = system_charset_info;
rlen = strconvert(cs_from, from, cs_to, to, len, &errors);
if (errors) {
fprintf(stderr, "InnoDB: There was a problem in converting"
"'%s' in charset %s to charset %s", from, cs_from->name,
cs_to->name);
}
return(rlen);
}
/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
......
......@@ -19,4 +19,7 @@ typedef struct dict_foreign_struct dict_foreign_t;
typedef struct ind_node_struct ind_node_t;
typedef struct tab_node_struct tab_node_t;
#define TEMP_TABLE_PREFIX "#sql"
#define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX
#endif
......@@ -92,10 +92,19 @@ Converts an identifier from my_charset_filename to UTF-8 charset. */
uint
innobase_convert_to_system_charset(
/*===============================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes */
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len, /* in: length of 'to', in bytes */
uint* errors); /* out: error return */
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset. */
uint
innobase_convert_to_filename_charset(
/*=================================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes */
#endif
#endif
......@@ -33,6 +33,7 @@ Created 9/17/2000 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "m_string.h"
#include "my_sys.h"
#include "ha_prototypes.h"
/* A dummy variable used to fool the compiler */
ibool row_mysql_identically_false = FALSE;
......@@ -3657,6 +3658,7 @@ row_rename_table_for_mysql(
ibool old_is_tmp, new_is_tmp;
pars_info_t* info = NULL;
ulint retry = 0;
DBUG_ENTER("row_rename_table_for_mysql");
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_a(old_name != NULL);
......@@ -3672,7 +3674,7 @@ row_rename_table_for_mysql(
stderr);
trx_commit_for_mysql(trx);
return(DB_ERROR);
DBUG_RETURN(DB_ERROR);
}
if (row_mysql_is_system_table(new_name)) {
......@@ -3685,7 +3687,7 @@ row_rename_table_for_mysql(
new_name);
trx_commit_for_mysql(trx);
return(DB_ERROR);
DBUG_RETURN(DB_ERROR);
}
trx->op_info = "renaming table";
......@@ -3799,12 +3801,29 @@ row_rename_table_for_mysql(
if (!new_is_tmp) {
/* Rename all constraints. */
char new_table_name[MAX_TABLE_NAME_LEN] = "";
uint errors = 0;
info = pars_info_create();
pars_info_add_str_literal(info, "new_table_name", new_name);
pars_info_add_str_literal(info, "old_table_name", old_name);
strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN);
innobase_convert_to_system_charset(
strchr(new_table_name, '/') + 1,
strchr(new_name, '/') +1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* Table name could not be converted from charset
my_charset_filename to UTF-8. This means that the
table name is already in UTF-8 (#mysql#50). */
strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN);
}
pars_info_add_str_literal(info, "new_table_utf8", new_table_name);
err = que_eval_sql(
info,
"PROCEDURE RENAME_CONSTRAINT_IDS () IS\n"
......@@ -3816,6 +3835,7 @@ row_rename_table_for_mysql(
"old_t_name_len INT;\n"
"new_db_name_len INT;\n"
"id_len INT;\n"
"offset INT;\n"
"found INT;\n"
"BEGIN\n"
"found := 1;\n"
......@@ -3824,8 +3844,6 @@ row_rename_table_for_mysql(
"new_db_name := SUBSTR(:new_table_name, 0,\n"
" new_db_name_len);\n"
"old_t_name_len := LENGTH(:old_table_name);\n"
"gen_constr_prefix := CONCAT(:old_table_name,\n"
" '_ibfk_');\n"
"WHILE found = 1 LOOP\n"
" SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n"
......@@ -3842,12 +3860,12 @@ row_rename_table_for_mysql(
" id_len := LENGTH(foreign_id);\n"
" IF (INSTR(foreign_id, '/') > 0) THEN\n"
" IF (INSTR(foreign_id,\n"
" gen_constr_prefix) > 0)\n"
" '_ibfk_') > 0)\n"
" THEN\n"
" offset := INSTR(foreign_id, '_ibfk_') - 1;\n"
" new_foreign_id :=\n"
" CONCAT(:new_table_name,\n"
" SUBSTR(foreign_id, old_t_name_len,\n"
" id_len - old_t_name_len));\n"
" CONCAT(:new_table_utf8,\n"
" SUBSTR(foreign_id, offset, id_len - offset));\n"
" ELSE\n"
" new_foreign_id :=\n"
" CONCAT(new_db_name,\n"
......@@ -4005,7 +4023,7 @@ funct_exit:
trx->op_info = "";
return((int) err);
DBUG_RETURN((int) err);
}
/*************************************************************************
......
......@@ -44,6 +44,21 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0vec.h"
#include "ha_prototypes.h"
/*************************************************************************
Checks if a table name contains the string TEMP_TABLE_PATH_PREFIX which
denotes temporary tables in MySQL. */
static
ibool
row_is_mysql_tmp_table_name(
/*========================*/
/* out: TRUE if temporary table */
const char* name) /* in: table name in the form
'database/tablename' */
{
return(strstr(name, TEMP_TABLE_PATH_PREFIX) != NULL);
}
/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
in the SYS_TABLES system table.
......@@ -1426,26 +1441,47 @@ dict_create_add_foreign_to_dictionary(
{
ulint error;
ulint i;
pars_info_t* info = pars_info_create();
pars_info_t* info;
if (foreign->id == NULL) {
char* stripped_name;
/* Generate a new constraint id */
ulint namelen = strlen(table->name);
char* id = mem_heap_alloc(foreign->heap, namelen + 20);
/* no overflow if number < 1e13 */
sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++);
foreign->id = id;
stripped_name = strchr(foreign->id, '/') + 1;
if (innobase_check_identifier_length(stripped_name)) {
fprintf(stderr, "InnoDB: Generated foreign key "
"name (%s) is too long\n", foreign->id);
return(DB_IDENTIFIER_TOO_LONG);
if (row_is_mysql_tmp_table_name(table->name)) {
sprintf(id, "%s_ibfk_%lu", table->name,
(ulong) (*id_nr)++);
} else {
char table_name[MAX_TABLE_NAME_LEN + 20] = "";
uint errors = 0;
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN + 20);
innobase_convert_to_system_charset(
strchr(table_name, '/') + 1,
strchr(table->name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN + 20);
}
sprintf(id, "%s_ibfk_%lu", table_name,
(ulong) (*id_nr)++);
if (innobase_check_identifier_length(
strchr(id,'/') + 1)) {
return(DB_IDENTIFIER_TOO_LONG);
}
}
foreign->id = id;
}
info = pars_info_create();
pars_info_add_str_literal(info, "id", foreign->id);
pars_info_add_str_literal(info, "for_name", table->name);
......
......@@ -1092,22 +1092,78 @@ dict_table_rename_in_cache(
strcpy(foreign->foreign_table_name, table->name);
if (strchr(foreign->id, '/')) {
/* This is a >= 4.0.18 format id */
ulint db_len;
char* old_id;
char old_name_cs_filename[MAX_TABLE_NAME_LEN+20];
uint errors = 0;
/* All table names are internally stored in charset
my_charset_filename (except the temp tables and the
partition identifier suffix in partition tables). The
foreign key constraint names are internally stored
in UTF-8 charset. The variable fkid here is used
to store foreign key constraint name in charset
my_charset_filename for comparison further below. */
char fkid[MAX_TABLE_NAME_LEN+20];
ibool on_tmp = FALSE;
/* The old table name in my_charset_filename is stored
in old_name_cs_filename */
strncpy(old_name_cs_filename, old_name,
MAX_TABLE_NAME_LEN);
if (strstr(old_name, TEMP_TABLE_PATH_PREFIX) == NULL) {
innobase_convert_to_system_charset(
strchr(old_name_cs_filename, '/') + 1,
strchr(old_name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* There has been an error to convert
old table into UTF-8. This probably
means that the old table name is
actually in UTF-8. */
innobase_convert_to_filename_charset(
strchr(old_name_cs_filename,
'/') + 1,
strchr(old_name, '/') + 1,
MAX_TABLE_NAME_LEN);
} else {
/* Old name already in
my_charset_filename */
strncpy(old_name_cs_filename, old_name,
MAX_TABLE_NAME_LEN);
}
}
/* This is a >= 4.0.18 format id */
strncpy(fkid, foreign->id, MAX_TABLE_NAME_LEN);
if (strstr(fkid, TEMP_TABLE_PATH_PREFIX) == NULL) {
innobase_convert_to_filename_charset(
strchr(fkid, '/') + 1,
strchr(foreign->id, '/') + 1,
MAX_TABLE_NAME_LEN+20);
} else {
on_tmp = TRUE;
}
old_id = mem_strdup(foreign->id);
if (ut_strlen(foreign->id) > ut_strlen(old_name)
if (ut_strlen(fkid) > ut_strlen(old_name_cs_filename)
+ ((sizeof dict_ibfk) - 1)
&& !memcmp(foreign->id, old_name,
ut_strlen(old_name))
&& !memcmp(foreign->id + ut_strlen(old_name),
&& !memcmp(fkid, old_name_cs_filename,
ut_strlen(old_name_cs_filename))
&& !memcmp(fkid + ut_strlen(old_name_cs_filename),
dict_ibfk, (sizeof dict_ibfk) - 1)) {
/* This is a generated >= 4.0.18 format id */
char table_name[MAX_TABLE_NAME_LEN] = "";
uint errors = 0;
if (strlen(table->name) > strlen(old_name)) {
foreign->id = mem_heap_alloc(
foreign->heap,
......@@ -1115,11 +1171,36 @@ dict_table_rename_in_cache(
+ strlen(old_id) + 1);
}
/* Convert the table name to UTF-8 */
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN);
innobase_convert_to_system_charset(
strchr(table_name, '/') + 1,
strchr(table->name, '/') + 1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* Table name could not be converted
from charset my_charset_filename to
UTF-8. This means that the table name
is already in UTF-8 (#mysql#50). */
strncpy(table_name, table->name,
MAX_TABLE_NAME_LEN);
}
/* Replace the prefix 'databasename/tablename'
with the new names */
strcpy(foreign->id, table->name);
strcat(foreign->id,
old_id + ut_strlen(old_name));
strcpy(foreign->id, table_name);
if (on_tmp) {
strcat(foreign->id,
old_id + ut_strlen(old_name));
} else {
sprintf(strchr(foreign->id, '/') + 1,
"%s%s",
strchr(table_name, '/') +1,
strstr(old_id, "_ibfk_") );
}
} else {
/* This is a >= 4.0.18 format id where the user
gave the id name */
......@@ -4602,7 +4683,6 @@ dict_print_info_on_foreign_key_in_create_format(
dict_foreign_t* foreign, /*!< in: foreign key constraint */
ibool add_newline) /*!< in: whether to add a newline */
{
char constraint_name[MAX_TABLE_NAME_LEN];
const char* stripped_id;
ulint i;
......@@ -4624,9 +4704,7 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(" CONSTRAINT ", file);
innobase_convert_from_id(&my_charset_filename, constraint_name,
stripped_id, MAX_TABLE_NAME_LEN);
ut_print_name(file, trx, FALSE, constraint_name);
ut_print_name(file, trx, FALSE, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
......
......@@ -1013,33 +1013,27 @@ innobase_convert_from_table_id(
/**********************************************************************
Check if the length of the identifier exceeds the maximum allowed.
The input to this function is an identifier in charset my_charset_filename.
return true when length of identifier is too long. */
extern "C" UNIV_INTERN
extern "C"
my_bool
innobase_check_identifier_length(
/*=============================*/
const char* id) /* in: identifier to check. it must belong
to charset my_charset_filename */
const char* id) /* in: FK identifier to check excluding the
database portion. */
{
char tmp[MAX_TABLE_NAME_LEN + 10];
uint errors;
uint len;
int well_formed_error = 0;
CHARSET_INFO* cs1 = &my_charset_filename;
CHARSET_INFO* cs2 = thd_charset(current_thd);
len = strconvert(cs1, id, cs2, tmp, MAX_TABLE_NAME_LEN + 10, &errors);
CHARSET_INFO *cs = system_charset_info;
DBUG_ENTER("innobase_check_identifier_length");
uint res = cs2->cset->well_formed_len(cs2, tmp, tmp + len,
NAME_CHAR_LEN,
&well_formed_error);
uint res = cs->cset->well_formed_len(cs, id, id + strlen(id),
NAME_CHAR_LEN,
&well_formed_error);
if (well_formed_error || res != len) {
my_error(ER_TOO_LONG_IDENT, MYF(0), tmp);
return(true);
if (well_formed_error || res == NAME_CHAR_LEN) {
my_error(ER_TOO_LONG_IDENT, MYF(0), id);
DBUG_RETURN(true);
}
return(false);
DBUG_RETURN(false);
}
/******************************************************************//**
......@@ -11614,4 +11608,30 @@ test_innobase_convert_name()
}
}
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset. */
extern "C"
uint
innobase_convert_to_filename_charset(
/*=================================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len) /* in: length of 'to', in bytes */
{
uint errors;
uint rlen;
CHARSET_INFO* cs_to = &my_charset_filename;
CHARSET_INFO* cs_from = system_charset_info;
rlen = strconvert(cs_from, from, cs_to, to, len, &errors);
if (errors) {
fprintf(stderr, "InnoDB: There was a problem in converting"
"'%s' in charset %s to charset %s", from, cs_from->name,
cs_to->name);
}
return(rlen);
}
#endif /* UNIV_COMPILE_TEST_FUNCS */
......@@ -40,4 +40,7 @@ typedef struct tab_node_struct tab_node_t;
#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
#define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO
#define TEMP_TABLE_PREFIX "#sql"
#define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX
#endif
......@@ -279,4 +279,24 @@ innobase_check_identifier_length(
const char* id); /* in: identifier to check. it must belong
to charset my_charset_filename */
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset. */
uint
innobase_convert_to_system_charset(
/*===============================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len, /* in: length of 'to', in bytes */
uint* errors); /* out: error return */
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset. */
uint
innobase_convert_to_filename_charset(
/*=================================*/
char* to, /* out: converted identifier */
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes */
#endif
......@@ -51,6 +51,7 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0sea.h"
#include "fil0fil.h"
#include "ibuf0ibuf.h"
#include "ha_prototypes.h"
#ifdef __WIN__
/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
......@@ -3902,12 +3903,29 @@ row_rename_table_for_mysql(
goto end;
} else if (!new_is_tmp) {
/* Rename all constraints. */
char new_table_name[MAX_TABLE_NAME_LEN] = "";
uint errors = 0;
info = pars_info_create();
pars_info_add_str_literal(info, "new_table_name", new_name);
pars_info_add_str_literal(info, "old_table_name", old_name);
strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN);
innobase_convert_to_system_charset(
strchr(new_table_name, '/') + 1,
strchr(new_name, '/') +1,
MAX_TABLE_NAME_LEN, &errors);
if (errors) {
/* Table name could not be converted from charset
my_charset_filename to UTF-8. This means that the
table name is already in UTF-8 (#mysql#50). */
strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN);
}
pars_info_add_str_literal(info, "new_table_utf8", new_table_name);
err = que_eval_sql(
info,
"PROCEDURE RENAME_CONSTRAINT_IDS () IS\n"
......@@ -3919,6 +3937,7 @@ row_rename_table_for_mysql(
"old_t_name_len INT;\n"
"new_db_name_len INT;\n"
"id_len INT;\n"
"offset INT;\n"
"found INT;\n"
"BEGIN\n"
"found := 1;\n"
......@@ -3927,8 +3946,6 @@ row_rename_table_for_mysql(
"new_db_name := SUBSTR(:new_table_name, 0,\n"
" new_db_name_len);\n"
"old_t_name_len := LENGTH(:old_table_name);\n"
"gen_constr_prefix := CONCAT(:old_table_name,\n"
" '_ibfk_');\n"
"WHILE found = 1 LOOP\n"
" SELECT ID INTO foreign_id\n"
" FROM SYS_FOREIGN\n"
......@@ -3945,12 +3962,13 @@ row_rename_table_for_mysql(
" id_len := LENGTH(foreign_id);\n"
" IF (INSTR(foreign_id, '/') > 0) THEN\n"
" IF (INSTR(foreign_id,\n"
" gen_constr_prefix) > 0)\n"
" '_ibfk_') > 0)\n"
" THEN\n"
" offset := INSTR(foreign_id, '_ibfk_') - 1;\n"
" new_foreign_id :=\n"
" CONCAT(:new_table_name,\n"
" SUBSTR(foreign_id, old_t_name_len,\n"
" id_len - old_t_name_len));\n"
" CONCAT(:new_table_utf8,\n"
" SUBSTR(foreign_id, offset,\n"
" id_len - offset));\n"
" ELSE\n"
" new_foreign_id :=\n"
" CONCAT(new_db_name,\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment