summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2010-09-16 11:11:13 +0200
committerJon Olav Hauglid <jon.hauglid@oracle.com>2010-09-16 11:11:13 +0200
commita302953bf77cceb0fec5097b7a5a7a937b8157c3 (patch)
treecb33ecedeedc556cabcde2a1922b1449b4c004ae
parente86bbbda55c12945aed9b141d4442b4dd6c49ea0 (diff)
downloadmariadb-git-a302953bf77cceb0fec5097b7a5a7a937b8157c3.tar.gz
Bug #56595 RENAME TABLE causes assert on OS X
The problem was that RENAME TABLE caused an assert if the system variable lower_case_table_names was 2 (default on Mac OS X) and the old table name was given in upper case. This caused lowercase_table2.test to fail. The assert checks that an exclusive metadata lock is held by the connection trying to do RENAME TABLE - specificially during updates of table triggers. The assert was triggered since the check is case sensitive and the lock was held on the normalized (lower case) version of the table name. This patch fixes the problem by making sure a normalized version of the table name is used for the metadata lock check, while using a non-normalized version of the table name for the rename of trigger files. The same is done for ALTER TABLE ... RENAME. Regression testing for the bug itself is already covered by lowercase_table2.test. Additional coverage added to lowercase_fs_off.test.
-rw-r--r--mysql-test/r/lowercase_fs_off.result8
-rw-r--r--mysql-test/t/lowercase_fs_off.test11
-rw-r--r--sql/sql_rename.cc1
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_trigger.h1
6 files changed, 28 insertions, 4 deletions
diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result
index 30f835a8ea3..c3284b225dd 100644
--- a/mysql-test/r/lowercase_fs_off.result
+++ b/mysql-test/r/lowercase_fs_off.result
@@ -55,3 +55,11 @@ DROP USER user_1@localhost;
DROP USER USER_1@localhost;
DROP DATABASE db1;
use test;
+#
+# Extra test coverage for Bug#56595 RENAME TABLE causes assert on OS X
+#
+CREATE TABLE t1(a INT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a= 1;
+RENAME TABLE t1 TO T1;
+ALTER TABLE T1 RENAME t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test
index 86d1e084c29..1be0351f9bc 100644
--- a/mysql-test/t/lowercase_fs_off.test
+++ b/mysql-test/t/lowercase_fs_off.test
@@ -91,3 +91,14 @@ DROP DATABASE db1;
use test;
# End of 5.0 tests
+
+
+--echo #
+--echo # Extra test coverage for Bug#56595 RENAME TABLE causes assert on OS X
+--echo #
+
+CREATE TABLE t1(a INT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a= 1;
+RENAME TABLE t1 TO T1;
+ALTER TABLE T1 RENAME t1;
+DROP TABLE t1;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 97f8e46d052..ac15239b040 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -285,6 +285,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
{
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
old_alias,
+ ren_table->table_name,
new_db,
new_alias)))
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9d8f59189d0..d8ef6d7030a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5918,7 +5918,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
*fn_ext(new_name)=0;
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
error= -1;
- else if (Table_triggers_list::change_table_name(thd, db, table_name,
+ else if (Table_triggers_list::change_table_name(thd, db,
+ alias, table_name,
new_db, new_alias))
{
(void) mysql_rename_table(old_db_type, new_db, new_alias, db,
@@ -6555,7 +6556,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
(need_copy_table != ALTER_TABLE_METADATA_ONLY ||
mysql_rename_table(save_old_db_type, db, table_name, new_db,
new_alias, NO_FRM_RENAME)) &&
- Table_triggers_list::change_table_name(thd, db, table_name,
+ Table_triggers_list::change_table_name(thd, db, alias, table_name,
new_db, new_alias)))
{
/* Try to get everything back. */
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index c1405015365..392343eb9a3 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1874,6 +1874,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *old_db_name,
@param[in,out] thd Thread context
@param[in] db Old database of subject table
+ @param[in] old_alias Old alias of subject table
@param[in] old_table Old name of subject table
@param[in] new_db New database for subject table
@param[in] new_table New name of subject table
@@ -1890,6 +1891,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *old_db_name,
*/
bool Table_triggers_list::change_table_name(THD *thd, const char *db,
+ const char *old_alias,
const char *old_table,
const char *new_db,
const char *new_table)
@@ -1911,7 +1913,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
MDL_EXCLUSIVE));
DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) ||
- my_strcasecmp(table_alias_charset, old_table, new_table));
+ my_strcasecmp(table_alias_charset, old_alias, new_table));
if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE))
{
@@ -1920,7 +1922,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
}
if (table.triggers)
{
- LEX_STRING old_table_name= { (char *) old_table, strlen(old_table) };
+ LEX_STRING old_table_name= { (char *) old_alias, strlen(old_alias) };
LEX_STRING new_table_name= { (char *) new_table, strlen(new_table) };
/*
Since triggers should be in the same schema as their subject tables
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 28bf0a60877..dd954957f07 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -157,6 +157,7 @@ public:
TABLE *table, bool names_only);
static bool drop_all_triggers(THD *thd, char *db, char *table_name);
static bool change_table_name(THD *thd, const char *db,
+ const char *old_alias,
const char *old_table,
const char *new_db,
const char *new_table);