summaryrefslogtreecommitdiff
path: root/innobase/dict/dict0dict.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/dict/dict0dict.c')
-rw-r--r--innobase/dict/dict0dict.c210
1 files changed, 123 insertions, 87 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index eeefd7bf1ae..c3d0d8d9ac1 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -53,6 +53,30 @@ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
/* Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
+/**********************************************************************
+Compares NUL-terminated UTF-8 strings case insensitively.
+
+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
+int
+innobase_strcasecmp(
+/*================*/
+ /* out: 0 if a=b, <0 if a<b, >1 if a>b */
+ const char* a, /* in: first string to compare */
+ const char* b); /* in: second string to compare */
+
+/**********************************************************************
+Makes all characters in a NUL-terminated UTF-8 string lower case.
+
+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_casedn_str(
+/*================*/
+ char* a); /* in/out: string to put in lower case */
+
/**************************************************************************
Adds a column to the data dictionary hash table. */
static
@@ -527,8 +551,10 @@ dict_index_contains_col_or_prefix(
}
/************************************************************************
-Looks for a matching field in an index. The column and the prefix len have
-to be the same. */
+Looks for a matching field in an index. The column has to be the same. The
+column in index must be complete, or must contain a prefix longer than the
+column in index2. That is, we must be able to construct the prefix in index2
+from the prefix in index. */
ulint
dict_index_get_nth_field_pos(
@@ -556,7 +582,9 @@ dict_index_get_nth_field_pos(
field = dict_index_get_nth_field(index, pos);
if (field->col == field2->col
- && field->prefix_len == field2->prefix_len) {
+ && (field->prefix_len == 0
+ || (field->prefix_len >= field2->prefix_len
+ && field2->prefix_len != 0))) {
return(pos);
}
@@ -939,8 +967,16 @@ dict_table_rename_in_cache(
.ibd file */
if (table->space != 0) {
- success = fil_rename_tablespace(table->name, table->space,
- new_name);
+ if (table->dir_path_of_temp_table != NULL) {
+ fprintf(stderr,
+"InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n"
+"InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table);
+ success = FALSE;
+ } else {
+ success = fil_rename_tablespace(table->name,
+ table->space, new_name);
+ }
+
if (!success) {
return(FALSE);
@@ -2054,7 +2090,7 @@ dict_foreign_find_index(
break;
}
- if (0 != ut_cmp_in_lower_case(columns[i],
+ if (0 != innobase_strcasecmp(columns[i],
col_name)) {
break;
}
@@ -2085,14 +2121,14 @@ Report an error in a foreign key definition. */
static
void
dict_foreign_error_report_low(
+/*==========================*/
FILE* file, /* in: output stream */
const char* name) /* in: table name */
{
rewind(file);
ut_print_timestamp(file);
- fputs(" Error in foreign key constraint of table ", file);
- ut_print_name(file, name);
- fputs(":\n", file);
+ fprintf(file, " Error in foreign key constraint of table %s:\n",
+ name);
}
/**************************************************************************
@@ -2100,6 +2136,7 @@ Report an error in a foreign key definition. */
static
void
dict_foreign_error_report(
+/*======================*/
FILE* file, /* in: output stream */
dict_foreign_t* fk, /* in: foreign key constraint */
const char* msg) /* in: the error message */
@@ -2108,12 +2145,13 @@ dict_foreign_error_report(
dict_foreign_error_report_low(file, fk->foreign_table_name);
fputs(msg, file);
fputs(" Constraint:\n", file);
- dict_print_info_on_foreign_key_in_create_format(file, fk);
+ dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
if (fk->foreign_index) {
fputs("\nThe index in the foreign key in table is ", file);
- ut_print_name(file, fk->foreign_index->name);
+ ut_print_name(file, NULL, fk->foreign_index->name);
fputs(
-"See http://www.innodb.com/ibman.php for correct foreign key definition.\n",
+"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
+"for correct foreign key definition.\n",
file);
}
mutex_exit(&dict_foreign_err_mutex);
@@ -2230,7 +2268,7 @@ dict_foreign_add_to_cache(
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity. Stops
also at '\0'. */
-static
+
const char*
dict_scan_to(
/*=========*/
@@ -2422,7 +2460,7 @@ dict_scan_col(
col = dict_table_get_nth_col(table, i);
- if (0 == ut_cmp_in_lower_case(col->name, *name)) {
+ if (0 == innobase_strcasecmp(col->name, *name)) {
/* Found */
*success = TRUE;
@@ -2514,30 +2552,19 @@ dict_scan_table_name(
table_name_len = strlen(table_name);
+ /* Copy database_name, '/', table_name, '\0' */
ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2);
-
-#ifdef __WIN__
- ut_cpy_in_lower_case(ref, database_name, database_name_len);
-#else
+ memcpy(ref, database_name, database_name_len);
+ ref[database_name_len] = '/';
+ memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
+#ifndef __WIN__
if (srv_lower_case_table_names) {
- ut_cpy_in_lower_case(ref, database_name, database_name_len);
- } else {
- memcpy(ref, database_name, database_name_len);
+#endif /* !__WIN__ */
+ /* The table name is always put to lower case on Windows. */
+ innobase_casedn_str(ref);
+#ifndef __WIN__
}
-#endif
- (ref)[database_name_len] = '/';
-
-#ifdef __WIN__
- ut_cpy_in_lower_case(ref + database_name_len + 1,
- table_name, table_name_len + 1);
-#else
- if (srv_lower_case_table_names) {
- ut_cpy_in_lower_case(ref + database_name_len + 1,
- table_name, table_name_len + 1);
- } else {
- strcpy(ref + database_name_len + 1, table_name);
- }
-#endif
+#endif /* !__WIN__ */
*success = TRUE;
*ref_name = ref;
@@ -2588,7 +2615,9 @@ dict_strip_comments(
char* str;
const char* sptr;
char* ptr;
-
+ /* unclosed quote character (0 if none) */
+ char quote = 0;
+
str = mem_alloc(strlen(sql_string) + 1);
sptr = sql_string;
@@ -2603,8 +2632,18 @@ scan_more:
return(str);
}
-
- if (*sptr == '#'
+
+ if (*sptr == quote) {
+ /* Closing quote character: do not look for
+ starting quote or comments. */
+ quote = 0;
+ } else if (quote) {
+ /* Within quotes: do not look for
+ starting quotes or comments. */
+ } else if (*sptr == '"' || *sptr == '`') {
+ /* Starting quote: remember the quote character. */
+ quote = *sptr;
+ } else if (*sptr == '#'
|| (0 == memcmp("-- ", sptr, 3))) {
for (;;) {
/* In Unix a newline is 0x0A while in Windows
@@ -2619,9 +2658,7 @@ scan_more:
sptr++;
}
- }
-
- if (*sptr == '/' && *(sptr + 1) == '*') {
+ } else if (!quote && *sptr == '/' && *(sptr + 1) == '*') {
for (;;) {
if (*sptr == '*' && *(sptr + 1) == '/') {
@@ -2946,10 +2983,11 @@ 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, name);
+ ut_print_name(ef, NULL, name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
-"See http://www.innodb.com/ibman.php for correct foreign key definition.\n",
+"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
+"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3214,7 +3252,8 @@ try_find_index:
"Cannot find an index in the referenced table where the\n"
"referenced columns appear as the first columns, or column types\n"
"in the table and the referenced table do not match for constraint.\n"
-"See http://www.innodb.com/ibman.php for correct foreign key definition.\n",
+"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
+"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3389,12 +3428,12 @@ loop:
ut_print_timestamp(ef);
fputs(
" Error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, NULL, 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, id);
+ ut_print_name(ef, NULL, id);
fputs(".\n", ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -3411,7 +3450,7 @@ syntax_error:
ut_print_timestamp(ef);
fputs(
" Syntax error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, NULL, table->name);
fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex);
@@ -3818,9 +3857,11 @@ dict_update_statistics_low(
if (table->ibd_file_missing) {
ut_print_timestamp(stderr);
fprintf(stderr,
-" InnoDB: cannot calculate statistics for table %s\n"
-"InnoDB: because the .ibd file is missing. See section 15.1 of\n"
-"InnoDB: http:/www.innodb.com/ibman.html for help\n", table->name);
+ " InnoDB: cannot calculate statistics for table %s\n"
+"InnoDB: because the .ibd file is missing. For help, please refer to\n"
+"InnoDB: "
+"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n",
+ table->name);
return;
}
@@ -3906,25 +3947,19 @@ dict_foreign_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- fputs(" FOREIGN KEY CONSTRAINT ", stderr);
- ut_print_name(stderr, foreign->id);
- fputs(": ", stderr);
- ut_print_name(stderr, foreign->foreign_table_name);
- fputs(" (", stderr);
+ fprintf(stderr, " FOREIGN KEY CONSTRAINT %s: %s (",
+ foreign->id, foreign->foreign_table_name);
for (i = 0; i < foreign->n_fields; i++) {
- putc(' ', stderr);
- ut_print_name(stderr, foreign->foreign_col_names[i]);
+ fprintf(stderr, " %s", foreign->foreign_col_names[i]);
}
- fputs(" )\n"
- " REFERENCES ", stderr);
- ut_print_name(stderr, foreign->referenced_table_name);
- fputs(" (", stderr);
+ fprintf(stderr, " )\n"
+ " REFERENCES %s (",
+ foreign->referenced_table_name);
for (i = 0; i < foreign->n_fields; i++) {
- putc(' ', stderr);
- ut_print_name(stderr, foreign->referenced_col_names[i]);
+ fprintf(stderr, " %s", foreign->referenced_col_names[i]);
}
fputs(" )\n", stderr);
@@ -3981,12 +4016,11 @@ dict_table_print_low(
dict_update_statistics_low(table, TRUE);
- fputs("--------------------------------------\n"
- "TABLE: name ", stderr);
- ut_print_name(stderr, table->name);
fprintf(stderr,
- ", id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
- " COLUMNS: ",
+"--------------------------------------\n"
+"TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
+" COLUMNS: ",
+ table->name,
(ulong) ut_dulint_get_high(table->id),
(ulong) ut_dulint_get_low(table->id),
(ulong) table->n_cols,
@@ -4037,8 +4071,7 @@ dict_col_print_low(
#endif /* UNIV_SYNC_DEBUG */
type = dict_col_get_type(col);
- ut_print_name(stderr, col->name);
- fputs(": ", stderr);
+ fprintf(stderr, "%s: ", col->name);
dtype_print(type);
}
@@ -4068,13 +4101,12 @@ dict_index_print_low(
n_vals = index->stat_n_diff_key_vals[1];
}
- fputs(" INDEX: ", stderr);
- dict_index_name_print(stderr, index);
fprintf(stderr,
- ", id %lu %lu, fields %lu/%lu, type %lu\n"
+ " INDEX: name %s, id %lu %lu, fields %lu/%lu, type %lu\n"
" root page %lu, appr.key vals %lu,"
" leaf pages %lu, size pages %lu\n"
" FIELDS: ",
+ index->name,
(ulong) ut_dulint_get_high(tree->id),
(ulong) ut_dulint_get_low(tree->id),
(ulong) index->n_user_defined_cols,
@@ -4106,8 +4138,7 @@ dict_field_print_low(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- putc(' ', stderr);
- ut_print_name(stderr, field->name);
+ fprintf(stderr, " %s", field->name);
if (field->prefix_len != 0) {
fprintf(stderr, "(%lu)", (ulong) field->prefix_len);
@@ -4122,6 +4153,7 @@ void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
dict_foreign_t* foreign)/* in: foreign key constraint */
{
const char* stripped_id;
@@ -4136,11 +4168,11 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(",\n CONSTRAINT ", file);
- ut_print_name(file, stripped_id);
+ ut_print_name(file, trx, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
- ut_print_name(file, foreign->foreign_col_names[i]);
+ ut_print_name(file, trx, foreign->foreign_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4153,7 +4185,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, dict_remove_db_name(
+ ut_print_name(file, trx, dict_remove_db_name(
foreign->referenced_table_name));
} else {
/* Look for the '/' in the table name */
@@ -4163,16 +4195,17 @@ dict_print_info_on_foreign_key_in_create_format(
i++;
}
- ut_print_namel(file, foreign->referenced_table_name, i);
+ ut_print_namel(file, trx, foreign->referenced_table_name, i);
putc('.', file);
- ut_print_name(file, foreign->referenced_table_name + i + 1);
+ ut_print_name(file, trx,
+ foreign->referenced_table_name + i + 1);
}
putc(' ', file);
putc('(', file);
for (i = 0;;) {
- ut_print_name(file, foreign->referenced_col_names[i]);
+ ut_print_name(file, trx, foreign->referenced_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4218,6 +4251,7 @@ dict_print_info_on_foreign_keys(
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
dict_table_t* table) /* in: table */
{
dict_foreign_t* foreign;
@@ -4235,7 +4269,7 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
dict_print_info_on_foreign_key_in_create_format(
- file, foreign);
+ file, trx, foreign);
} else {
ulint i;
fputs("; (", file);
@@ -4245,19 +4279,20 @@ dict_print_info_on_foreign_keys(
putc(' ', file);
}
- ut_print_name(file,
+ ut_print_name(file, trx,
foreign->foreign_col_names[i]);
}
fputs(") REFER ", file);
- ut_print_name(file, foreign->referenced_table_name);
+ ut_print_name(file, trx,
+ foreign->referenced_table_name);
putc('(', file);
for (i = 0; i < foreign->n_fields; i++) {
if (i) {
putc(' ', file);
}
- ut_print_name(file,
+ ut_print_name(file, trx,
foreign->referenced_col_names[i]);
}
@@ -4300,10 +4335,11 @@ void
dict_index_name_print(
/*==================*/
FILE* file, /* in: output stream */
+ trx_t* trx, /* in: transaction */
const dict_index_t* index) /* in: index to print */
{
fputs("index ", file);
- ut_print_name(file, index->name);
+ ut_print_name(file, trx, index->name);
fputs(" of table ", file);
- ut_print_name(file, index->table_name);
+ ut_print_name(file, trx, index->table_name);
}