diff options
author | unknown <heikki@hundin.mysql.fi> | 2004-10-31 15:43:29 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2004-10-31 15:43:29 +0200 |
commit | 61ac832464a48afcf85f8c302734aa01d4346c78 (patch) | |
tree | b1dc2682b042c48923623d30c4590faa4b4b8fd8 /innobase/dict | |
parent | 99b76e6bf41d5fb08cb25bc2005885633cf6e323 (diff) | |
download | mariadb-git-61ac832464a48afcf85f8c302734aa01d4346c78.tar.gz |
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
Diffstat (limited to 'innobase/dict')
-rw-r--r-- | innobase/dict/dict0crea.c | 16 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 4 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 21 |
3 files changed, 35 insertions, 6 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 31a601e68b0..e8261ab1e91 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -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); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 4340934ab3d..5ca31ecd422 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -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 diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 6a4d4c86824..a4637e09d07 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -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)) { |