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/grant.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/grant.test')
-rw-r--r-- | mysql-test/t/grant.test | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index d3781d58780..10203a4a221 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -822,6 +822,82 @@ create user mysqltest1_thisisreallytoolong; # statements. # +# +# Bug #22369: Alter table rename combined with other alterations causes lost tables +# +CREATE DATABASE mysqltest1; +CREATE TABLE mysqltest1.t1 ( + int_field INTEGER UNSIGNED NOT NULL, + char_field CHAR(10), + INDEX(`int_field`) +); +CREATE TABLE mysqltest1.t2 (int_field INT); + +--echo "Now check that we require equivalent grants for " +--echo "RENAME TABLE and ALTER TABLE" +CREATE USER mysqltest_1@localhost; +GRANT SELECT ON mysqltest1.t1 TO mysqltest_1@localhost; + +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +SELECT USER(); +SHOW GRANTS; +--error ER_TABLEACCESS_DENIED_ERROR +RENAME TABLE t1 TO t2; +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 RENAME TO t2; +--disconnect conn42 +--connection default +GRANT DROP ON mysqltest1.t1 TO mysqltest_1@localhost; + +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +--error ER_TABLEACCESS_DENIED_ERROR +RENAME TABLE t1 TO t2; +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 RENAME TO t2; +--disconnect conn42 +--connection default +GRANT ALTER ON mysqltest1.t1 TO mysqltest_1@localhost; + +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +SHOW GRANTS; +--error ER_TABLEACCESS_DENIED_ERROR +RENAME TABLE t1 TO t2; +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 RENAME TO t2; +--disconnect conn42 +--connection default +GRANT INSERT, CREATE ON mysqltest1.t1 TO mysqltest_1@localhost; +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +SHOW GRANTS; +--error ER_TABLEACCESS_DENIED_ERROR +--disconnect conn42 +--connection default +GRANT INSERT, SELECT, CREATE, ALTER, DROP ON mysqltest1.t2 TO mysqltest_1@localhost; +DROP TABLE mysqltest1.t2; + +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +SHOW GRANTS; +RENAME TABLE t1 TO t2; +RENAME TABLE t2 TO t1; +ALTER TABLE t1 RENAME TO t2; +ALTER TABLE t2 RENAME TO t1; +--disconnect conn42 +--connection default +REVOKE DROP, INSERT ON mysqltest1.t1 FROM mysqltest_1@localhost; +REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost; + +--connect (conn42,localhost,mysqltest_1,,mysqltest1); +SHOW GRANTS; +--error ER_TABLEACCESS_DENIED_ERROR +RENAME TABLE t1 TO t2; +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 RENAME TO t2; +--disconnect conn42 +--connection default + +DROP USER mysqltest_1@localhost; +DROP DATABASE mysqltest1; + # Working with database-level privileges. --error ER_WRONG_STRING_LENGTH |