#At file:///G:/bzr/ts2/ based on revid:vvaintroub@stripped
3030 Vladislav Vaintroub 2009-02-23
Bug#42478 : Falcon crash in Database::updateSequence
The problem: when a Falcon table with autoincrement column is created
,Falcon will assign a sequence to table name /schema name combination.
and use it to generate autoincrement values. When table is renamed,
sequence is modified (table name changed). However, schema name changes
are not taken into account when renaming.
This is be a problem, because
a) Falcon data dictionary (sequences table) is now corrupt.
b) hash table sequences will have duplicate entries if there is
a table with the same name and different schema. drop table may
drop a wrong sequence.
The fix is to take schema name into account when renaming a sequence.
@ mysql-test/suite/falcon/r/falcon_bug_42478.result
new test
@ mysql-test/suite/falcon/t/falcon_bug_42478.test
new test
@ storage/falcon/Sequence.cpp
when renaming sequence, take schema name into account
@ storage/falcon/Sequence.h
when renaming sequence, take schema name into account
@ storage/falcon/SequenceManager.cpp
when renaming sequence, take schema name into account
@ storage/falcon/SequenceManager.h
when renaming sequence, take schema name into account
@ storage/falcon/StorageDatabase.cpp
when renaming sequence, take schema name into account
added:
mysql-test/suite/falcon/r/falcon_bug_42478.result
mysql-test/suite/falcon/t/falcon_bug_42478.test
modified:
storage/falcon/Sequence.cpp
storage/falcon/Sequence.h
storage/falcon/SequenceManager.cpp
storage/falcon/SequenceManager.h
storage/falcon/StorageDatabase.cpp
=== added file 'mysql-test/suite/falcon/r/falcon_bug_42478.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_42478.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_42478.result 2009-02-23 16:21:49 +0000
@@ -0,0 +1,27 @@
+*** Bug #42478 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+CREATE TABLE t1 (i INT AUTO_INCREMENT, PRIMARY KEY(i));
+RENAME TABLE t1 TO d1.t1;
+CREATE TABLE t1 (i INT AUTO_INCREMENT, PRIMARY KEY(i));
+RENAME TABLE t1 TO d2.t1;
+INSERT INTO d1.t1 VALUES();
+INSERT INTO d2.t1 VALUES();
+SHOW CREATE TABLE d1.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`i`)
+) ENGINE=Falcon AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
+SHOW CREATE TABLE d2.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`i`)
+) ENGINE=Falcon AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
+DROP TABLE d1.t1;
+DROP TABLE d2.t1;
+DROP DATABASE d1;
+DROP DATABASE d2;
=== added file 'mysql-test/suite/falcon/t/falcon_bug_42478.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_42478.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_42478.test 2009-02-23 16:21:49 +0000
@@ -0,0 +1,54 @@
+--source include/have_falcon.inc
+
+#
+# Bug #42478 Falcon crash in Database::updateSequence
+#
+# The reason for the crash is broken handling or rename
+# cross database/schema boundaries (Falcon sequences
+# disregard schema name on rename)
+# This test uses rename, equal table names and different
+# database/schema names to make the error apparent
+
+--echo *** Bug #42478 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test --- #
+# ----------------------------------------------------- #
+
+CREATE DATABASE d1;
+CREATE DATABASE d2;
+
+CREATE TABLE t1 (i INT AUTO_INCREMENT, PRIMARY KEY(i));
+RENAME TABLE t1 TO d1.t1;
+
+CREATE TABLE t1 (i INT AUTO_INCREMENT, PRIMARY KEY(i));
+RENAME TABLE t1 TO d2.t1;
+
+INSERT INTO d1.t1 VALUES();
+INSERT INTO d2.t1 VALUES();
+
+
+# ----------------------------------------------------- #
+# --- Check --- #
+# ----------------------------------------------------- #
+SHOW CREATE TABLE d1.t1;
+SHOW CREATE TABLE d2.t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup --- #
+# ----------------------------------------------------- #
+DROP TABLE d1.t1;
+DROP TABLE d2.t1;
+
+DROP DATABASE d1;
+DROP DATABASE d2;
=== modified file 'storage/falcon/Sequence.cpp'
--- a/storage/falcon/Sequence.cpp 2007-11-13 22:09:39 +0000
+++ b/storage/falcon/Sequence.cpp 2009-02-23 16:21:49 +0000
@@ -56,9 +56,9 @@ int64 Sequence::updatePhysical(int64 del
return database->updateSequence (id, delta, transaction);
}
-void Sequence::rename(const char* newName)
+void Sequence::rename(const char *newSchema, const char* newName)
{
- database->sequenceManager->renameSequence(this, newName);
+ database->sequenceManager->renameSequence(this, newSchema, newName);
}
Sequence* Sequence::recreate(void)
=== modified file 'storage/falcon/Sequence.h'
--- a/storage/falcon/Sequence.h 2007-11-13 22:09:39 +0000
+++ b/storage/falcon/Sequence.h 2009-02-23 16:21:49 +0000
@@ -44,7 +44,7 @@ public:
Sequence *collision;
Schema *schema;
Database *database;
- void rename(const char* newName);
+ void rename(const char *newSchema, const char* newName);
Sequence *recreate(void);
};
=== modified file 'storage/falcon/SequenceManager.cpp'
--- a/storage/falcon/SequenceManager.cpp 2008-07-24 08:45:03 +0000
+++ b/storage/falcon/SequenceManager.cpp 2009-02-23 16:21:49 +0000
@@ -178,7 +178,7 @@ Sequence* SequenceManager::getSequence(c
return sequence;
}
-void SequenceManager::renameSequence(Sequence* sequence, const char* newName)
+void SequenceManager::renameSequence(Sequence* sequence, const char *newSchema, const char* newName)
{
Sync sync (&syncObject, "SequenceManager::renameSequence");
sync.lock (Exclusive);
@@ -194,14 +194,16 @@ void SequenceManager::renameSequence(Seq
sync.unlock();
PreparedStatement *statement = database->prepareStatement (
- "update system.sequences set sequenceName=? where schema=? and sequenceName=?");
- statement->setString (1, newName);
- statement->setString (2, sequence->schemaName);
- statement->setString (3, sequence->name);
+ "update system.sequences set schema=? , sequenceName=? where schema=? and sequenceName=?");
+ statement->setString (1, newSchema);
+ statement->setString (2, newName);
+ statement->setString (3, sequence->schemaName);
+ statement->setString (4, sequence->name);
statement->executeUpdate();
statement->close();
sync.lock (Exclusive);
+ sequence->schemaName = database->getSymbol(newSchema);
sequence->name = database->getSymbol(newName);
slot = HASH (sequence->name, SEQUENCE_HASH_SIZE);
ASSERT (slot >= 0 && slot < SEQUENCE_HASH_SIZE);
=== modified file 'storage/falcon/SequenceManager.h'
--- a/storage/falcon/SequenceManager.h 2007-11-13 22:09:39 +0000
+++ b/storage/falcon/SequenceManager.h 2009-02-23 16:21:49 +0000
@@ -47,7 +47,7 @@ protected:
Sequence *sequences [SEQUENCE_HASH_SIZE];
SyncObject syncObject;
public:
- void renameSequence(Sequence* sequence, const char* newName);
+ void renameSequence(Sequence* sequence, const char* newSchema, const char* newName);
Sequence *recreateSequence(Sequence *oldSequence);
};
=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp 2009-01-20 08:09:02 +0000
+++ b/storage/falcon/StorageDatabase.cpp 2009-02-23 16:21:49 +0000
@@ -733,7 +733,7 @@ int StorageDatabase::renameTable(Storage
try
{
Database *database = connection->database;
- Sequence *sequence = connection->findSequence(schemaName, table->name);
+ Sequence *sequence = connection->findSequence(table->schemaName, table->name);
Sync syncDDL(&database->syncSysDDL, "StorageDatabase::renameTable(1)");
syncDDL.lock(Exclusive);
@@ -744,7 +744,7 @@ int StorageDatabase::renameTable(Storage
table->rename(schemaName, tableName);
if (sequence)
- sequence->rename(tableName);
+ sequence->rename(schemaName, tableName);
syncTables.unlock();
syncDDL.unlock();
Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20090223162149-hbwff7k6y2t18ml4.bundle