diff options
author | unknown <andrey@example.com> | 2006-12-04 18:22:38 +0100 |
---|---|---|
committer | unknown <andrey@example.com> | 2006-12-04 18:22:38 +0100 |
commit | ab31e4278d06107cae90c8035748769b352ba3ad (patch) | |
tree | d2a1ddd6efe00051bea52be22419fff7748a7087 /mysql-test/t/alter_table.test | |
parent | 4f912e049871bf3a4a708dc66477d4b55247bddd (diff) | |
download | mariadb-git-ab31e4278d06107cae90c8035748769b352ba3ad.tar.gz |
Fix for bug#22369: Alter table rename combined
with other alterations causes lost tables
Using RENAME clause combined with other clauses of ALTER TABLE led to
data loss (the data was there but not accessible). This could happen if the
changes do not change the table much. Adding and droppping of fields and
indices was safe. Renaming a column with MODIFY or CHANGE was unsafe operation,
if the actual column didn't change (changing from int to int, which is a noop)
Depending on the storage engine (SE) the behavior is different:
1)MyISAM/MEMORY - the ALTER TABLE statement completes
without any error but next SELECT against the new table fails.
2)InnoDB (and every other transactional table) - The ALTER TABLE statement
fails. There are the the following files in the db dir -
`new_table_name.frm` and a temporary table's frm. If the SE is file
based, then the data and index files will be present but with the old
names. What happens is that for InnoDB the table is not renamed in the
internal DDIC.
Fixed by adding additional call to mysql_rename_table() method, which should
not include FRM file rename, because it has been already done during file
names juggling.
mysql-test/r/alter_table.result:
update result
mysql-test/r/grant.result:
update result
mysql-test/t/alter_table.test:
2006/11/29 11:46:23+01:00 andrey@example.com +44 -9
Error to bug number
Added test case for #22369: Alter table rename combined
with other alterations causes lost tables
mysql-test/t/grant.test:
add test for bug#22369 - alter table was missing check
for DROP_ACL when ALTER_RENAME clause is specified. Synchronise
with RENAME TABLE DDL.
sql/mysql_priv.h:
Add a new flag for mysql_rename_table()
sql/sql_parse.cc:
To be consistent with SQLCOM_RENAME_TABLE, SQLCOM_ALTER_TABLE has
to check for DROP_ACL if there is ALTER_RENAME flag set.
sql/sql_table.cc:
ALTER_RENAME, the data and index files weren't renamed in the engine
but only the FRM was new, when the tables old and new tables are compatible.
In the chain of FRM renames we add a call to mysql_rename_table() which should
instruct the engine to rename the table but not rename the FRM.
This bug was there only in 5.1 branch. 4.1 and 5.0 always do copy data on RENAME
if there are more clauses than just rename.
Diffstat (limited to 'mysql-test/t/alter_table.test')
-rw-r--r-- | mysql-test/t/alter_table.test | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index aa2133db9c5..d4db81f08fa 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -101,7 +101,7 @@ create table mysqltest.t1 (name char(15)); insert into mysqltest.t1 (name) values ("mysqltest"); select * from t1; select * from mysqltest.t1; ---error 1050 +--error ER_TABLE_EXISTS_ERROR alter table t1 rename mysqltest.t1; select * from t1; select * from mysqltest.t1; @@ -231,9 +231,9 @@ DROP TABLE t1; # BUG#4717 - check for valid table names # create table t1 (a int); ---error 1103 +--error ER_WRONG_TABLE_NAME alter table t1 rename to ``; ---error 1103 +--error ER_WRONG_TABLE_NAME rename table t1 to ``; drop table t1; @@ -325,14 +325,14 @@ drop table t1; CREATE TABLE t1 (a int PRIMARY KEY, b INT UNIQUE); ALTER TABLE t1 DROP PRIMARY KEY; SHOW CREATE TABLE t1; ---error 1091 +--error ER_CANT_DROP_FIELD_OR_KEY ALTER TABLE t1 DROP PRIMARY KEY; DROP TABLE t1; # BUG#3899 create table t1 (a int, b int, key(a)); insert into t1 values (1,1), (2,2); ---error 1091 +--error ER_CANT_DROP_FIELD_OR_KEY alter table t1 drop key no_such_key; alter table t1 drop key a; drop table t1; @@ -343,7 +343,7 @@ drop table t1; # Some platforms (Mac OS X, Windows) will send the error message using small letters. CREATE TABLE T12207(a int) ENGINE=MYISAM; --replace_result t12207 T12207 ---error 1031 +--error ER_ILLEGAL_HA ALTER TABLE T12207 DISCARD TABLESPACE; DROP TABLE T12207; @@ -367,7 +367,7 @@ drop table t1; # shorter than packed field length. # create table t1 ( a timestamp ); ---error 1089 +--error ER_WRONG_SUB_KEY alter table t1 add unique ( a(1) ); drop table t1; @@ -380,7 +380,7 @@ create table t1 (c1 int); # Move table to other database. alter table t1 rename mysqltest.t1; # Assure that it has moved. ---error 1051 +--error ER_BAD_TABLE_ERROR drop table t1; # Move table back. alter table mysqltest.t1 rename t1; @@ -394,7 +394,7 @@ use mysqltest; # Drop the current db. This de-selects any db. drop database mysqltest; # Now test for correct message. ---error 1046 +--error ER_NO_DB_ERROR alter table test.t1 rename t1; # Check that explicit qualifying works even with no selected db. alter table test.t1 rename test.t1; @@ -554,3 +554,38 @@ SHOW CREATE TABLE `#sql2`; SHOW CREATE TABLE `@0023sql1`; DROP TABLE `#sql2`, `@0023sql1`; +# +# Bug #22369: Alter table rename combined with other alterations causes lost tables +# +# This problem happens if the data change is compatible. +# Changing to the same type is compatible for example. +# +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings +CREATE TABLE t1 ( + int_field INTEGER UNSIGNED NOT NULL, + char_field CHAR(10), + INDEX(`int_field`) +); + +DESCRIBE t1; + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES (1, "edno"), (1, "edno"), (2, "dve"), (3, "tri"), (5, "pet"); +--echo "Non-copy data change - new frm, but old data and index files" +ALTER TABLE t1 + CHANGE int_field unsigned_int_field INTEGER UNSIGNED NOT NULL, + RENAME t2; + +--error ER_NO_SUCH_TABLE +SELECT * FROM t1 ORDER BY int_field; +SELECT * FROM t2 ORDER BY unsigned_int_field; +DESCRIBE t2; +DESCRIBE t2; +ALTER TABLE t2 MODIFY unsigned_int_field BIGINT UNSIGNED NOT NULL; +DESCRIBE t2; + +DROP TABLE t2; |