From: kevin.lewis Date: November 23 2010 9:05pm Subject: bzr commit into mysql-5.5-innodb branch (kevin.lewis:3231) Bug#55222 List-Archive: http://lists.mysql.com/commits/124772 X-Bug: 55222 Message-Id: <20101123210534.3A96378D660@kevin-lewis-macbook.local> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0920308335==" --===============0920308335== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/kevinlewis/Work/Mysql/Bug55222/mysql-5.5-innodb/ based on revid:vasil.dimov@stripped 3231 kevin.lewis@stripped 2010-11-23 Bug#55222 - InnoDB does not attempt to handle lower_case_table_names == 2 when looking up foreign table names and referenced table name. It turned that server vaiable into a boolean and ignored the possibility of it being '2'. lower_case_table_names == 2 means that it should be stored and displayed in mixed case as given, but compared internally in lower case. Normally the server deals with this since it stores table names. But InnoDB stores referential constrainsts for the server, so it need to keep track of both lower case and given names. This solution creates two table name pointers for each foreign and referenced table name. One to display the name, and one to look it up. Both pointers point to the same allocated string unless this setting is 2. So the overhead added is not too much. Two functions are created in dict0mem.c to populate the ..._lookup versions of these pointers. Both dict_mem_set_foreign_table_name_lookup() and dict_mem_set_referenced_table_name_lookup() are called 5 times each. modified: mysql-test/r/lowercase_table4.result mysql-test/suite/innodb/r/innodb_bug57904.result mysql-test/suite/innodb/t/innodb_bug57904.test mysql-test/t/lowercase_table4.test storage/innobase/dict/dict0dict.c storage/innobase/dict/dict0load.c storage/innobase/dict/dict0mem.c storage/innobase/handler/ha_innodb.cc storage/innobase/include/dict0mem.h storage/innobase/include/srv0srv.h storage/innobase/row/row0ins.c storage/innobase/row/row0mysql.c storage/innobase/row/row0upd.c storage/innobase/srv/srv0srv.c === modified file 'mysql-test/r/lowercase_table4.result' --- a/mysql-test/r/lowercase_table4.result revid:vasil.dimov@stripped +++ b/mysql-test/r/lowercase_table4.result revid:kevin.lewis@stripped @@ -5,3 +5,111 @@ CREATE DATABASE XY; USE XY; DROP DATABASE XY; +USE TEST; +# +# Bug55222 Mysqldump table names case bug in REFERENCES clause +# InnoDB did not handle lower_case_table_names=2 for +# foreign_table_names and referenced_table_names. +# +SHOW VARIABLES LIKE 'lower_case_table_names'; +Variable_name Value +lower_case_table_names 2 +DROP TABLE IF EXISTS `Table2`; +DROP TABLE IF EXISTS `Table1`; +CREATE TABLE `Table1`(c1 INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE `Table2`(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; +ALTER TABLE `Table2` ADD CONSTRAINT fk1 FOREIGN KEY(c2) REFERENCES `Table1`(c1); +SHOW CREATE TABLE `Table2`; +Table Table2 +Create Table CREATE TABLE `Table2` ( + `c1` int(11) NOT NULL, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `fk1` (`c2`), + CONSTRAINT `fk1` FOREIGN KEY (`c2`) REFERENCES `Table1` (`c1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME fk1 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE RESTRICT +DELETE_RULE RESTRICT +TABLE_NAME Table2 +REFERENCED_TABLE_NAME Table1 +DROP TABLE `Table2`; +DROP TABLE `Table1`; +DROP TABLE IF EXISTS Product_Order; +DROP TABLE IF EXISTS Product; +DROP TABLE IF EXISTS Customer; +CREATE TABLE Product (Category INT NOT NULL, Id INT NOT NULL, +Price DECIMAL, PRIMARY KEY(Category, Id)) ENGINE=InnoDB; +CREATE TABLE Customer (Id INT NOT NULL, PRIMARY KEY (Id)) ENGINE=InnoDB; +CREATE TABLE Product_Order (No INT NOT NULL AUTO_INCREMENT, +Product_Category INT NOT NULL, +Product_Id INT NOT NULL, +Customer_Id INT NOT NULL, +PRIMARY KEY(No), +INDEX (Product_Category, Product_Id), +FOREIGN KEY (Product_Category, Product_Id) +REFERENCES Product(Category, Id) ON UPDATE CASCADE ON DELETE RESTRICT, +INDEX (Customer_Id), +FOREIGN KEY (Customer_Id) +REFERENCES Customer(Id) +) ENGINE=INNODB; +SHOW CREATE TABLE Product_Order; +Table Product_Order +Create Table CREATE TABLE `Product_Order` ( + `No` int(11) NOT NULL AUTO_INCREMENT, + `Product_Category` int(11) NOT NULL, + `Product_Id` int(11) NOT NULL, + `Customer_Id` int(11) NOT NULL, + PRIMARY KEY (`No`), + KEY `Product_Category` (`Product_Category`,`Product_Id`), + KEY `Customer_Id` (`Customer_Id`), + CONSTRAINT `product_order_ibfk_1` FOREIGN KEY (`Product_Category`, `Product_Id`) REFERENCES `Product` (`Category`, `Id`) ON UPDATE CASCADE, + CONSTRAINT `product_order_ibfk_2` FOREIGN KEY (`Customer_Id`) REFERENCES `Customer` (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE Product; +Table Product +Create Table CREATE TABLE `Product` ( + `Category` int(11) NOT NULL, + `Id` int(11) NOT NULL, + `Price` decimal(10,0) DEFAULT NULL, + PRIMARY KEY (`Category`,`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE Customer; +Table Customer +Create Table CREATE TABLE `Customer` ( + `Id` int(11) NOT NULL, + PRIMARY KEY (`Id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_1 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE CASCADE +DELETE_RULE RESTRICT +TABLE_NAME Product_Order +REFERENCED_TABLE_NAME Product +CONSTRAINT_CATALOG def +CONSTRAINT_SCHEMA test +CONSTRAINT_NAME product_order_ibfk_2 +UNIQUE_CONSTRAINT_CATALOG def +UNIQUE_CONSTRAINT_SCHEMA test +UNIQUE_CONSTRAINT_NAME PRIMARY +MATCH_OPTION NONE +UPDATE_RULE RESTRICT +DELETE_RULE RESTRICT +TABLE_NAME Product_Order +REFERENCED_TABLE_NAME Customer +DROP TABLE Product_Order; +DROP TABLE Product; +DROP TABLE Customer; === modified file 'mysql-test/suite/innodb/r/innodb_bug57904.result' --- a/mysql-test/suite/innodb/r/innodb_bug57904.result revid:vasil.dimov@stripped +++ b/mysql-test/suite/innodb/r/innodb_bug57904.result revid:kevin.lewis@stripped @@ -1,16 +1,16 @@ -CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; -CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, -product_category INT NOT NULL, -product_id INT NOT NULL, -customer_id INT NOT NULL, -PRIMARY KEY(no), -INDEX (product_category, product_id), -FOREIGN KEY (product_category, product_id) -REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, -INDEX (customer_id), -FOREIGN KEY (customer_id) +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, +product_category INT NOT NULL, +product_id INT NOT NULL, +customer_id INT NOT NULL, +PRIMARY KEY(no), +INDEX (product_category, product_id), +FOREIGN KEY (product_category, product_id) +REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, +INDEX (customer_id), +FOREIGN KEY (customer_id) REFERENCES customer(id) ) ENGINE=INNODB; SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; === modified file 'mysql-test/suite/innodb/t/innodb_bug57904.test' --- a/mysql-test/suite/innodb/t/innodb_bug57904.test revid:vasil.dimov@stripped +++ b/mysql-test/suite/innodb/t/innodb_bug57904.test revid:kevin.lewis@stripped @@ -3,19 +3,19 @@ # -- source include/have_innodb.inc -CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, +CREATE TABLE product (category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY(category, id)) ENGINE=INNODB; CREATE TABLE customer (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; -CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, - product_category INT NOT NULL, - product_id INT NOT NULL, - customer_id INT NOT NULL, - PRIMARY KEY(no), - INDEX (product_category, product_id), - FOREIGN KEY (product_category, product_id) - REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, - INDEX (customer_id), - FOREIGN KEY (customer_id) +CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT, + product_category INT NOT NULL, + product_id INT NOT NULL, + customer_id INT NOT NULL, + PRIMARY KEY(no), + INDEX (product_category, product_id), + FOREIGN KEY (product_category, product_id) + REFERENCES product(category, id) ON UPDATE CASCADE ON DELETE RESTRICT, + INDEX (customer_id), + FOREIGN KEY (customer_id) REFERENCES customer(id) ) ENGINE=INNODB; === modified file 'mysql-test/t/lowercase_table4.test' --- a/mysql-test/t/lowercase_table4.test revid:vasil.dimov@stripped +++ b/mysql-test/t/lowercase_table4.test revid:kevin.lewis@stripped @@ -53,4 +53,56 @@ eval SELECT * FROM XY.T_$tcs LIMIT 1; --enable_query_log --enable_result_log DROP DATABASE XY; +USE TEST; + +--echo # +--echo # Bug55222 Mysqldump table names case bug in REFERENCES clause +--echo # InnoDB did not handle lower_case_table_names=2 for +--echo # foreign_table_names and referenced_table_names. +--echo # + +SHOW VARIABLES LIKE 'lower_case_table_names'; + +--disable_warnings +DROP TABLE IF EXISTS `Table2`; +DROP TABLE IF EXISTS `Table1`; +--disable_warnings + +CREATE TABLE `Table1`(c1 INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE `Table2`(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; +ALTER TABLE `Table2` ADD CONSTRAINT fk1 FOREIGN KEY(c2) REFERENCES `Table1`(c1); +query_vertical SHOW CREATE TABLE `Table2`; +query_vertical SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +DROP TABLE `Table2`; +DROP TABLE `Table1`; + +--disable_warnings +DROP TABLE IF EXISTS Product_Order; +DROP TABLE IF EXISTS Product; +DROP TABLE IF EXISTS Customer; +--enable_warnings + +CREATE TABLE Product (Category INT NOT NULL, Id INT NOT NULL, + Price DECIMAL, PRIMARY KEY(Category, Id)) ENGINE=InnoDB; +CREATE TABLE Customer (Id INT NOT NULL, PRIMARY KEY (Id)) ENGINE=InnoDB; +CREATE TABLE Product_Order (No INT NOT NULL AUTO_INCREMENT, + Product_Category INT NOT NULL, + Product_Id INT NOT NULL, + Customer_Id INT NOT NULL, + PRIMARY KEY(No), + INDEX (Product_Category, Product_Id), + FOREIGN KEY (Product_Category, Product_Id) + REFERENCES Product(Category, Id) ON UPDATE CASCADE ON DELETE RESTRICT, + INDEX (Customer_Id), + FOREIGN KEY (Customer_Id) + REFERENCES Customer(Id) + ) ENGINE=INNODB; + +query_vertical SHOW CREATE TABLE Product_Order; +query_vertical SHOW CREATE TABLE Product; +query_vertical SHOW CREATE TABLE Customer; +query_vertical SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS; +DROP TABLE Product_Order; +DROP TABLE Product; +DROP TABLE Customer; === modified file 'storage/innobase/dict/dict0dict.c' --- a/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped +++ b/storage/innobase/dict/dict0dict.c revid:kevin.lewis@stripped @@ -52,8 +52,9 @@ UNIV_INTERN dict_index_t* dict_ind_compa #include "que0que.h" #include "rem0cmp.h" #include "row0merge.h" +#include "srv0srv.h" /* srv_lower_case_table_names */ #include "m_ctype.h" /* my_isspace() */ -#include "ha_prototypes.h" /* innobase_strcasecmp() */ +#include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/ #include @@ -1068,9 +1069,9 @@ dict_table_rename_in_cache( return(TRUE); } - /* Update the table name fields in foreign constraints, and update also - the constraint id of new format >= 4.0.18 constraints. Note that at - this point we have already changed table->name to the new name. */ + /* Update the table name fields in foreign constraints, and update + also the constraint id of new format >= 4.0.18 constraints. Note that + at this point we have already changed table->name to the new name. */ foreign = UT_LIST_GET_FIRST(table->foreign_list); @@ -1080,13 +1081,13 @@ dict_table_rename_in_cache( /* Allocate a longer name buffer; TODO: store buf len to save memory */ - foreign->foreign_table_name - = mem_heap_alloc(foreign->heap, - ut_strlen(table->name) + 1); + foreign->foreign_table_name = mem_heap_strdup( + foreign->heap, table->name); + dict_mem_set_foreign_table_name_lookup(foreign, TRUE); + } else { + strcpy(foreign->foreign_table_name, table->name); + dict_mem_set_foreign_table_name_lookup(foreign, FALSE); } - - strcpy(foreign->foreign_table_name, table->name); - if (strchr(foreign->id, '/')) { ulint db_len; char* old_id; @@ -1152,12 +1153,14 @@ dict_table_rename_in_cache( /* Allocate a longer name buffer; TODO: store buf len to save memory */ - foreign->referenced_table_name = mem_heap_alloc( - foreign->heap, strlen(table->name) + 1); + foreign->referenced_table_name = mem_heap_strdup( + foreign->heap, table->name); + dict_mem_set_referenced_table_name_lookup(foreign, TRUE); + } else { + /* Use the same buffer */ + strcpy(foreign->referenced_table_name, table->name); + dict_mem_set_referenced_table_name_lookup(foreign, FALSE); } - - strcpy(foreign->referenced_table_name, table->name); - foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } @@ -2583,10 +2586,10 @@ dict_foreign_add_to_cache( ut_ad(mutex_own(&(dict_sys->mutex))); for_table = dict_table_check_if_in_cache_low( - foreign->foreign_table_name); + foreign->foreign_table_name_lookup); ref_table = dict_table_check_if_in_cache_low( - foreign->referenced_table_name); + foreign->referenced_table_name_lookup); ut_a(for_table || ref_table); if (for_table) { @@ -3015,19 +3018,26 @@ dict_scan_table_name( 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) { -#endif /* !__WIN__ */ - /* The table name is always put to lower case on Windows. */ + + /* srv_lower_case_table_names is always non-zero on Windows + Values; 0 = Store and compare as given; case sensitive + 1 = Store and compare in lower; case insensitive + 2 = Store as given, compare in lower; case semi-sensitive */ + if (srv_lower_case_table_names == 2) { innobase_casedn_str(ref); -#ifndef __WIN__ + *table = dict_table_get_low(ref); + memcpy(ref, database_name, database_name_len); + ref[database_name_len] = '/'; + memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); + } else { + if (srv_lower_case_table_names == 1) { + innobase_casedn_str(ref); + } + *table = dict_table_get_low(ref); } -#endif /* !__WIN__ */ *success = TRUE; *ref_name = ref; - *table = dict_table_get_low(ref); - return(ptr); } @@ -3516,8 +3526,10 @@ col_loop1: } foreign->foreign_table = table; - foreign->foreign_table_name = mem_heap_strdup(foreign->heap, - table->name); + foreign->foreign_table_name = mem_heap_strdup( + foreign->heap, table->name); + dict_mem_set_foreign_table_name_lookup(foreign, TRUE); + foreign->foreign_index = index; foreign->n_fields = (unsigned int) i; foreign->foreign_col_names = mem_heap_alloc(foreign->heap, @@ -3774,8 +3786,9 @@ try_find_index: foreign->referenced_index = index; foreign->referenced_table = referenced_table; - foreign->referenced_table_name - = mem_heap_strdup(foreign->heap, referenced_table_name); + foreign->referenced_table_name = mem_heap_strdup( + foreign->heap, referenced_table_name); + dict_mem_set_referenced_table_name_lookup(foreign, TRUE); foreign->referenced_col_names = mem_heap_alloc(foreign->heap, i * sizeof(void*)); @@ -4586,8 +4599,8 @@ dict_print_info_on_foreign_key_in_create fputs(") REFERENCES ", file); - if (dict_tables_have_same_db(foreign->foreign_table_name, - foreign->referenced_table_name)) { + if (dict_tables_have_same_db(foreign->foreign_table_name_lookup, + foreign->referenced_table_name_lookup)) { /* Do not print the database name of the referenced table */ ut_print_name(file, trx, TRUE, dict_remove_db_name( === modified file 'storage/innobase/dict/dict0load.c' --- a/storage/innobase/dict/dict0load.c revid:vasil.dimov@stripped +++ b/storage/innobase/dict/dict0load.c revid:kevin.lewis@stripped @@ -40,6 +40,7 @@ Created 4/24/1996 Heikki Tuuri #include "rem0cmp.h" #include "srv0start.h" #include "srv0srv.h" +#include "ha_prototypes.h" /* innobase_casedn_str() */ /** Following are six InnoDB system tables */ @@ -435,6 +436,8 @@ dict_process_sys_fields_rec( return(err_msg); } + +#ifdef FOREIGN_NOT_USED /********************************************************************//** This function parses a SYS_FOREIGN record and populate a dict_foreign_t structure with the information from the record. For detail information @@ -483,13 +486,16 @@ err_len: } foreign->foreign_table_name = mem_heap_strdupl( heap, (const char*) field, len); + dict_mem_set_foreign_table_name_lookup(foreign, TRUE); field = rec_get_nth_field_old(rec, 4/*REF_NAME*/, &len); if (UNIV_UNLIKELY(len < 1 || len == UNIV_SQL_NULL)) { goto err_len; } + foreign->referenced_table_name = mem_heap_strdupl( heap, (const char*) field, len); + dict_mem_set_referenced_table_name_lookup(foreign, TRUE); field = rec_get_nth_field_old(rec, 5/*N_COLS*/, &len); if (UNIV_UNLIKELY(len != 4)) { @@ -502,6 +508,9 @@ err_len: return(NULL); } +#endif /* FOREIGN_NOT_USED */ + +#ifdef FOREIGN_NOT_USED /********************************************************************//** This function parses a SYS_FOREIGN_COLS record and extract necessary information from the record and return to caller. @@ -565,6 +574,8 @@ err_len: return(NULL); } +#endif /* FOREIGN_NOT_USED */ + /********************************************************************//** Determine the flags of a table described in SYS_TABLES. @return compressed page size in kilobytes; or 0 if the tablespace is @@ -2057,12 +2068,15 @@ dict_load_foreign( foreign->id = mem_heap_strdup(foreign->heap, id); field = rec_get_nth_field_old(rec, 3, &len); + foreign->foreign_table_name = mem_heap_strdupl( foreign->heap, (char*) field, len); + dict_mem_set_foreign_table_name_lookup(foreign, TRUE); field = rec_get_nth_field_old(rec, 4, &len); foreign->referenced_table_name = mem_heap_strdupl( foreign->heap, (char*) field, len); + dict_mem_set_referenced_table_name_lookup(foreign, TRUE); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -2070,7 +2084,7 @@ dict_load_foreign( dict_load_foreign_cols(id, foreign); ref_table = dict_table_check_if_in_cache_low( - foreign->referenced_table_name); + foreign->referenced_table_name_lookup); /* We could possibly wind up in a deep recursive calls if we call dict_table_get_low() again here if there @@ -2103,7 +2117,7 @@ dict_load_foreign( have to load it so that we are able to make type comparisons in the next function call. */ - for_table = dict_table_get_low(foreign->foreign_table_name); + for_table = dict_table_get_low(foreign->foreign_table_name_lookup); if (for_table && ref_table && check_recursive) { /* This is to record the longest chain of ancesters === modified file 'storage/innobase/dict/dict0mem.c' --- a/storage/innobase/dict/dict0mem.c revid:vasil.dimov@stripped +++ b/storage/innobase/dict/dict0mem.c revid:kevin.lewis@stripped @@ -33,6 +33,7 @@ Created 1/8/1996 Heikki Tuuri #include "data0type.h" #include "mach0data.h" #include "dict0dict.h" +#include "srv0srv.h" /* srv_lower_case_table_names */ #ifndef UNIV_HOTBACKUP # include "lock0lock.h" #endif /* !UNIV_HOTBACKUP */ @@ -288,6 +289,60 @@ dict_mem_foreign_create(void) } /**********************************************************************//** +Sets the foreign_table_name_lookup pointer based on the value of +srv_lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup +will point to foreign_table_name. If 2, then another string is allocated +of the heap and set to lower case. */ +UNIV_INLINE +void +dict_mem_set_foreign_table_name_lookup( + dict_foreign_t* foreign, /*!< in/out: foreign struct */ + ibool do_alloc) /*!< in: is an alloc needed */ +/*=========================*/ +{ + if (srv_lower_case_table_names == 2) { + if (do_alloc) { + foreign->foreign_table_name_lookup = mem_heap_alloc( + foreign->heap, + strlen(foreign->foreign_table_name) + 1); + } + strcpy(foreign->foreign_table_name_lookup, + foreign->foreign_table_name); + innobase_casedn_str(foreign->foreign_table_name_lookup); + } else { + foreign->foreign_table_name_lookup + = foreign->foreign_table_name; + } +} + +/**********************************************************************//** +Sets the referenced_table_name_lookup pointer based on the value of +srv_lower_case_table_names. If that is 0 or 1, +referenced_table_name_lookup will point to referenced_table_name. If 2, +then another string is allocated of the heap and set to lower case. */ +UNIV_INLINE +void +dict_mem_set_referenced_table_name_lookup( + dict_foreign_t* foreign, /*!< in/out: foreign struct */ + ibool do_alloc) /*!< in: is an alloc needed */ +/*=========================*/ +{ + if (srv_lower_case_table_names == 2) { + if (do_alloc) { + foreign->referenced_table_name_lookup = mem_heap_alloc( + foreign->heap, + strlen(foreign->referenced_table_name) + 1); + } + strcpy(foreign->referenced_table_name_lookup, + foreign->referenced_table_name); + innobase_casedn_str(foreign->referenced_table_name_lookup); + } else { + foreign->referenced_table_name_lookup + = foreign->referenced_table_name; + } +} + +/**********************************************************************//** Adds a field definition to an index. NOTE: does not take a copy of the column name if the field is a column. The memory occupied by the column name may be released only after publishing the index. */ === modified file 'storage/innobase/handler/ha_innodb.cc' --- a/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped +++ b/storage/innobase/handler/ha_innodb.cc revid:kevin.lewis@stripped @@ -3639,6 +3639,7 @@ ha_innobase::open( UT_NOT_USED(test_if_locked); thd = ha_thd(); + srv_lower_case_table_names = lower_case_table_names; /* Under some cases MySQL seems to call this function while holding btr_search_latch. This breaks the latching order as @@ -6753,11 +6754,7 @@ ha_innobase::create( trx = innobase_trx_allocate(thd); - if (lower_case_table_names) { - srv_lower_case_table_names = TRUE; - } else { - srv_lower_case_table_names = FALSE; - } + srv_lower_case_table_names = lower_case_table_names; strcpy(name2, name); @@ -7181,11 +7178,7 @@ ha_innobase::delete_table( trx = innobase_trx_allocate(thd); - if (lower_case_table_names) { - srv_lower_case_table_names = TRUE; - } else { - srv_lower_case_table_names = FALSE; - } + srv_lower_case_table_names = lower_case_table_names; name_len = strlen(name); @@ -7308,11 +7301,7 @@ innobase_rename_table( char* norm_to; char* norm_from; - if (lower_case_table_names) { - srv_lower_case_table_names = TRUE; - } else { - srv_lower_case_table_names = FALSE; - } + srv_lower_case_table_names = lower_case_table_names; // Magic number 64 arbitrary norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0)); === modified file 'storage/innobase/include/dict0mem.h' --- a/storage/innobase/include/dict0mem.h revid:vasil.dimov@stripped +++ b/storage/innobase/include/dict0mem.h revid:kevin.lewis@stripped @@ -238,6 +238,26 @@ dict_foreign_t* dict_mem_foreign_create(void); /*=========================*/ +/**********************************************************************//** +Sets the foreign_table_name_lookup pointer based on the value of +srv_lower_case_table_names. */ +UNIV_INTERN +void +dict_mem_set_foreign_table_name_lookup( +/*============================*/ + dict_foreign_t* foreign, /*!< in/out: foreign struct */ + ibool do_alloc); /*!< in: is an alloc needed */ + +/**********************************************************************//** +Sets the reference_table_name_lookup pointer based on the value of +srv_lower_case_table_names. */ +UNIV_INTERN +void +dict_mem_set_referenced_table_name_lookup( +/*============================*/ + dict_foreign_t* foreign, /*!< in/out: foreign struct */ + ibool do_alloc); /*!< in: is an alloc needed */ + /** Data structure for a column in a table */ struct dict_col_struct{ /*----------------------*/ @@ -393,10 +413,12 @@ struct dict_foreign_struct{ unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE or DICT_FOREIGN_ON_DELETE_SET_NULL */ char* foreign_table_name;/*!< foreign table name */ + char* foreign_table_name_lookup;/*!< foreign table name used for dict lookup */ dict_table_t* foreign_table; /*!< table where the foreign key is */ const char** foreign_col_names;/*!< names of the columns in the foreign key */ char* referenced_table_name;/*!< referenced table name */ + char* referenced_table_name_lookup;/*!< referenced table name for dict lookup*/ dict_table_t* referenced_table;/*!< table where the referenced key is */ const char** referenced_col_names;/*!< names of the referenced === modified file 'storage/innobase/include/srv0srv.h' --- a/storage/innobase/include/srv0srv.h revid:vasil.dimov@stripped +++ b/storage/innobase/include/srv0srv.h revid:kevin.lewis@stripped @@ -71,8 +71,8 @@ at a time */ #define SRV_AUTO_EXTEND_INCREMENT \ (srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE)) -/* This is set to TRUE if the MySQL user has set it in MySQL */ -extern ibool srv_lower_case_table_names; +/* This is set to the MySQL server value for this variable. */ +extern uint srv_lower_case_table_names; /* Mutex for locking srv_monitor_file */ extern mutex_t srv_monitor_file_mutex; === modified file 'storage/innobase/row/row0ins.c' --- a/storage/innobase/row/row0ins.c revid:vasil.dimov@stripped +++ b/storage/innobase/row/row0ins.c revid:kevin.lewis@stripped @@ -1525,7 +1525,7 @@ row_ins_check_foreign_constraints( if (foreign->foreign_index == index) { if (foreign->referenced_table == NULL) { - dict_table_get(foreign->referenced_table_name, + dict_table_get(foreign->referenced_table_name_lookup, FALSE); } === modified file 'storage/innobase/row/row0mysql.c' --- a/storage/innobase/row/row0mysql.c revid:vasil.dimov@stripped +++ b/storage/innobase/row/row0mysql.c revid:kevin.lewis@stripped @@ -3163,7 +3163,7 @@ check_next_foreign: if (foreign && trx->check_foreigns && !(drop_db && dict_tables_have_same_db( - name, foreign->foreign_table_name))) { + name, foreign->foreign_table_name_lookup))) { FILE* ef = dict_foreign_err_file; /* We only allow dropping a referenced table if === modified file 'storage/innobase/row/row0upd.c' --- a/storage/innobase/row/row0upd.c revid:vasil.dimov@stripped +++ b/storage/innobase/row/row0upd.c revid:kevin.lewis@stripped @@ -238,7 +238,7 @@ row_upd_check_references_constraints( foreign->n_fields))) { if (foreign->foreign_table == NULL) { - dict_table_get(foreign->foreign_table_name, + dict_table_get(foreign->foreign_table_name_lookup, FALSE); } === modified file 'storage/innobase/srv/srv0srv.c' --- a/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped +++ b/storage/innobase/srv/srv0srv.c revid:kevin.lewis@stripped @@ -87,9 +87,12 @@ Created 10/8/1995 Heikki Tuuri #include "mysql/plugin.h" #include "mysql/service_thd_wait.h" -/* This is set to TRUE if the MySQL user has set it in MySQL; currently -affects only FOREIGN KEY definition parsing */ -UNIV_INTERN ibool srv_lower_case_table_names = FALSE; +/* This is set to the MySQL server value for this variable. +It is only needed for FOREIGN KEY definition parsing. +FOREIGN KEY names are not stored in the server metadata. +The server stores and enforces it for regular database and +table names */ +UNIV_INTERN uint srv_lower_case_table_names = 0; /* The following counter is incremented whenever there is some user activity in the server */ --===============0920308335== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/kevin.lewis@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kevin.lewis@stripped # target_branch: file:///Users/kevinlewis/Work/Mysql/Bug55222/mysql-\ # 5.5-innodb/ # testament_sha1: 58f68787f1f5d8aab77b3a799da59092a110cc69 # timestamp: 2010-11-23 15:05:32 -0600 # base_revision_id: vasil.dimov@stripped\ # lk81dxudn9eaqddm # # Begin bundle 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 3JFOFCQgzFkOAA== --===============0920308335==--