From 3ca9164590151e932ef4750b78e0b927788a3a9a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Sep 2006 14:23:41 +0200 Subject: [PATCH] Bug#20789 Merge Subtable Rename Causes Crash - When an ALTER TABLE RENAME is performed on windows, the files are closed and their cached file descriptors are marked invalid. Performing INSERT, UPDATE or SELECT on the associated merge table causes a server crash on windows. This patch adds a test for bad file descriptors when a table attempts a lock. If a bad descriptor is found an error is thrown. An additional FLUSH TABLES will be necessary to further operate on the associated merge table. myisam/mi_locking.c: This patch prevents the windows built to crash if the file is closed. mysql-test/r/windows.result: Added test case for the windows built. mysql-test/t/windows.test: Added test case for the windows built. --- myisam/mi_locking.c | 11 +++++++++++ mysql-test/r/windows.result | 28 ++++++++++++++++++++++++++ mysql-test/t/windows.test | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 8d48c5242e5..4f8420d4b12 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -223,7 +223,18 @@ int mi_lock_database(MI_INFO *info, int lock_type) default: break; /* Impossible */ } + } +#ifdef __WIN__ + else + { + /* + The file has been closed and kfile is -1. + See mi_extra.c about implementation of + HA_EXTRA_PREPARE_FOR_DELETE. + */ + error=HA_ERR_NO_SUCH_TABLE; } +#endif pthread_mutex_unlock(&share->intern_lock); #if defined(FULL_LOG) || defined(_lint) lock_type|=(int) (flag << 8); /* Set bit to set if real lock */ diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result index 039c5b1476e..e3241daf719 100644 --- a/mysql-test/r/windows.result +++ b/mysql-test/r/windows.result @@ -6,3 +6,31 @@ use prn; ERROR 42000: Unknown database 'prn' create table nu (a int); drop table nu; +CREATE TABLE `t1` ( +`TIM` datetime NOT NULL, +`VAL` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE `t2` ( +`TIM` datetime NOT NULL, +`VAL` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE `mt` ( +`TIM` datetime NOT NULL, +`VAL` double default NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST +UNION=(`t1`,`t2`); +INSERT INTO mt VALUES ('2006-01-01',0); +ALTER TABLE `t2` RENAME TO `t`; +INSERT INTO mt VALUES ('2006-01-01',0); +ERROR HY000: Can't lock file (errno: 155) +select * from mt; +ERROR HY000: Can't lock file (errno: 155) +FLUSH TABLES; +select * from mt; +ERROR HY000: Can't find file: 'mt' (errno: 2) +ALTER TABLE `t` RENAME TO `t2`; +INSERT INTO mt VALUES ('2006-01-01',0); +select * from mt; +TIM VAL +2006-01-01 00:00:00 0 +2006-01-01 00:00:00 0 diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test index d6bcfeb8cb3..79517df6517 100644 --- a/mysql-test/t/windows.test +++ b/mysql-test/t/windows.test @@ -18,3 +18,42 @@ create table nu (a int); drop table nu; # End of 4.1 tests + +# +# Bug #20789: Merge Subtable Rename Causes Crash +# +CREATE TABLE `t1` ( + `TIM` datetime NOT NULL, + `VAL` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE `t2` ( + `TIM` datetime NOT NULL, + `VAL` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE `mt` ( + `TIM` datetime NOT NULL, + `VAL` double default NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST +UNION=(`t1`,`t2`); + +# insert into the merge table and thus open it. +INSERT INTO mt VALUES ('2006-01-01',0); + +# Alter one of the tables that are part of the merge table +ALTER TABLE `t2` RENAME TO `t`; + +# Insert into the merge table that has just been altered +--error 1015 +INSERT INTO mt VALUES ('2006-01-01',0); +--error 1015 +select * from mt; + +FLUSH TABLES; +--error 1017 +select * from mt; + +# Alter one of the tables that are part of the merge table +ALTER TABLE `t` RENAME TO `t2`; +INSERT INTO mt VALUES ('2006-01-01',0); +select * from mt; +