row0mysql.c, pars0pars.c, eval0eval.c, dict0load.c, dict0dict.c, dict0crea.c:

Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
dict0dict.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it; fix also a hang that would occur if one tried in ALTER TABLE or RENAME TABLE to create a foreign key constraint name that collided with another existing name


innobase/dict/dict0crea.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
innobase/dict/dict0load.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
innobase/dict/dict0dict.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it; fix also a hang that would occur if one tried in ALTER TABLE or RENAME TABLE to create a foreign key constraint name that collided with another existing name
innobase/eval/eval0eval.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
innobase/pars/pars0pars.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
innobase/row/row0mysql.c:
  Fix bug #3478: InnoDB's FOREIGN KEY tables treated table and database names as case-insensitive; RENAME TABLE t to T would hang in an endless loop if t had a foreign key constraint defined on it
This commit is contained in:
unknown 2004-10-31 15:43:29 +02:00
commit 61ac832464
6 changed files with 69 additions and 13 deletions

View file

@ -1011,6 +1011,12 @@ dict_create_or_check_foreign_constraint_tables(void)
there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */
/* NOTE: when designing InnoDB's foreign key support in 2001, we made
an error and made the table names and the foreign key id of type
'CHAR' (internally, really a VARCHAR). We should have made the type
VARBINARY, like in other InnoDB system tables, to get a clean
design. */
str = (char *)
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
@ -1227,9 +1233,17 @@ loop:
fputs(".\nA foreign key constraint of name ", ef);
ut_print_name(ef, foreign->id);
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",
ef);
fputs("Note that InnoDB's FOREIGN KEY system tables store\n"
"constraint names as case-insensitive, with the\n"
"MySQL standard latin1_swedish_ci collation. If you\n"
"create tables or databases whose names differ only in\n"
"the character case, then collisions in constraint\n"
"names can occur. Workaround: name your constraints\n"
"explicitly with unique names.\n",
ef);
mutex_exit(&dict_foreign_err_mutex);

View file

@ -132,7 +132,7 @@ dict_index_build_internal_non_clust(
dict_index_t* index); /* in: user representation of a non-clustered
index */
/**************************************************************************
Removes a foreign constraint struct from the dictionet cache. */
Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
@ -581,7 +581,7 @@ dict_table_get_on_id(
dict_table_t* table;
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
|| trx->dict_operation) {
|| trx->dict_operation_lock_mode == RW_X_LATCH) {
/* It is a system table which will always exist in the table
cache: we avoid acquiring the dictionary mutex, because
if we are doing a rollback to handle an error in TABLE

View file

@ -19,6 +19,7 @@ Created 4/24/1996 Heikki Tuuri
#include "mach0data.h"
#include "dict0dict.h"
#include "dict0boot.h"
#include "rem0cmp.h"
/************************************************************************
Finds the first table name in the given database. */
@ -1121,12 +1122,26 @@ loop:
rec = btr_pcur_get_rec(&pcur);
field = rec_get_nth_field(rec, 0, &len);
/* Check if the table name in record is the one searched for */
if (len != ut_strlen(table_name)
|| 0 != ut_memcmp(field, table_name, len)) {
/* Check if the table name in the record is the one searched for; the
following call does the comparison in the latin1_swedish_ci
charset-collation, in a case-insensitive way. */
if (0 != cmp_data_data(dfield_get_type(dfield),
dfield_get_data(dfield), dfield_get_len(dfield),
field, len)) {
goto load_next_index;
}
/* Since table names in SYS_FOREIGN are stored in a case-insensitive
order, we have to check that the table name matches also in a binary
string comparison. On Unix, MySQL allows table names that only differ
in character case. */
if (0 != ut_memcmp(field, table_name, len)) {
goto next_rec;
}
if (rec_get_deleted_flag(rec)) {