Commit 83edf1fc authored by marko's avatar marko

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