Commit 85ccc78f 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 5fbd0192
......@@ -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);
......
......@@ -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;
}
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.
TODO: we should lex the string using thd->charset_info, and
my_isspace(). Only after that, convert id names to UTF-8. */
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 */
str = mem_heap_strdupl(heap, s, len);
}
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);
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[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 */
{
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) {
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,
name, (int) namelen));
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);
......
......@@ -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;
}
putc(q, f);
while (s < e) {
int c = *s++;
if (c == q) {
putc(c, f);
}
putc(c, f);
#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);
#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