mirror of
https://github.com/MariaDB/server.git
synced 2025-01-25 00:04:33 +01:00
Adapt InnoDB to the new tablename to filename encoding in MySQL 5.1.
ut_print_name(), ut_print_namel(): Add parameter table_id for distinguishing names of tables from other identifiers (names of indexes, columns and constraints). innobase_convert_from_table_id(), innobase_convert_from_id(), innobase_convert_from_filename(), innobase_get_charset(): New functions. dict_accept(), dict_scan_id(), dict_scan_col(), dict_scan_table_name(), dict_skip_word(), dict_create_foreign_constraints_low(): Add parameter "cs", so that isspace() can be replaced with my_isspace(), whose operation depends on the connection character set. dict_scan_id(): Convert the identifier to UTF-8. dict_str_starts_with_keyword(): New extern function, to replace dict_accept() in row_search_for_mysql(). mysql_get_identifier_quote_char(): Replaced with innobase_print_identifier(). ha_innobase::create(): Remove the thd->convert_string() call. Pass the statement to InnoDB in the connection character set and let InnoDB convert the identifiers to UTF-8.
This commit is contained in:
parent
d05cf4df80
commit
83edf1fce1
17 changed files with 485 additions and 268 deletions
|
@ -605,9 +605,9 @@ btr_page_get_father_for_rec(
|
|||
buf_page_print(buf_frame_align(node_ptr));
|
||||
|
||||
fputs("InnoDB: Corruption of an index tree: table ", stderr);
|
||||
ut_print_name(stderr, NULL, index->table_name);
|
||||
ut_print_name(stderr, NULL, TRUE, index->table_name);
|
||||
fputs(", index ", stderr);
|
||||
ut_print_name(stderr, NULL, index->name);
|
||||
ut_print_name(stderr, NULL, FALSE, index->name);
|
||||
fprintf(stderr, ",\n"
|
||||
"InnoDB: father ptr page no %lu, child page no %lu\n",
|
||||
(ulong)
|
||||
|
|
|
@ -1250,9 +1250,9 @@ dict_foreign_eval_sql(
|
|||
ut_print_timestamp(ef);
|
||||
fputs(" Error in foreign key constraint creation for table ",
|
||||
ef);
|
||||
ut_print_name(ef, trx, table->name);
|
||||
ut_print_name(ef, trx, TRUE, table->name);
|
||||
fputs(".\nA foreign key constraint of name ", ef);
|
||||
ut_print_name(ef, trx, foreign->id);
|
||||
ut_print_name(ef, trx, FALSE, foreign->id);
|
||||
fputs("\nalready exists."
|
||||
" (Note that internally InnoDB adds 'databasename/'\n"
|
||||
"in front of the user-defined constraint name).\n",
|
||||
|
@ -1280,7 +1280,7 @@ dict_foreign_eval_sql(
|
|||
ut_print_timestamp(ef);
|
||||
fputs(" Internal error in foreign key constraint creation"
|
||||
" for table ", ef);
|
||||
ut_print_name(ef, trx, table->name);
|
||||
ut_print_name(ef, trx, TRUE, table->name);
|
||||
fputs(".\n"
|
||||
"See the MySQL .err log in the datadir for more information.\n", ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
|
319
dict/dict0dict.c
319
dict/dict0dict.c
|
@ -26,6 +26,9 @@ Created 1/8/1996 Heikki Tuuri
|
|||
#include "pars0sym.h"
|
||||
#include "que0que.h"
|
||||
#include "rem0cmp.h"
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
# include "m_ctype.h" /* my_isspace() */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
dict_sys_t* dict_sys = NULL; /* the dictionary system */
|
||||
|
||||
|
@ -55,6 +58,42 @@ static char dict_ibfk[] = "_ibfk_";
|
|||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
extern
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 5 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
extern
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 3 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Removes the filename encoding of a table or database name.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
extern
|
||||
void
|
||||
innobase_convert_from_filename(
|
||||
/*===========================*/
|
||||
char* s); /* in: identifier; out: decoded identifier */
|
||||
/**********************************************************************
|
||||
Compares NUL-terminated UTF-8 strings case insensitively.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
|
@ -77,6 +116,17 @@ void
|
|||
innobase_casedn_str(
|
||||
/*================*/
|
||||
char* a); /* in/out: string to put in lower case */
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd); /* in: MySQL thread handle */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1400,6 +1450,7 @@ dict_index_add_to_cache(
|
|||
|
||||
ut_ad(mem_heap_validate(index->heap));
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
dict_index_t* index2;
|
||||
index2 = UT_LIST_GET_FIRST(table->indexes);
|
||||
|
@ -1409,10 +1460,11 @@ dict_index_add_to_cache(
|
|||
|
||||
index2 = UT_LIST_GET_NEXT(indexes, index2);
|
||||
}
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(table->indexes) == 0
|
||||
|| (index->type & DICT_CLUSTERED) == 0);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_a(!(index->type & DICT_CLUSTERED)
|
||||
|| UT_LIST_GET_LEN(table->indexes) == 0);
|
||||
|
||||
success = dict_index_find_cols(table, index);
|
||||
|
||||
|
@ -2045,6 +2097,7 @@ dict_foreign_find(
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*************************************************************************
|
||||
Tries to find an index whose first fields are the columns in the array,
|
||||
in the same order. */
|
||||
|
@ -2062,7 +2115,6 @@ dict_foreign_find_index(
|
|||
only has an effect if types_idx !=
|
||||
NULL. */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
dict_index_t* index;
|
||||
const char* col_name;
|
||||
ulint i;
|
||||
|
@ -2108,13 +2160,6 @@ dict_foreign_find_index(
|
|||
}
|
||||
|
||||
return(NULL);
|
||||
#else /* UNIV_HOTBACKUP */
|
||||
/* This function depends on MySQL code that is not included in
|
||||
InnoDB Hot Backup builds. Besides, this function should never
|
||||
be called in InnoDB Hot Backup. */
|
||||
ut_error;
|
||||
return(NULL);
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -2150,7 +2195,7 @@ dict_foreign_error_report(
|
|||
putc('\n', file);
|
||||
if (fk->foreign_index) {
|
||||
fputs("The index in the foreign key in table is ", file);
|
||||
ut_print_name(file, NULL, fk->foreign_index->name);
|
||||
ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
|
||||
fputs(
|
||||
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
|
||||
"for correct foreign key definition.\n",
|
||||
|
@ -2313,12 +2358,13 @@ dict_scan_to(
|
|||
|
||||
/*************************************************************************
|
||||
Accepts a specified string. Comparisons are case-insensitive. */
|
||||
|
||||
static
|
||||
const char*
|
||||
dict_accept(
|
||||
/*========*/
|
||||
/* out: if string was accepted, the pointer
|
||||
is moved after that, else ptr is returned */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scan from this */
|
||||
const char* string, /* in: accept only this string as the next
|
||||
non-whitespace string */
|
||||
|
@ -2329,7 +2375,7 @@ dict_accept(
|
|||
|
||||
*success = FALSE;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
@ -2354,12 +2400,15 @@ const char*
|
|||
dict_scan_id(
|
||||
/*=========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
mem_heap_t* heap, /* in: heap where to allocate the id
|
||||
(NULL=id will not be allocated, but it
|
||||
will point to string near ptr) */
|
||||
const char** id, /* out,own: the id; NULL if no id was
|
||||
scannable */
|
||||
ibool table_id,/* in: TRUE=convert the allocated id
|
||||
as a table name; FALSE=convert to UTF-8 */
|
||||
ibool accept_also_dot)
|
||||
/* in: TRUE if also a dot can appear in a
|
||||
non-quoted id; in a quoted id it can appear
|
||||
|
@ -2368,13 +2417,12 @@ dict_scan_id(
|
|||
char quote = '\0';
|
||||
ulint len = 0;
|
||||
const char* s;
|
||||
char* d;
|
||||
ulint id_len;
|
||||
byte* b;
|
||||
char* str;
|
||||
char* dst;
|
||||
|
||||
*id = NULL;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
@ -2405,7 +2453,7 @@ dict_scan_id(
|
|||
len++;
|
||||
}
|
||||
} else {
|
||||
while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'
|
||||
while (!my_isspace(cs, *ptr) && *ptr != '(' && *ptr != ')'
|
||||
&& (accept_also_dot || *ptr != '.')
|
||||
&& *ptr != ',' && *ptr != '\0') {
|
||||
|
||||
|
@ -2415,43 +2463,50 @@ dict_scan_id(
|
|||
len = ptr - s;
|
||||
}
|
||||
|
||||
if (quote && heap) {
|
||||
*id = d = mem_heap_alloc(heap, len + 1);
|
||||
if (UNIV_UNLIKELY(!heap)) {
|
||||
/* no heap given: id will point to source string */
|
||||
*id = s;
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
if (quote) {
|
||||
char* d;
|
||||
str = d = mem_heap_alloc(heap, len + 1);
|
||||
while (len--) {
|
||||
if ((*d++ = *s++) == quote) {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
*d++ = 0;
|
||||
ut_a(*s == quote);
|
||||
ut_a(s + 1 == ptr);
|
||||
} else if (heap) {
|
||||
*id = mem_heap_strdupl(heap, s, len);
|
||||
len = d - str;
|
||||
ut_ad(*s == quote);
|
||||
ut_ad(s + 1 == ptr);
|
||||
} else {
|
||||
/* no heap given: id will point to source string */
|
||||
*id = s;
|
||||
str = mem_heap_strdupl(heap, s, len);
|
||||
}
|
||||
|
||||
if (heap && !quote) {
|
||||
/* EMS MySQL Manager sometimes adds characters 0xA0 (in
|
||||
latin1, a 'non-breakable space') to the end of a table name.
|
||||
But isspace(0xA0) is not true, which confuses our foreign key
|
||||
parser. After the UTF-8 conversion in ha_innodb.cc, bytes 0xC2
|
||||
and 0xA0 are at the end of the string.
|
||||
if (!table_id) {
|
||||
convert_id:
|
||||
/* Convert the identifier from connection character set
|
||||
to UTF-8. */
|
||||
len = 3 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
TODO: we should lex the string using thd->charset_info, and
|
||||
my_isspace(). Only after that, convert id names to UTF-8. */
|
||||
innobase_convert_from_id(dst, str, len);
|
||||
} else if (!strncmp(str, srv_mysql50_table_name_prefix,
|
||||
sizeof srv_mysql50_table_name_prefix)) {
|
||||
/* 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. */
|
||||
str += sizeof srv_mysql50_table_name_prefix;
|
||||
len -= sizeof srv_mysql50_table_name_prefix;
|
||||
goto convert_id;
|
||||
} else {
|
||||
/* Encode using filename-safe characters. */
|
||||
len = 5 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
b = (byte*)(*id);
|
||||
id_len = strlen((char*) b);
|
||||
|
||||
if (id_len >= 3 && b[id_len - 1] == 0xA0
|
||||
&& b[id_len - 2] == 0xC2) {
|
||||
|
||||
/* Strip the 2 last bytes */
|
||||
|
||||
b[id_len - 2] = '\0';
|
||||
}
|
||||
innobase_convert_from_table_id(dst, str, len);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
@ -2464,6 +2519,7 @@ const char*
|
|||
dict_scan_col(
|
||||
/*==========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
ibool* success,/* out: TRUE if success */
|
||||
dict_table_t* table, /* in: table in which the column is */
|
||||
|
@ -2472,13 +2528,12 @@ dict_scan_col(
|
|||
const char** name) /* out,own: the column name; NULL if no name
|
||||
was scannable */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
dict_col_t* col;
|
||||
ulint i;
|
||||
|
||||
*success = FALSE;
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, name, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, name, FALSE, TRUE);
|
||||
|
||||
if (*name == NULL) {
|
||||
|
||||
|
@ -2506,13 +2561,6 @@ dict_scan_col(
|
|||
}
|
||||
|
||||
return(ptr);
|
||||
#else /* UNIV_HOTBACKUP */
|
||||
/* This function depends on MySQL code that is not included in
|
||||
InnoDB Hot Backup builds. Besides, this function should never
|
||||
be called in InnoDB Hot Backup. */
|
||||
ut_error;
|
||||
return(NULL);
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -2522,6 +2570,7 @@ const char*
|
|||
dict_scan_table_name(
|
||||
/*=================*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
dict_table_t** table, /* out: table object or NULL */
|
||||
const char* name, /* in: foreign key table name */
|
||||
|
@ -2530,7 +2579,6 @@ dict_scan_table_name(
|
|||
const char** ref_name)/* out,own: the table name;
|
||||
NULL if no name was scannable */
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
const char* database_name = NULL;
|
||||
ulint database_name_len = 0;
|
||||
const char* table_name = NULL;
|
||||
|
@ -2541,7 +2589,7 @@ dict_scan_table_name(
|
|||
*success = FALSE;
|
||||
*table = NULL;
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, &scan_name, FALSE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, &scan_name, TRUE, FALSE);
|
||||
|
||||
if (scan_name == NULL) {
|
||||
|
||||
|
@ -2556,7 +2604,7 @@ dict_scan_table_name(
|
|||
database_name = scan_name;
|
||||
database_name_len = strlen(database_name);
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, &table_name, FALSE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, &table_name, TRUE, FALSE);
|
||||
|
||||
if (table_name == NULL) {
|
||||
|
||||
|
@ -2611,14 +2659,14 @@ dict_scan_table_name(
|
|||
*ref_name = ref;
|
||||
*table = dict_table_get_low(ref);
|
||||
|
||||
if (!*table) {
|
||||
/* Try to look up the table with UTF-8 encoded name. */
|
||||
|
||||
innobase_convert_from_filename(ref);
|
||||
*table = dict_table_get_low(ref);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
#else /* UNIV_HOTBACKUP */
|
||||
/* This function depends on MySQL code that is not included in
|
||||
InnoDB Hot Backup builds. Besides, this function should never
|
||||
be called in InnoDB Hot Backup. */
|
||||
ut_error;
|
||||
return(NULL);
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -2628,6 +2676,7 @@ const char*
|
|||
dict_skip_word(
|
||||
/*===========*/
|
||||
/* out: scanned to */
|
||||
struct charset_info_st* cs,/* in: the character set of ptr */
|
||||
const char* ptr, /* in: scanned to */
|
||||
ibool* success)/* out: TRUE if success, FALSE if just spaces
|
||||
left in string or a syntax error */
|
||||
|
@ -2636,7 +2685,7 @@ dict_skip_word(
|
|||
|
||||
*success = FALSE;
|
||||
|
||||
ptr = dict_scan_id(ptr, NULL, &start, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, NULL, &start, FALSE, TRUE);
|
||||
|
||||
if (start) {
|
||||
*success = TRUE;
|
||||
|
@ -2814,6 +2863,7 @@ dict_create_foreign_constraints_low(
|
|||
/* out: error code or DB_SUCCESS */
|
||||
trx_t* trx, /* in: transaction */
|
||||
mem_heap_t* heap, /* in: memory heap */
|
||||
struct charset_info_st* cs,/* in: the character set of sql_string */
|
||||
const char* sql_string,
|
||||
/* in: CREATE TABLE or ALTER TABLE statement
|
||||
where foreign keys are declared like:
|
||||
|
@ -2871,14 +2921,14 @@ dict_create_foreign_constraints_low(
|
|||
/* First check if we are actually doing an ALTER TABLE, and in that
|
||||
case look for the table being altered */
|
||||
|
||||
ptr = dict_accept(ptr, "ALTER", &success);
|
||||
ptr = dict_accept(cs, ptr, "ALTER", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "TABLE", &success);
|
||||
ptr = dict_accept(cs, ptr, "TABLE", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
|
@ -2887,7 +2937,7 @@ dict_create_foreign_constraints_low(
|
|||
|
||||
/* We are doing an ALTER TABLE: scan the table name we are altering */
|
||||
|
||||
ptr = dict_scan_table_name(ptr, &table_to_alter, name,
|
||||
ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
|
||||
&success, heap, &referenced_table_name);
|
||||
if (!success) {
|
||||
fprintf(stderr,
|
||||
|
@ -2927,21 +2977,22 @@ loop:
|
|||
of the constraint to system tables. */
|
||||
ptr = ptr1;
|
||||
|
||||
ptr = dict_accept(ptr, "CONSTRAINT", &success);
|
||||
ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
|
||||
|
||||
ut_a(success);
|
||||
|
||||
if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') {
|
||||
if (!my_isspace(cs, *ptr) && *ptr != '"' && *ptr != '`') {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
while (my_isspace(cs, *ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* read constraint name unless got "CONSTRAINT FOREIGN" */
|
||||
if (ptr != ptr2) {
|
||||
ptr = dict_scan_id(ptr, heap, &constraint_name, FALSE);
|
||||
ptr = dict_scan_id(cs, ptr, heap,
|
||||
&constraint_name, FALSE, FALSE);
|
||||
}
|
||||
} else {
|
||||
ptr = ptr2;
|
||||
|
@ -2971,28 +3022,28 @@ loop:
|
|||
|
||||
start_of_latest_foreign = ptr;
|
||||
|
||||
ptr = dict_accept(ptr, "FOREIGN", &success);
|
||||
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
|
||||
|
||||
if (!success) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (!isspace(*ptr)) {
|
||||
if (!my_isspace(cs, *ptr)) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "KEY", &success);
|
||||
ptr = dict_accept(cs, ptr, "KEY", &success);
|
||||
|
||||
if (!success) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
/* MySQL allows also an index id before the '('; we
|
||||
skip it */
|
||||
ptr = dict_skip_word(ptr, &success);
|
||||
ptr = dict_skip_word(cs, ptr, &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_report_syntax_err(name,
|
||||
|
@ -3001,7 +3052,7 @@ loop:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
/* We do not flag a syntax error here because in an
|
||||
|
@ -3016,7 +3067,7 @@ loop:
|
|||
/* Scan the columns in the first list */
|
||||
col_loop1:
|
||||
ut_a(i < (sizeof column_names) / sizeof *column_names);
|
||||
ptr = dict_scan_col(ptr, &success, table, columns + i,
|
||||
ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
|
||||
heap, column_names + i);
|
||||
if (!success) {
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
|
@ -3030,13 +3081,13 @@ col_loop1:
|
|||
|
||||
i++;
|
||||
|
||||
ptr = dict_accept(ptr, ",", &success);
|
||||
ptr = dict_accept(cs, ptr, ",", &success);
|
||||
|
||||
if (success) {
|
||||
goto col_loop1;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ")", &success);
|
||||
ptr = dict_accept(cs, ptr, ")", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||
|
@ -3053,7 +3104,7 @@ col_loop1:
|
|||
mutex_enter(&dict_foreign_err_mutex);
|
||||
dict_foreign_error_report_low(ef, name);
|
||||
fputs("There is no index in table ", ef);
|
||||
ut_print_name(ef, NULL, name);
|
||||
ut_print_name(ef, NULL, TRUE, name);
|
||||
fprintf(ef, " where the columns appear\n"
|
||||
"as the first columns. Constraint:\n%s\n"
|
||||
"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
|
||||
|
@ -3063,9 +3114,9 @@ col_loop1:
|
|||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
ptr = dict_accept(ptr, "REFERENCES", &success);
|
||||
ptr = dict_accept(cs, ptr, "REFERENCES", &success);
|
||||
|
||||
if (!success || !isspace(*ptr)) {
|
||||
if (!success || !my_isspace(cs, *ptr)) {
|
||||
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
|
||||
ptr);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
|
@ -3105,7 +3156,7 @@ col_loop1:
|
|||
mem_heap_strdup(foreign->heap, columns[i]->name);
|
||||
}
|
||||
|
||||
ptr = dict_scan_table_name(ptr, &referenced_table, name,
|
||||
ptr = dict_scan_table_name(cs, ptr, &referenced_table, name,
|
||||
&success, heap, &referenced_table_name);
|
||||
|
||||
/* Note that referenced_table can be NULL if the user has suppressed
|
||||
|
@ -3124,7 +3175,7 @@ col_loop1:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "(", &success);
|
||||
ptr = dict_accept(cs, ptr, "(", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3137,7 +3188,7 @@ col_loop1:
|
|||
i = 0;
|
||||
|
||||
col_loop2:
|
||||
ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
|
||||
ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
|
||||
heap, column_names + i);
|
||||
i++;
|
||||
|
||||
|
@ -3154,13 +3205,13 @@ col_loop2:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ",", &success);
|
||||
ptr = dict_accept(cs, ptr, ",", &success);
|
||||
|
||||
if (success) {
|
||||
goto col_loop2;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, ")", &success);
|
||||
ptr = dict_accept(cs, ptr, ")", &success);
|
||||
|
||||
if (!success || foreign->n_fields != i) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3176,17 +3227,17 @@ col_loop2:
|
|||
scan_on_conditions:
|
||||
/* Loop here as long as we can find ON ... conditions */
|
||||
|
||||
ptr = dict_accept(ptr, "ON", &success);
|
||||
ptr = dict_accept(cs, ptr, "ON", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "DELETE", &success);
|
||||
ptr = dict_accept(cs, ptr, "DELETE", &success);
|
||||
|
||||
if (!success) {
|
||||
ptr = dict_accept(ptr, "UPDATE", &success);
|
||||
ptr = dict_accept(cs, ptr, "UPDATE", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3203,13 +3254,13 @@ scan_on_conditions:
|
|||
n_on_deletes++;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "RESTRICT", &success);
|
||||
ptr = dict_accept(cs, ptr, "RESTRICT", &success);
|
||||
|
||||
if (success) {
|
||||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "CASCADE", &success);
|
||||
ptr = dict_accept(cs, ptr, "CASCADE", &success);
|
||||
|
||||
if (success) {
|
||||
if (is_on_delete) {
|
||||
|
@ -3221,10 +3272,10 @@ scan_on_conditions:
|
|||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NO", &success);
|
||||
ptr = dict_accept(cs, ptr, "NO", &success);
|
||||
|
||||
if (success) {
|
||||
ptr = dict_accept(ptr, "ACTION", &success);
|
||||
ptr = dict_accept(cs, ptr, "ACTION", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3243,7 +3294,7 @@ scan_on_conditions:
|
|||
goto scan_on_conditions;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "SET", &success);
|
||||
ptr = dict_accept(cs, ptr, "SET", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3252,7 +3303,7 @@ scan_on_conditions:
|
|||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NULL", &success);
|
||||
ptr = dict_accept(cs, ptr, "NULL", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
@ -3362,6 +3413,25 @@ try_find_index:
|
|||
goto loop;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines whether a string starts with the specified keyword. */
|
||||
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
/* out: TRUE if str starts
|
||||
with keyword */
|
||||
void* mysql_thd, /* in: MySQL thread handle */
|
||||
const char* str, /* in: string to scan for keyword */
|
||||
const char* keyword) /* in: keyword to look for */
|
||||
{
|
||||
struct charset_info_st* cs = innobase_get_charset(mysql_thd);
|
||||
ibool success;
|
||||
|
||||
dict_accept(cs, str, keyword, &success);
|
||||
return(success);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Scans a table create SQL string and adds to the data dictionary the foreign
|
||||
key constraints declared in the string. This function should be called after
|
||||
|
@ -3393,11 +3463,14 @@ dict_create_foreign_constraints(
|
|||
ulint err;
|
||||
mem_heap_t* heap;
|
||||
|
||||
ut_a(trx && trx->mysql_thd);
|
||||
|
||||
str = dict_strip_comments(sql_string);
|
||||
heap = mem_heap_create(10000);
|
||||
|
||||
err = dict_create_foreign_constraints_low(trx, heap, str, name,
|
||||
reject_fks);
|
||||
err = dict_create_foreign_constraints_low(trx, heap,
|
||||
innobase_get_charset(trx->mysql_thd),
|
||||
str, name, reject_fks);
|
||||
|
||||
mem_heap_free(heap);
|
||||
mem_free(str);
|
||||
|
@ -3430,6 +3503,11 @@ dict_foreign_parse_drop_constraints(
|
|||
const char* ptr;
|
||||
const char* id;
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
struct charset_info_st* cs;
|
||||
|
||||
ut_a(trx && trx->mysql_thd);
|
||||
|
||||
cs = innobase_get_charset(trx->mysql_thd);
|
||||
|
||||
*n = 0;
|
||||
|
||||
|
@ -3450,28 +3528,28 @@ loop:
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "DROP", &success);
|
||||
ptr = dict_accept(cs, ptr, "DROP", &success);
|
||||
|
||||
if (!isspace(*ptr)) {
|
||||
if (!my_isspace(cs, *ptr)) {
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "FOREIGN", &success);
|
||||
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "KEY", &success);
|
||||
ptr = dict_accept(cs, ptr, "KEY", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto syntax_error;
|
||||
}
|
||||
|
||||
ptr = dict_scan_id(ptr, heap, &id, TRUE);
|
||||
ptr = dict_scan_id(cs, ptr, heap, &id, FALSE, TRUE);
|
||||
|
||||
if (id == NULL) {
|
||||
|
||||
|
@ -3504,12 +3582,12 @@ loop:
|
|||
ut_print_timestamp(ef);
|
||||
fputs(
|
||||
" Error in dropping of a foreign key constraint of table ", ef);
|
||||
ut_print_name(ef, NULL, table->name);
|
||||
ut_print_name(ef, NULL, TRUE, table->name);
|
||||
fputs(",\n"
|
||||
"in SQL command\n", ef);
|
||||
fputs(str, ef);
|
||||
fputs("\nCannot find a constraint with the given id ", ef);
|
||||
ut_print_name(ef, NULL, id);
|
||||
ut_print_name(ef, NULL, FALSE, id);
|
||||
fputs(".\n", ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -3526,7 +3604,7 @@ syntax_error:
|
|||
ut_print_timestamp(ef);
|
||||
fputs(
|
||||
" Syntax error in dropping of a foreign key constraint of table ", ef);
|
||||
ut_print_name(ef, NULL, table->name);
|
||||
ut_print_name(ef, NULL, TRUE, table->name);
|
||||
fprintf(ef, ",\n"
|
||||
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
@ -3535,6 +3613,7 @@ syntax_error:
|
|||
|
||||
return(DB_CANNOT_DROP_CONSTRAINT);
|
||||
}
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
|
||||
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
|
||||
|
||||
|
@ -4185,11 +4264,11 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
}
|
||||
|
||||
fputs(" CONSTRAINT ", file);
|
||||
ut_print_name(file, trx, stripped_id);
|
||||
ut_print_name(file, trx, FALSE, stripped_id);
|
||||
fputs(" FOREIGN KEY (", file);
|
||||
|
||||
for (i = 0;;) {
|
||||
ut_print_name(file, trx, foreign->foreign_col_names[i]);
|
||||
ut_print_name(file, trx, FALSE, foreign->foreign_col_names[i]);
|
||||
if (++i < foreign->n_fields) {
|
||||
fputs(", ", file);
|
||||
} else {
|
||||
|
@ -4202,7 +4281,7 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
if (dict_tables_have_same_db(foreign->foreign_table_name,
|
||||
foreign->referenced_table_name)) {
|
||||
/* Do not print the database name of the referenced table */
|
||||
ut_print_name(file, trx, dict_remove_db_name(
|
||||
ut_print_name(file, trx, TRUE, dict_remove_db_name(
|
||||
foreign->referenced_table_name));
|
||||
} else {
|
||||
/* Look for the '/' in the table name */
|
||||
|
@ -4212,9 +4291,10 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
i++;
|
||||
}
|
||||
|
||||
ut_print_namel(file, trx, foreign->referenced_table_name, i);
|
||||
ut_print_namel(file, trx, TRUE,
|
||||
foreign->referenced_table_name, i);
|
||||
putc('.', file);
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, TRUE,
|
||||
foreign->referenced_table_name + i + 1);
|
||||
}
|
||||
|
||||
|
@ -4222,7 +4302,8 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||
putc('(', file);
|
||||
|
||||
for (i = 0;;) {
|
||||
ut_print_name(file, trx, foreign->referenced_col_names[i]);
|
||||
ut_print_name(file, trx, FALSE,
|
||||
foreign->referenced_col_names[i]);
|
||||
if (++i < foreign->n_fields) {
|
||||
fputs(", ", file);
|
||||
} else {
|
||||
|
@ -4296,12 +4377,12 @@ dict_print_info_on_foreign_keys(
|
|||
putc(' ', file);
|
||||
}
|
||||
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, FALSE,
|
||||
foreign->foreign_col_names[i]);
|
||||
}
|
||||
|
||||
fputs(") REFER ", file);
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, TRUE,
|
||||
foreign->referenced_table_name);
|
||||
putc('(', file);
|
||||
|
||||
|
@ -4309,7 +4390,7 @@ dict_print_info_on_foreign_keys(
|
|||
if (i) {
|
||||
putc(' ', file);
|
||||
}
|
||||
ut_print_name(file, trx,
|
||||
ut_print_name(file, trx, FALSE,
|
||||
foreign->referenced_col_names[i]);
|
||||
}
|
||||
|
||||
|
@ -4356,7 +4437,7 @@ dict_index_name_print(
|
|||
const dict_index_t* index) /* in: index to print */
|
||||
{
|
||||
fputs("index ", file);
|
||||
ut_print_name(file, trx, index->name);
|
||||
ut_print_name(file, trx, FALSE, index->name);
|
||||
fputs(" of table ", file);
|
||||
ut_print_name(file, trx, index->table_name);
|
||||
ut_print_name(file, trx, TRUE, index->table_name);
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ loop:
|
|||
|
||||
if (table == NULL) {
|
||||
fputs("InnoDB: Failed to load table ", stderr);
|
||||
ut_print_namel(stderr, NULL, (char*) field, len);
|
||||
ut_print_namel(stderr, NULL, TRUE, (char*) field, len);
|
||||
putc('\n', stderr);
|
||||
} else {
|
||||
/* The table definition was corrupt if there
|
||||
|
|
|
@ -706,6 +706,61 @@ innobase_get_cset_width(
|
|||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
extern "C"
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
{
|
||||
uint errors;
|
||||
|
||||
strconvert(current_thd->charset(), from,
|
||||
&my_charset_filename, to, len, &errors);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
extern "C"
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
{
|
||||
uint errors;
|
||||
|
||||
strconvert(current_thd->charset(), from,
|
||||
system_charset_info, to, len, &errors);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Removes the filename encoding of a table or database name.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
extern "C"
|
||||
void
|
||||
innobase_convert_from_filename(
|
||||
/*===========================*/
|
||||
char* s) /* in: identifier; out: decoded identifier */
|
||||
{
|
||||
uint errors;
|
||||
|
||||
strconvert(&my_charset_filename, s,
|
||||
system_charset_info, s, strlen(s), &errors);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Compares NUL-terminated UTF-8 strings case insensitively.
|
||||
|
||||
|
@ -736,6 +791,21 @@ innobase_casedn_str(
|
|||
my_casedn_str(system_charset_info, a);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
extern "C"
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd) /* in: MySQL thread handle */
|
||||
{
|
||||
return(((THD*) mysql_thd)->charset());
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Creates a temporary file. */
|
||||
extern "C"
|
||||
|
@ -1135,23 +1205,70 @@ innobase_invalidate_query_cache(
|
|||
}
|
||||
|
||||
/*********************************************************************
|
||||
Get the quote character to be used in SQL identifiers.
|
||||
Display an SQL identifier.
|
||||
This definition must match the one in innobase/ut/ut0ut.c! */
|
||||
extern "C"
|
||||
int
|
||||
mysql_get_identifier_quote_char(
|
||||
/*============================*/
|
||||
/* out: quote character to be
|
||||
used in SQL identifiers; EOF if none */
|
||||
void
|
||||
innobase_print_identifier(
|
||||
/*======================*/
|
||||
FILE* f, /* in: output stream */
|
||||
trx_t* trx, /* in: transaction */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name, /* in: name to print */
|
||||
ulint namelen)/* in: length of name */
|
||||
{
|
||||
if (!trx || !trx->mysql_thd) {
|
||||
return(EOF);
|
||||
const char* s = name;
|
||||
char* qname = NULL;
|
||||
int q;
|
||||
|
||||
if (table_id) {
|
||||
/* Decode the table name. The filename_to_tablename()
|
||||
function expects a NUL-terminated string. The input and
|
||||
output strings buffers must not be shared. The function
|
||||
only produces more output when the name contains other
|
||||
characters than [0-9A-Z_a-z]. */
|
||||
char* temp_name = my_malloc(namelen + 1, MYF(MY_WME));
|
||||
uint qnamelen = namelen
|
||||
+ (1 + sizeof srv_mysql50_table_name_prefix);
|
||||
|
||||
if (temp_name) {
|
||||
qname = my_malloc(qnamelen, MYF(MY_WME));
|
||||
if (qname) {
|
||||
memcpy(temp_name, name, namelen);
|
||||
temp_name[namelen] = 0;
|
||||
s = qname;
|
||||
namelen = filename_to_tablename(temp_name,
|
||||
qname, qnamelen);
|
||||
}
|
||||
return(get_quote_char_for_identifier((THD*) trx->mysql_thd,
|
||||
name, (int) namelen));
|
||||
my_free(temp_name, MYF(0));
|
||||
}
|
||||
}
|
||||
|
||||
if (!trx || !trx->mysql_thd) {
|
||||
|
||||
q = '"';
|
||||
} else {
|
||||
/* TODO: convert from UTF-8 to trx->mysql_thd->charset() ? */
|
||||
q = get_quote_char_for_identifier((THD*) trx->mysql_thd,
|
||||
s, (int) namelen);
|
||||
}
|
||||
|
||||
if (q == EOF) {
|
||||
fwrite(s, 1, namelen, f);
|
||||
} else {
|
||||
const char* e = s + namelen;
|
||||
putc(q, f);
|
||||
while (s < e) {
|
||||
int c = *s++;
|
||||
if (c == q) {
|
||||
putc(c, f);
|
||||
}
|
||||
putc(c, f);
|
||||
}
|
||||
putc(q, f);
|
||||
}
|
||||
|
||||
my_free(qname, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1267,6 +1384,24 @@ innobase_init(void)
|
|||
|
||||
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
static const char test_filename[] = "-@";
|
||||
char test_tablename[sizeof test_filename
|
||||
+ sizeof srv_mysql50_table_name_prefix];
|
||||
if ((sizeof test_tablename) - 1
|
||||
!= filename_to_tablename(test_filename, test_tablename,
|
||||
sizeof test_tablename)
|
||||
|| strncmp(test_tablename,
|
||||
srv_mysql50_table_name_prefix,
|
||||
sizeof srv_mysql50_table_name_prefix)
|
||||
|| strcmp(test_tablename
|
||||
+ sizeof srv_mysql50_table_name_prefix,
|
||||
test_filename)) {
|
||||
sql_print_error("tablename encoding has been changed");
|
||||
goto error;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/* Check that values don't overflow on 32-bit systems. */
|
||||
if (sizeof(ulint) == 4) {
|
||||
if (innobase_buffer_pool_size > UINT_MAX32) {
|
||||
|
@ -4690,7 +4825,7 @@ ha_innobase::create(
|
|||
/* Get the transaction associated with the current thd, or create one
|
||||
if not yet created */
|
||||
|
||||
parent_trx = check_trx_exists(current_thd);
|
||||
parent_trx = check_trx_exists(thd);
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
@ -4786,20 +4921,9 @@ ha_innobase::create(
|
|||
}
|
||||
}
|
||||
|
||||
if (current_thd->query != NULL) {
|
||||
LEX_STRING q;
|
||||
|
||||
if (thd->convert_string(&q, system_charset_info,
|
||||
current_thd->query,
|
||||
current_thd->query_length,
|
||||
current_thd->charset())) {
|
||||
error = HA_ERR_OUT_OF_MEM;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (thd->query != NULL) {
|
||||
error = row_table_add_foreign_constraints(trx,
|
||||
q.str, norm_name,
|
||||
thd->query, norm_name,
|
||||
create_info->options & HA_LEX_CREATE_TMP_TABLE);
|
||||
|
||||
error = convert_error_code_to_mysql(error, NULL);
|
||||
|
@ -4955,7 +5079,7 @@ ha_innobase::delete_table(
|
|||
/* Get the transaction associated with the current thd, or create one
|
||||
if not yet created */
|
||||
|
||||
parent_trx = check_trx_exists(current_thd);
|
||||
parent_trx = check_trx_exists(thd);
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||
possible adaptive hash latch to avoid deadlocks of threads */
|
||||
|
|
|
@ -44,18 +44,6 @@ dict_get_db_name_len(
|
|||
/* out: database name length */
|
||||
const char* name); /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
/*************************************************************************
|
||||
Accepts a specified string. Comparisons are case-insensitive. */
|
||||
|
||||
const char*
|
||||
dict_accept(
|
||||
/*========*/
|
||||
/* out: if string was accepted, the pointer
|
||||
is moved after that, else ptr is returned */
|
||||
const char* ptr, /* in: scan from this */
|
||||
const char* string, /* in: accept only this string as the next
|
||||
non-whitespace string */
|
||||
ibool* success);/* out: TRUE if accepted */
|
||||
/************************************************************************
|
||||
Decrements the count of open MySQL handles to a table. */
|
||||
|
||||
|
@ -219,6 +207,17 @@ dict_table_referenced_by_foreign_key(
|
|||
/* out: TRUE if table is referenced by a
|
||||
foreign key */
|
||||
dict_table_t* table); /* in: InnoDB table */
|
||||
/**************************************************************************
|
||||
Determines whether a string starts with the specified keyword. */
|
||||
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
/* out: TRUE if str starts
|
||||
with keyword */
|
||||
void* mysql_thd, /* in: MySQL thread handle */
|
||||
const char* str, /* in: string to scan for keyword */
|
||||
const char* keyword); /* in: keyword to look for */
|
||||
/*************************************************************************
|
||||
Scans a table create SQL string and adds to the data dictionary
|
||||
the foreign key constraints declared in the string. This function
|
||||
|
|
|
@ -18,6 +18,9 @@ Created 10/10/1995 Heikki Tuuri
|
|||
|
||||
extern const char* srv_main_thread_op_info;
|
||||
|
||||
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
|
||||
extern const char srv_mysql50_table_name_prefix[9];
|
||||
|
||||
/* When this event is set the lock timeout and InnoDB monitor
|
||||
thread starts running */
|
||||
extern os_event_t srv_lock_timeout_thread_event;
|
||||
|
|
|
@ -224,6 +224,7 @@ ut_print_name(
|
|||
/*==========*/
|
||||
FILE* f, /* in: output stream */
|
||||
struct trx_struct*trx, /* in: transaction */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name); /* in: name to print */
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -234,6 +235,7 @@ ut_print_namel(
|
|||
/*===========*/
|
||||
FILE* f, /* in: output stream */
|
||||
struct trx_struct*trx, /* in: transaction (NULL=no quotes) */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name, /* in: name to print */
|
||||
ulint namelen);/* in: length of name */
|
||||
|
||||
|
|
|
@ -1860,7 +1860,7 @@ lock_rec_enqueue_waiting(
|
|||
fputs(
|
||||
" InnoDB: Error: a record lock wait happens in a dictionary operation!\n"
|
||||
"InnoDB: Table name ", stderr);
|
||||
ut_print_name(stderr, trx, index->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, index->table_name);
|
||||
fputs(".\n"
|
||||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
|
||||
stderr);
|
||||
|
@ -1899,7 +1899,7 @@ lock_rec_enqueue_waiting(
|
|||
if (lock_print_waits) {
|
||||
fprintf(stderr, "Lock wait for trx %lu in index ",
|
||||
(ulong) ut_dulint_get_low(trx->id));
|
||||
ut_print_name(stderr, trx, index->name);
|
||||
ut_print_name(stderr, trx, FALSE, index->name);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
@ -3555,7 +3555,7 @@ lock_table_enqueue_waiting(
|
|||
fputs(
|
||||
" InnoDB: Error: a table lock wait happens in a dictionary operation!\n"
|
||||
"InnoDB: Table name ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(".\n"
|
||||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
|
||||
stderr);
|
||||
|
@ -4074,7 +4074,8 @@ lock_table_print(
|
|||
ut_a(lock_get_type(lock) == LOCK_TABLE);
|
||||
|
||||
fputs("TABLE LOCK table ", file);
|
||||
ut_print_name(file, lock->trx, lock->un_member.tab_lock.table->name);
|
||||
ut_print_name(file, lock->trx, TRUE,
|
||||
lock->un_member.tab_lock.table->name);
|
||||
fprintf(file, " trx id %lu %lu",
|
||||
(ulong) (lock->trx)->id.high, (ulong) (lock->trx)->id.low);
|
||||
|
||||
|
|
|
@ -601,7 +601,7 @@ row_ins_set_detailed(
|
|||
rewind(srv_misc_tmpfile);
|
||||
|
||||
if (os_file_set_eof(srv_misc_tmpfile)) {
|
||||
ut_print_name(srv_misc_tmpfile, trx,
|
||||
ut_print_name(srv_misc_tmpfile, trx, TRUE,
|
||||
foreign->foreign_table_name);
|
||||
dict_print_info_on_foreign_key_in_create_format(
|
||||
srv_misc_tmpfile,
|
||||
|
@ -643,22 +643,22 @@ row_ins_foreign_report_err(
|
|||
trx_print(ef, trx, 600);
|
||||
|
||||
fputs("Foreign key constraint fails for table ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
fputs(":\n", ef);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||
TRUE);
|
||||
putc('\n', ef);
|
||||
fputs(errstr, ef);
|
||||
fputs(" in parent table, in index ", ef);
|
||||
ut_print_name(ef, trx, foreign->referenced_index->name);
|
||||
ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
|
||||
if (entry) {
|
||||
fputs(" tuple:\n", ef);
|
||||
dtuple_print(ef, entry);
|
||||
}
|
||||
fputs("\nBut in child table ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
fputs(", in index ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||
ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
|
||||
if (rec) {
|
||||
fputs(", there is a record:\n", ef);
|
||||
rec_print(ef, rec, foreign->foreign_index);
|
||||
|
@ -696,20 +696,20 @@ row_ins_foreign_report_add_err(
|
|||
fputs(" Transaction:\n", ef);
|
||||
trx_print(ef, trx, 600);
|
||||
fputs("Foreign key constraint fails for table ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
fputs(":\n", ef);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||
TRUE);
|
||||
fputs("\nTrying to add in child table, in index ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||
ut_print_name(ef, trx, FALSE, foreign->foreign_index->name);
|
||||
if (entry) {
|
||||
fputs(" tuple:\n", ef);
|
||||
dtuple_print(ef, entry);
|
||||
}
|
||||
fputs("\nBut in parent table ", ef);
|
||||
ut_print_name(ef, trx, foreign->referenced_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->referenced_table_name);
|
||||
fputs(", in index ", ef);
|
||||
ut_print_name(ef, trx, foreign->referenced_index->name);
|
||||
ut_print_name(ef, trx, FALSE, foreign->referenced_index->name);
|
||||
fputs(",\nthe closest match we can find is record:\n", ef);
|
||||
if (rec && page_rec_is_supremum(rec)) {
|
||||
/* If the cursor ended on a supremum record, it is better
|
||||
|
@ -1277,16 +1277,19 @@ run_again:
|
|||
fputs(" Transaction:\n", ef);
|
||||
trx_print(ef, trx, 600);
|
||||
fputs("Foreign key constraint fails for table ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE,
|
||||
foreign->foreign_table_name);
|
||||
fputs(":\n", ef);
|
||||
dict_print_info_on_foreign_key_in_create_format(ef,
|
||||
trx, foreign, TRUE);
|
||||
fputs("\nTrying to add to index ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||
ut_print_name(ef, trx, FALSE,
|
||||
foreign->foreign_index->name);
|
||||
fputs(" tuple:\n", ef);
|
||||
dtuple_print(ef, entry);
|
||||
fputs("\nBut the parent table ", ef);
|
||||
ut_print_name(ef, trx, foreign->referenced_table_name);
|
||||
ut_print_name(ef, trx, TRUE,
|
||||
foreign->referenced_table_name);
|
||||
fputs("\nor its .ibd file does not currently exist!\n", ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
|
|
@ -680,7 +680,7 @@ row_prebuilt_free(
|
|||
"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name",
|
||||
(ulong) prebuilt->magic_n,
|
||||
(ulong) prebuilt->magic_n2);
|
||||
ut_print_name(stderr, NULL, prebuilt->table->name);
|
||||
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -773,7 +773,7 @@ row_update_prebuilt_trx(
|
|||
"InnoDB: Error: trying to use a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, NULL, prebuilt->table->name);
|
||||
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1094,7 +1094,8 @@ row_insert_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, prebuilt->trx, prebuilt->table->name);
|
||||
ut_print_name(stderr, prebuilt->trx, TRUE,
|
||||
prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1329,7 +1330,8 @@ row_update_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, prebuilt->trx, prebuilt->table->name);
|
||||
ut_print_name(stderr, prebuilt->trx, TRUE,
|
||||
prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -1941,7 +1943,7 @@ row_create_table_for_mysql(
|
|||
|
||||
fputs(" InnoDB: Warning: cannot create table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(" because tablespace full\n", stderr);
|
||||
|
||||
if (dict_table_get_low(table->name)) {
|
||||
|
@ -1954,7 +1956,7 @@ row_create_table_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(" already exists in InnoDB internal\n"
|
||||
"InnoDB: data dictionary. Have you deleted the .frm file\n"
|
||||
"InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
|
||||
|
@ -2031,7 +2033,7 @@ row_create_index_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: column ", stderr);
|
||||
ut_print_name(stderr, trx,
|
||||
ut_print_name(stderr, trx, FALSE,
|
||||
dict_index_get_nth_field(index, i)->name);
|
||||
fputs(" appears twice in ", stderr);
|
||||
dict_index_name_print(stderr, trx, index);
|
||||
|
@ -2196,7 +2198,7 @@ row_drop_table_for_mysql_in_background(
|
|||
trx->check_foreigns = FALSE;
|
||||
|
||||
/* fputs("InnoDB: Error: Dropping table ", stderr);
|
||||
ut_print_name(stderr, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs(" in background drop list\n", stderr); */
|
||||
|
||||
/* Try to drop the table in InnoDB */
|
||||
|
@ -2360,7 +2362,7 @@ row_add_table_to_background_drop_list(
|
|||
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
|
||||
|
||||
/* fputs("InnoDB: Adding table ", stderr);
|
||||
ut_print_name(stderr, drop->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, drop->table_name);
|
||||
fputs(" to background drop list\n", stderr); */
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
@ -2429,7 +2431,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
if (table->space == 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: is in the system tablespace 0 which cannot be discarded\n", stderr);
|
||||
err = DB_ERROR;
|
||||
|
@ -2441,7 +2443,7 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: You are trying to DISCARD table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there is a foreign key check running on it.\n"
|
||||
"InnoDB: Cannot discard the table.\n",
|
||||
|
@ -2475,10 +2477,10 @@ do not allow the discard. We also reserve the data dictionary latch. */
|
|||
ut_print_timestamp(ef);
|
||||
|
||||
fputs(" Cannot DISCARD table ", ef);
|
||||
ut_print_name(ef, trx, name);
|
||||
ut_print_name(ef, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"because it is referenced by ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
putc('\n', ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -2590,7 +2592,7 @@ row_import_tablespace_for_mysql(
|
|||
if (!success) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: cannot reset lsn's in table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n", stderr);
|
||||
|
||||
|
@ -2611,7 +2613,7 @@ row_import_tablespace_for_mysql(
|
|||
if (!table) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: does not exist in the InnoDB data dictionary\n"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
|
||||
|
@ -2625,7 +2627,7 @@ row_import_tablespace_for_mysql(
|
|||
if (table->space == 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: is in the system tablespace 0 which cannot be imported\n", stderr);
|
||||
err = DB_ERROR;
|
||||
|
@ -2638,7 +2640,7 @@ row_import_tablespace_for_mysql(
|
|||
fputs(
|
||||
" InnoDB: Error: you are trying to IMPORT a tablespace\n"
|
||||
"InnoDB: ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs(", though you have not called DISCARD on it yet\n"
|
||||
"InnoDB: during the lifetime of the mysqld process!\n", stderr);
|
||||
|
||||
|
@ -2663,7 +2665,7 @@ row_import_tablespace_for_mysql(
|
|||
fputs(
|
||||
" InnoDB: cannot find or open in the database directory the .ibd file of\n"
|
||||
"InnoDB: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: in ALTER TABLE ... IMPORT TABLESPACE\n",
|
||||
stderr);
|
||||
|
@ -2783,10 +2785,10 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
|||
ut_print_timestamp(ef);
|
||||
|
||||
fputs(" Cannot truncate table ", ef);
|
||||
ut_print_name(ef, trx, table->name);
|
||||
ut_print_name(ef, trx, TRUE, table->name);
|
||||
fputs(" by DROP+CREATE\n"
|
||||
"InnoDB: because it is referenced by ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
putc('\n', ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -2803,7 +2805,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
|||
if (table->n_foreign_key_checks_running > 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Cannot truncate table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(" by DROP+CREATE\n"
|
||||
"InnoDB: because there is a foreign key check running on it.\n",
|
||||
stderr);
|
||||
|
@ -2918,7 +2920,7 @@ do not allow the TRUNCATE. We also reserve the data dictionary latch. */
|
|||
trx->error_state = DB_SUCCESS;
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Unable to assign a new identifier to table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: after truncating it. Background processes may corrupt the table!\n",
|
||||
stderr);
|
||||
|
@ -3045,7 +3047,7 @@ row_drop_table_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs(" does not exist in the InnoDB internal\n"
|
||||
"InnoDB: data dictionary though MySQL is trying to drop it.\n"
|
||||
"InnoDB: Have you copied the .frm file of the table to the\n"
|
||||
|
@ -3081,10 +3083,10 @@ row_drop_table_for_mysql(
|
|||
ut_print_timestamp(ef);
|
||||
|
||||
fputs(" Cannot drop table ", ef);
|
||||
ut_print_name(ef, trx, name);
|
||||
ut_print_name(ef, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"because it is referenced by ", ef);
|
||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
|
||||
putc('\n', ef);
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
|
||||
|
@ -3103,7 +3105,7 @@ row_drop_table_for_mysql(
|
|||
if (added) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there are still open handles to it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
|
@ -3136,7 +3138,7 @@ fputs(" InnoDB: Warning: MySQL is trying to drop table ", stderr);
|
|||
if (added) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: You are trying to drop table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there is a foreign key check running on it.\n"
|
||||
"InnoDB: Adding the table to the background drop queue.\n",
|
||||
|
@ -3259,7 +3261,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: not able to remove table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs(" from the dictionary cache!\n", stderr);
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
@ -3277,7 +3279,7 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
fprintf(stderr,
|
||||
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
|
||||
"InnoDB: of table ");
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fprintf(stderr, ".\n");
|
||||
|
||||
goto funct_exit;
|
||||
|
@ -3289,14 +3291,14 @@ fputs(" InnoDB: You are trying to drop table ", stderr);
|
|||
fprintf(stderr,
|
||||
"InnoDB: We removed now the InnoDB internal data dictionary entry\n"
|
||||
"InnoDB: of table ");
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fprintf(stderr, ".\n");
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: not able to delete tablespace %lu of table ",
|
||||
(ulong) space_id);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("!\n", stderr);
|
||||
err = DB_ERROR;
|
||||
}
|
||||
|
@ -3364,10 +3366,10 @@ loop:
|
|||
ut_print_timestamp(stderr);
|
||||
fputs(
|
||||
" InnoDB: Warning: MySQL is trying to drop database ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fputs("\n"
|
||||
"InnoDB: though there are still open handles to table ", stderr);
|
||||
ut_print_name(stderr, trx, table_name);
|
||||
ut_print_name(stderr, trx, TRUE, table_name);
|
||||
fputs(".\n", stderr);
|
||||
|
||||
os_thread_sleep(1000000);
|
||||
|
@ -3383,10 +3385,10 @@ loop:
|
|||
|
||||
if (err != DB_SUCCESS) {
|
||||
fputs("InnoDB: DROP DATABASE ", stderr);
|
||||
ut_print_name(stderr, trx, name);
|
||||
ut_print_name(stderr, trx, TRUE, name);
|
||||
fprintf(stderr, " failed with error %lu for table ",
|
||||
(ulint) err);
|
||||
ut_print_name(stderr, trx, table_name);
|
||||
ut_print_name(stderr, trx, TRUE, table_name);
|
||||
putc('\n', stderr);
|
||||
break;
|
||||
}
|
||||
|
@ -3543,7 +3545,7 @@ row_rename_table_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(" does not exist in the InnoDB internal\n"
|
||||
"InnoDB: data dictionary though MySQL is trying to rename the table.\n"
|
||||
"InnoDB: Have you copied the .frm file of the table to the\n"
|
||||
|
@ -3559,7 +3561,7 @@ row_rename_table_for_mysql(
|
|||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: table ", stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(
|
||||
" does not have an .ibd file in the database directory.\n"
|
||||
"InnoDB: You can look for further help from\n"
|
||||
|
@ -3704,17 +3706,17 @@ end:
|
|||
"InnoDB: 1) Table rename would cause two FOREIGN KEY constraints\n"
|
||||
"InnoDB: to have the same internal name in case-insensitive comparison.\n"
|
||||
"InnoDB: 2) table ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs(" exists in the InnoDB internal data\n"
|
||||
"InnoDB: dictionary though MySQL is trying rename table ", stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(" to it.\n"
|
||||
"InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n"
|
||||
"InnoDB: You can look for further help from\n"
|
||||
"InnoDB: http://dev.mysql.com/doc/mysql/en/"
|
||||
"InnoDB_troubleshooting_datadict.html\n"
|
||||
"InnoDB: If table ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs(
|
||||
" is a temporary table #sql..., then it can be that\n"
|
||||
"InnoDB: there are still queries running on the table, and it will be\n"
|
||||
|
@ -3742,9 +3744,9 @@ end:
|
|||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error in table rename, cannot rename ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, old_name);
|
||||
ut_print_name(stderr, trx, TRUE, old_name);
|
||||
fputs(" to ", stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
putc('\n', stderr);
|
||||
err = DB_ERROR;
|
||||
|
||||
|
@ -3763,7 +3765,7 @@ end:
|
|||
if (old_is_tmp) {
|
||||
fputs(" InnoDB: Error: in ALTER TABLE ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs("\n"
|
||||
"InnoDB: has or is referenced in foreign key constraints\n"
|
||||
"InnoDB: which are not compatible with the new table definition.\n",
|
||||
|
@ -3772,7 +3774,7 @@ end:
|
|||
fputs(
|
||||
" InnoDB: Error: in RENAME TABLE table ",
|
||||
stderr);
|
||||
ut_print_name(stderr, trx, new_name);
|
||||
ut_print_name(stderr, trx, TRUE, new_name);
|
||||
fputs("\n"
|
||||
"InnoDB: is referenced in foreign key constraints\n"
|
||||
"InnoDB: which are not compatible with the new table definition.\n",
|
||||
|
@ -3986,7 +3988,7 @@ row_check_table_for_mysql(
|
|||
|
||||
while (index != NULL) {
|
||||
/* fputs("Validating index ", stderr);
|
||||
ut_print_name(stderr, index->name);
|
||||
ut_print_name(stderr, trx, FALSE, index->name);
|
||||
putc('\n', stderr); */
|
||||
|
||||
if (!btr_validate_tree(index->tree, prebuilt->trx)) {
|
||||
|
|
|
@ -480,12 +480,12 @@ row_build_row_ref_in_tuple(
|
|||
|
||||
ut_a(ref && index && rec);
|
||||
|
||||
if (!index->table) {
|
||||
if (UNIV_UNLIKELY(!index->table)) {
|
||||
fputs("InnoDB: table ", stderr);
|
||||
notfound:
|
||||
ut_print_name(stderr, trx, index->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, index->table_name);
|
||||
fputs(" for index ", stderr);
|
||||
ut_print_name(stderr, trx, index->name);
|
||||
ut_print_name(stderr, trx, FALSE, index->name);
|
||||
fputs(" not found\n", stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
|
|
@ -3248,7 +3248,7 @@ row_search_for_mysql(
|
|||
"InnoDB: Error: trying to free a corrupt\n"
|
||||
"InnoDB: table handle. Magic n %lu, table name ",
|
||||
(ulong) prebuilt->magic_n);
|
||||
ut_print_name(stderr, trx, prebuilt->table->name);
|
||||
ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
|
||||
putc('\n', stderr);
|
||||
|
||||
mem_analyze_corruption(prebuilt);
|
||||
|
@ -3534,15 +3534,13 @@ shortcut_fails_too_big_rec:
|
|||
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& trx->mysql_query_str) {
|
||||
&& trx->mysql_query_str && trx->mysql_thd) {
|
||||
|
||||
/* Scan the MySQL query string; check if SELECT is the first
|
||||
word there */
|
||||
ibool success;
|
||||
|
||||
dict_accept(*trx->mysql_query_str, "SELECT", &success);
|
||||
|
||||
if (success) {
|
||||
if (dict_str_starts_with_keyword(trx->mysql_thd,
|
||||
*trx->mysql_query_str, "SELECT")) {
|
||||
/* It is a plain locking SELECT and the isolation
|
||||
level is low: do not lock gaps */
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ ibool srv_error_monitor_active = FALSE;
|
|||
|
||||
const char* srv_main_thread_op_info = "";
|
||||
|
||||
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
|
||||
const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
|
||||
|
||||
/* Server parameters which are read from the initfile */
|
||||
|
||||
/* The following three are dir paths which are catenated before file
|
||||
|
|
|
@ -843,7 +843,7 @@ trx_undo_update_rec_get_update(
|
|||
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n"
|
||||
"InnoDB: Run also CHECK TABLE ",
|
||||
(ulong) dict_index_get_n_fields(index));
|
||||
ut_print_name(stderr, trx, index->table_name);
|
||||
ut_print_name(stderr, trx, TRUE, index->table_name);
|
||||
fprintf(stderr, "\n"
|
||||
"InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
|
||||
(ulong) n_fields, (ulong) i, ptr);
|
||||
|
|
|
@ -241,7 +241,7 @@ trx_rollback_to_savepoint_for_mysql(
|
|||
if (trx->conc_state == TRX_NOT_STARTED) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Error: transaction has a savepoint ", stderr);
|
||||
ut_print_name(stderr, trx, savep->name);
|
||||
ut_print_name(stderr, trx, FALSE, savep->name);
|
||||
fputs(" though it is not started\n", stderr);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ loop:
|
|||
|
||||
if (table) {
|
||||
fputs("InnoDB: Table found: dropping table ", stderr);
|
||||
ut_print_name(stderr, trx, table->name);
|
||||
ut_print_name(stderr, trx, TRUE, table->name);
|
||||
fputs(" in recovery\n", stderr);
|
||||
|
||||
err = row_drop_table_for_mysql(table->name, trx, TRUE);
|
||||
|
|
49
ut/ut0ut.c
49
ut/ut0ut.c
|
@ -20,18 +20,20 @@ Created 5/11/1994 Heikki Tuuri
|
|||
|
||||
ibool ut_always_false = FALSE;
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*********************************************************************
|
||||
Get the quote character to be used in SQL identifiers.
|
||||
Display an SQL identifier.
|
||||
This definition must match the one in sql/ha_innodb.cc! */
|
||||
extern
|
||||
int
|
||||
mysql_get_identifier_quote_char(
|
||||
/*============================*/
|
||||
/* out: quote character to be
|
||||
used in SQL identifiers; EOF if none */
|
||||
void
|
||||
innobase_print_identifier(
|
||||
/*======================*/
|
||||
FILE* f, /* in: output stream */
|
||||
trx_t* trx, /* in: transaction */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name, /* in: name to print */
|
||||
ulint namelen);/* in: length of name */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/************************************************************
|
||||
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
|
||||
|
@ -398,9 +400,10 @@ ut_print_name(
|
|||
/*==========*/
|
||||
FILE* f, /* in: output stream */
|
||||
trx_t* trx, /* in: transaction */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name) /* in: name to print */
|
||||
{
|
||||
ut_print_namel(f, trx, name, strlen(name));
|
||||
ut_print_namel(f, trx, table_id, name, strlen(name));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -411,29 +414,27 @@ ut_print_namel(
|
|||
/*===========*/
|
||||
FILE* f, /* in: output stream */
|
||||
trx_t* trx, /* in: transaction (NULL=no quotes) */
|
||||
ibool table_id,/* in: TRUE=decode table name */
|
||||
const char* name, /* in: name to print */
|
||||
ulint namelen)/* in: length of name */
|
||||
{
|
||||
const char* s = name;
|
||||
const char* e = s + namelen;
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
int q = '"';
|
||||
#else
|
||||
int q = mysql_get_identifier_quote_char(trx, name, namelen);
|
||||
#endif
|
||||
if (q == EOF) {
|
||||
fwrite(name, 1, namelen, f);
|
||||
return;
|
||||
#else
|
||||
char* slash = strchr(name, '/');
|
||||
|
||||
if (UNIV_LIKELY_NULL(slash)) {
|
||||
/* Print the database name and table name separately. */
|
||||
ut_ad(table_id);
|
||||
|
||||
innobase_print_identifier(f, trx, TRUE, name, slash - name);
|
||||
putc('.', f);
|
||||
innobase_print_identifier(f, trx, TRUE, slash + 1,
|
||||
namelen - (slash - name) - 1);
|
||||
} else {
|
||||
innobase_print_identifier(f, trx, table_id, name, namelen);
|
||||
}
|
||||
putc(q, f);
|
||||
while (s < e) {
|
||||
int c = *s++;
|
||||
if (c == q) {
|
||||
putc(c, f);
|
||||
}
|
||||
putc(c, f);
|
||||
}
|
||||
putc(q, f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
Loading…
Add table
Reference in a new issue