#At file:///usr/local/devel/bzrroot/server/mysql-5.5/ based on revid:bjorn.munch@stripped
3485 Vasil Dimov 2011-05-02 [merge]
Merge mysql-5.5-innodb -> mysql-5.5
modified:
mysql-test/suite/innodb/r/innodb_bug60196.result
mysql-test/suite/innodb/t/innodb_bug60196.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/ha_prototypes.h
storage/innobase/include/srv0srv.h
storage/innobase/srv/srv0srv.c
=== modified file 'mysql-test/suite/innodb/r/innodb_bug60196.result'
--- a/mysql-test/suite/innodb/r/innodb_bug60196.result revid:bjorn.munch@stripped
+++ b/mysql-test/suite/innodb/r/innodb_bug60196.result revid:vasil.dimov@stripped
@@ -71,3 +71,47 @@ FK1_Key FK2_Key
DROP TABLE Bug_60196;
DROP TABLE Bug_60196_FK1;
DROP TABLE Bug_60196_FK2;
+CREATE TABLE Bug_60309_FK (
+ID INT PRIMARY KEY,
+ID2 INT,
+KEY K2(ID2)
+) ENGINE=InnoDB;
+CREATE TABLE Bug_60309 (
+ID INT PRIMARY KEY,
+FK_ID INT,
+KEY (FK_ID),
+CONSTRAINT FK FOREIGN KEY (FK_ID) REFERENCES Bug_60309_FK (ID)
+) ENGINE=InnoDB;
+INSERT INTO Bug_60309_FK (ID, ID2) VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO Bug_60309 VALUES (1, 1);
+INSERT INTO Bug_60309 VALUES (2, 99);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`bug_60309`, CONSTRAINT `FK` FOREIGN KEY (`FK_ID`) REFERENCES `Bug_60309_FK` (`ID`))
+SELECT * FROM Bug_60309_FK;
+ID ID2
+1 1
+2 2
+3 3
+SELECT * FROM Bug_60309;
+ID FK_ID
+1 1
+# Stop server
+# Restart server.
+#
+# Try to insert more to the example table with foreign keys.
+# Bug60309 causes the foreign key file not to be found after
+# the resstart above.
+#
+SELECT * FROM Bug_60309;
+ID FK_ID
+1 1
+INSERT INTO Bug_60309 VALUES (2, 2);
+INSERT INTO Bug_60309 VALUES (3, 3);
+SELECT * FROM Bug_60309;
+ID FK_ID
+1 1
+2 2
+3 3
+
+# Clean up.
+DROP TABLE Bug_60309;
+DROP TABLE Bug_60309_FK;
=== modified file 'mysql-test/suite/innodb/t/innodb_bug60196.test'
--- a/mysql-test/suite/innodb/t/innodb_bug60196.test revid:bjorn.munch@stripped
+++ b/mysql-test/suite/innodb/t/innodb_bug60196.test revid:vasil.dimov@stripped
@@ -85,3 +85,73 @@ DROP TABLE Bug_60196;
DROP TABLE Bug_60196_FK1;
DROP TABLE Bug_60196_FK2;
+
+# Bug#60309/12356829
+# MYSQL 5.5.9 FOR MAC OSX HAS BUG WITH FOREIGN KEY CONSTRAINTS
+# This testcase is different from that for Bug#60196 in that the
+# referenced table contains a secondary key. When the engine is
+# restarted, the referenced table is opened by the purge thread,
+# which does not notice that lower_case_table_names == 2.
+
+#
+# Create test data.
+#
+CREATE TABLE Bug_60309_FK (
+ ID INT PRIMARY KEY,
+ ID2 INT,
+ KEY K2(ID2)
+) ENGINE=InnoDB;
+CREATE TABLE Bug_60309 (
+ ID INT PRIMARY KEY,
+ FK_ID INT,
+ KEY (FK_ID),
+ CONSTRAINT FK FOREIGN KEY (FK_ID) REFERENCES Bug_60309_FK (ID)
+) ENGINE=InnoDB;
+
+INSERT INTO Bug_60309_FK (ID, ID2) VALUES (1, 1), (2, 2), (3, 3);
+INSERT INTO Bug_60309 VALUES (1, 1);
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO Bug_60309 VALUES (2, 99);
+
+SELECT * FROM Bug_60309_FK;
+SELECT * FROM Bug_60309;
+
+--echo # Stop server
+
+# Write file to make mysql-test-run.pl wait for the server to stop
+-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Send a shutdown request to the server
+-- shutdown_server 10
+
+# Call script that will poll the server waiting for it to disapear
+-- source include/wait_until_disconnected.inc
+
+--echo # Restart server.
+
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+
+# Turn off reconnect again
+--disable_reconnect
+
+--echo #
+--echo # Try to insert more to the example table with foreign keys.
+--echo # Bug60309 causes the foreign key file not to be found after
+--echo # the resstart above.
+--echo #
+SELECT * FROM Bug_60309;
+INSERT INTO Bug_60309 VALUES (2, 2);
+INSERT INTO Bug_60309 VALUES (3, 3);
+SELECT * FROM Bug_60309;
+
+--echo
+--echo # Clean up.
+DROP TABLE Bug_60309;
+DROP TABLE Bug_60309_FK;
=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c revid:bjorn.munch@stripped
+++ b/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped
@@ -52,7 +52,6 @@ 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(), innobase_casedn_str()*/
@@ -3029,14 +3028,14 @@ dict_scan_table_name(
/* 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) {
+ if (innobase_get_lower_case_table_names() == 2) {
innobase_casedn_str(ref);
*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) {
+ if (innobase_get_lower_case_table_names() == 1) {
innobase_casedn_str(ref);
}
*table = dict_table_get_low(ref);
=== modified file 'storage/innobase/dict/dict0load.c'
--- a/storage/innobase/dict/dict0load.c revid:bjorn.munch@stripped
+++ b/storage/innobase/dict/dict0load.c revid:vasil.dimov@stripped
@@ -2262,7 +2262,7 @@ loop:
may not be the same case, but the previous comparison showed that they
match with no-case. */
- if ((srv_lower_case_table_names != 2)
+ if ((innobase_get_lower_case_table_names() != 2)
&& (0 != ut_memcmp(field, table_name, len))) {
goto next_rec;
}
=== modified file 'storage/innobase/dict/dict0mem.c'
--- a/storage/innobase/dict/dict0mem.c revid:bjorn.munch@stripped
+++ b/storage/innobase/dict/dict0mem.c revid:vasil.dimov@stripped
@@ -33,7 +33,6 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
-#include "srv0srv.h" /* srv_lower_case_table_names */
#include "ha_prototypes.h" /* innobase_casedn_str()*/
#ifndef UNIV_HOTBACKUP
# include "lock0lock.h"
@@ -294,9 +293,9 @@ 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. */
+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 from foreign->heap and set to lower case. */
UNIV_INTERN
void
dict_mem_foreign_table_name_lookup_set(
@@ -304,7 +303,7 @@ dict_mem_foreign_table_name_lookup_set(
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{
- if (srv_lower_case_table_names == 2) {
+ if (innobase_get_lower_case_table_names() == 2) {
if (do_alloc) {
foreign->foreign_table_name_lookup = mem_heap_alloc(
foreign->heap,
@@ -321,9 +320,9 @@ dict_mem_foreign_table_name_lookup_set(
/**********************************************************************//**
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. */
+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 from foreign->heap and set to lower case. */
UNIV_INTERN
void
dict_mem_referenced_table_name_lookup_set(
@@ -331,7 +330,7 @@ dict_mem_referenced_table_name_lookup_se
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc) /*!< in: is an alloc needed */
{
- if (srv_lower_case_table_names == 2) {
+ if (innobase_get_lower_case_table_names() == 2) {
if (do_alloc) {
foreign->referenced_table_name_lookup = mem_heap_alloc(
foreign->heap,
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:bjorn.munch@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped
@@ -1199,6 +1199,20 @@ innobase_get_stmt(
return(stmt->str);
}
+/**********************************************************************//**
+Get the current setting of the lower_case_table_names global parameter from
+mysqld.cc. We do a dirty read because for one there is no synchronization
+object and secondly there is little harm in doing so even if we get a torn
+read.
+@return value of lower_case_table_names */
+extern "C" UNIV_INTERN
+ulint
+innobase_get_lower_case_table_names(void)
+/*=====================================*/
+{
+ return(lower_case_table_names);
+}
+
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
/*******************************************************************//**
@@ -3671,7 +3685,6 @@ 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
@@ -6362,8 +6375,6 @@ err_col:
col_len);
}
- srv_lower_case_table_names = lower_case_table_names;
-
error = row_create_table_for_mysql(table, trx);
if (error == DB_DUPLICATE_KEY) {
@@ -7223,8 +7234,6 @@ ha_innobase::delete_table(
/* Drop the table in InnoDB */
- srv_lower_case_table_names = lower_case_table_names;
-
error = row_drop_table_for_mysql(norm_name, trx,
thd_sql_command(thd)
== SQLCOM_DROP_DB);
@@ -7354,8 +7363,6 @@ innobase_rename_table(
row_mysql_lock_data_dictionary(trx);
}
- srv_lower_case_table_names = lower_case_table_names;
-
error = row_rename_table_for_mysql(
norm_from, norm_to, trx, lock_and_commit);
=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h revid:bjorn.munch@stripped
+++ b/storage/innobase/include/dict0mem.h revid:vasil.dimov@stripped
@@ -240,7 +240,9 @@ dict_mem_foreign_create(void);
/**********************************************************************//**
Sets the foreign_table_name_lookup pointer based on the value of
-srv_lower_case_table_names. */
+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 from the heap and set to lower case. */
UNIV_INTERN
void
dict_mem_foreign_table_name_lookup_set(
@@ -249,8 +251,10 @@ dict_mem_foreign_table_name_lookup_set(
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. */
+Sets the referenced_table_name_lookup pointer based on the value of
+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 from the heap and set to lower case. */
UNIV_INTERN
void
dict_mem_referenced_table_name_lookup_set(
=== modified file 'storage/innobase/include/ha_prototypes.h'
--- a/storage/innobase/include/ha_prototypes.h revid:bjorn.munch@stripped
+++ b/storage/innobase/include/ha_prototypes.h revid:vasil.dimov@stripped
@@ -285,4 +285,15 @@ thd_set_lock_wait_time(
void* thd, /*!< in: thread handle (THD*) */
ulint value); /*!< in: time waited for the lock */
+/**********************************************************************//**
+Get the current setting of the lower_case_table_names global parameter from
+mysqld.cc. We do a dirty read because for one there is no synchronization
+object and secondly there is little harm in doing so even if we get a torn
+read.
+@return value of lower_case_table_names */
+UNIV_INTERN
+ulint
+innobase_get_lower_case_table_names(void);
+/*=====================================*/
+
#endif
=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h revid:bjorn.munch@stripped
+++ b/storage/innobase/include/srv0srv.h revid:vasil.dimov@stripped
@@ -71,9 +71,6 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
-/* 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;
/* Temporary file for innodb monitor output */
=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c revid:bjorn.munch@stripped
+++ b/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped
@@ -86,12 +86,6 @@ Created 10/8/1995 Heikki Tuuri
#include "mysql/plugin.h"
#include "mysql/service_thd_wait.h"
-/* This is set to the MySQL server value for this variable. It is only
-needed for FOREIGN KEY definition parsing since 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 */
UNIV_INTERN ulint srv_activity_count = 0;
No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
| Thread |
|---|
| • bzr commit into mysql-5.5 branch (vasil.dimov:3485) | vasil.dimov | 2 May |