diff options
-rw-r--r-- | mysql-test/r/merge.result | 33 | ||||
-rw-r--r-- | mysql-test/t/merge.test | 44 | ||||
-rw-r--r-- | mysys/my_delete.c | 32 | ||||
-rw-r--r-- | mysys/my_mmap.c | 18 | ||||
-rw-r--r-- | sql/item_func.cc | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 7 | ||||
-rw-r--r-- | storage/myisam/mi_check.c | 15 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 2 |
8 files changed, 124 insertions, 30 deletions
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 8f7ebb06c06..87d4f75dc8d 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -1191,6 +1191,9 @@ SHOW CREATE TABLE t4; ERROR HY000: Table 't4' was not locked with LOCK TABLES INSERT INTO t4 VALUES (4); ERROR HY000: Table 't4' was not locked with LOCK TABLES +# Temporary tables can be created in spite of LOCK TABLES. +# If the temporary MERGE table uses the locked children only, +# it can even be used. CREATE TEMPORARY TABLE t4 LIKE t3; SHOW CREATE TABLE t4; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist @@ -1672,6 +1675,7 @@ c1 33 DELETE FROM t4 WHERE c1 = 33; DROP TRIGGER t3_ai; +UNLOCK TABLES; # # Trigger with table use on child DELETE FROM t4 WHERE c1 = 4; @@ -1854,9 +1858,9 @@ ALTER TABLE t2 UNION=(t3,t1); SELECT * FROM t2; ERROR HY000: Table 't3' is differently defined or of non-MyISAM type or doesn't exist DROP TABLE t1, t2, t3; -CREATE TABLE t1 (c1 INT) ENGINE= MyISAM; -CREATE TABLE t2 (c1 INT) ENGINE= MyISAM; -CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2); +CREATE TABLE t1 (c1 INT) ENGINE=MyISAM; +CREATE TABLE t2 (c1 INT) ENGINE=MyISAM; +CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2); INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (2); SELECT * FROM t3; @@ -2635,6 +2639,17 @@ DROP TRIGGER t2_au; DROP FUNCTION f1; DROP TABLE tm1, t1, t2, t3, t4, t5; # +# Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE +# +CREATE TEMPORARY TABLE t1 (c1 INT); +ALTER TABLE t1 ENGINE=MERGE UNION(t_not_exists,t1); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize Error Table 'test.t_not_exists' doesn't exist +test.t1 optimize Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.t1 optimize note The storage engine for the table doesn't support optimize +DROP TABLE t1; +# # Bug47098 assert in MDL_context::destroy on HANDLER # <damaged merge table> OPEN # @@ -2700,6 +2715,18 @@ ALTER TABLE m1 ADD INDEX (c1); UNLOCK TABLES; DROP TABLE m1, t1; # +# If children are to be altered, they need an explicit lock. +# +CREATE TABLE t1 (c1 INT); +CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1); +LOCK TABLE m1 WRITE; +ALTER TABLE t1 ADD INDEX (c1); +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +LOCK TABLE m1 WRITE, t1 WRITE; +ALTER TABLE t1 ADD INDEX (c1); +UNLOCK TABLES; +DROP TABLE m1, t1; +# # Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter" # drop tables if exists t1, m1, m2; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 29c0eae1df6..a06da03cbcd 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -457,7 +457,7 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1); SELECT * FROM t2; DROP TABLE t1, t2; CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3); ---error 1168 +--error ER_WRONG_MRG_TABLE SELECT * FROM t2; DROP TABLE t2; @@ -549,11 +549,11 @@ drop table t1; # CREATE TABLE fails # CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2); ---error 1168 +--error ER_WRONG_MRG_TABLE SELECT * FROM tm1; CHECK TABLE tm1; CREATE TABLE t1(a INT); ---error 1168 +--error ER_WRONG_MRG_TABLE SELECT * FROM tm1; CHECK TABLE tm1; CREATE TABLE t2(a BLOB); @@ -887,6 +887,9 @@ CREATE TABLE t4 LIKE t3; SHOW CREATE TABLE t4; --error ER_TABLE_NOT_LOCKED INSERT INTO t4 VALUES (4); +--echo # Temporary tables can be created in spite of LOCK TABLES. +--echo # If the temporary MERGE table uses the locked children only, +--echo # it can even be used. CREATE TEMPORARY TABLE t4 LIKE t3; --error ER_WRONG_MRG_TABLE SHOW CREATE TABLE t4; @@ -913,7 +916,7 @@ DROP TABLE t4; --echo # 2. Normal rename. SELECT * FROM t3 ORDER BY c1; RENAME TABLE t2 TO t5; ---error 1168 +--error ER_WRONG_MRG_TABLE SELECT * FROM t3 ORDER BY c1; RENAME TABLE t5 TO t2; SELECT * FROM t3 ORDER BY c1; @@ -931,7 +934,7 @@ UNLOCK TABLES; --echo # --echo # 4. Alter table rename. ALTER TABLE t2 RENAME TO t5; ---error 1168 +--error ER_WRONG_MRG_TABLE SELECT * FROM t3 ORDER BY c1; ALTER TABLE t5 RENAME TO t2; SELECT * FROM t3 ORDER BY c1; @@ -1170,6 +1173,7 @@ SELECT @a; SELECT * FROM t4 ORDER BY c1; DELETE FROM t4 WHERE c1 = 33; DROP TRIGGER t3_ai; +UNLOCK TABLES; --echo # --echo # Trigger with table use on child DELETE FROM t4 WHERE c1 = 4; @@ -1273,11 +1277,12 @@ DROP TABLE t1, t2, t3; # # Bug#25038 - Waiting TRUNCATE +# Truncate failed with error message when table was in use by MERGE. # # Show that truncate of child table after use of parent table works. -CREATE TABLE t1 (c1 INT) ENGINE= MyISAM; -CREATE TABLE t2 (c1 INT) ENGINE= MyISAM; -CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2); +CREATE TABLE t1 (c1 INT) ENGINE=MyISAM; +CREATE TABLE t2 (c1 INT) ENGINE=MyISAM; +CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2); INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (2); SELECT * FROM t3; @@ -1429,7 +1434,6 @@ FLUSH TABLES m1, t1; UNLOCK TABLES; DROP TABLE t1, m1; - # # Bug#35068 - Assertion fails when reading from i_s.tables # and there is incorrect merge table @@ -1816,7 +1820,7 @@ CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,mysql_test1.t2) INSERT INTO t1 VALUES (1); INSERT INTO mysql_test1.t2 VALUES (2); SELECT * FROM m1; -#--copy_file $MYSQLTEST_VARDIR/master-data/test/m1.MRG /tmp/mysql-test-m1.MRG +#--copy_file $MYSQLTEST_DATADIR/test/m1.MRG /tmp/mysql-test-m1.MRG DROP TABLE t1, mysql_test1.t2, m1; DROP DATABASE mysql_test1; # @@ -2105,6 +2109,14 @@ DROP FUNCTION f1; DROP TABLE tm1, t1, t2, t3, t4, t5; --echo # +--echo # Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE +--echo # +CREATE TEMPORARY TABLE t1 (c1 INT); +ALTER TABLE t1 ENGINE=MERGE UNION(t_not_exists,t1); +OPTIMIZE TABLE t1; +DROP TABLE t1; + +--echo # --echo # Bug47098 assert in MDL_context::destroy on HANDLER --echo # <damaged merge table> OPEN --echo # @@ -2186,6 +2198,18 @@ ALTER TABLE m1 ADD INDEX (c1); UNLOCK TABLES; DROP TABLE m1, t1; +--echo # +--echo # If children are to be altered, they need an explicit lock. +--echo # +CREATE TABLE t1 (c1 INT); +CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1); +LOCK TABLE m1 WRITE; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +ALTER TABLE t1 ADD INDEX (c1); +LOCK TABLE m1 WRITE, t1 WRITE; +ALTER TABLE t1 ADD INDEX (c1); +UNLOCK TABLES; +DROP TABLE m1, t1; --echo # --echo # Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter" diff --git a/mysys/my_delete.c b/mysys/my_delete.c index edee1c4e875..4a23fedb5ab 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -93,23 +93,33 @@ int nt_share_delete(const char *name, myf MyFlags) name, buf, errno)); break; } - + if (errno == ERROR_FILE_NOT_FOUND) { - my_errno= ENOENT; // marking, that `name' doesn't exist + my_errno= ENOENT; // marking, that `name' doesn't exist } else if (errno == 0) { - if (DeleteFile(buf)) - DBUG_RETURN(0); - else if ((my_errno= GetLastError()) == 0) - my_errno= ENOENT; // marking, that `buf' doesn't exist - } else - my_errno= errno; - + if (DeleteFile(buf)) + DBUG_RETURN(0); + /* + The below is more complicated than necessary. For some reason, the + assignment to my_errno clears the error number, which is retrieved + by GetLastError() (VC2005EE). Assigning to errno first, allows to + retrieve the correct value. + */ + errno= GetLastError(); + if (errno == 0) + my_errno= ENOENT; // marking, that `buf' doesn't exist + else + my_errno= errno; + } + else + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) - my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)), - name, my_errno); + my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)), + name, my_errno); DBUG_RETURN(-1); } #endif diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c index 303d8efaf30..82ee1562bc2 100644 --- a/mysys/my_mmap.c +++ b/mysys/my_mmap.c @@ -38,13 +38,16 @@ void *my_mmap(void *addr, size_t len, int prot, HANDLE hFileMap; LPVOID ptr; HANDLE hFile= (HANDLE)my_get_osfhandle(fd); + DBUG_ENTER("my_mmap"); + DBUG_PRINT("mysys", ("map fd: %d", fd)); + if (hFile == INVALID_HANDLE_VALUE) - return MAP_FAILED; + DBUG_RETURN(MAP_FAILED); hFileMap=CreateFileMapping(hFile, &mmap_security_attributes, PAGE_READWRITE, 0, (DWORD) len, NULL); if (hFileMap == 0) - return MAP_FAILED; + DBUG_RETURN(MAP_FAILED); ptr=MapViewOfFile(hFileMap, prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ, @@ -59,14 +62,19 @@ void *my_mmap(void *addr, size_t len, int prot, CloseHandle(hFileMap); if (ptr) - return ptr; + { + DBUG_PRINT("mysys", ("mapped addr: %p", ptr)); + DBUG_RETURN(ptr); + } - return MAP_FAILED; + DBUG_RETURN(MAP_FAILED); } int my_munmap(void *addr, size_t len) { - return UnmapViewOfFile(addr) ? 0 : -1; + DBUG_ENTER("my_munmap"); + DBUG_PRINT("mysys", ("unmap addr: %p", addr)); + DBUG_RETURN(UnmapViewOfFile(addr) ? 0 : -1); } int my_msync(int fd, void *addr, size_t len, int flags) diff --git a/sql/item_func.cc b/sql/item_func.cc index 26c802b8057..efa14c8498b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -51,6 +51,7 @@ #include "sp_rcontext.h" #include "sp.h" #include "set_var.h" +#include "debug_sync.h" #ifdef NO_EMBEDDED_ACCESS_CHECKS #define sp_restore_security_context(A,B) while (0) {} @@ -1941,6 +1942,8 @@ double Item_func_pow::val_real() double Item_func_acos::val_real() { DBUG_ASSERT(fixed == 1); + /* One can use this to defer SELECT processing. */ + DEBUG_SYNC(current_thd, "before_acos_function"); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) volatile double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 902e7fa7b5f..b3213638c4d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4882,6 +4882,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (wait_while_table_is_used(thd, table->table, HA_EXTRA_PREPARE_FOR_RENAME)) goto err; + DEBUG_SYNC(thd, "after_admin_flush"); /* Flush entries in the query cache involving this table. */ query_cache_invalidate3(thd, table->table, 0); /* @@ -5149,7 +5150,11 @@ send_result_message: { if (table->table->s->tmp_table) { - if (open_for_modify) + /* + If the table was not opened successfully, do not try to get + status information. (Bug#47633) + */ + if (open_for_modify && !open_error) table->table->file->info(HA_STATUS_CONST); } else if (open_for_modify || fatal_error) diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 0bcc022a0dc..25267bfb9ea 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1736,6 +1736,21 @@ err: { mysql_file_close(new_file, MYF(0)); info->dfile=new_file= -1; + /* + On Windows, the old data file cannot be deleted if it is either + open, or memory mapped. Closing the file won't remove the memory + map implicilty on Windows. We closed the data file, but we keep + the MyISAM table open. A memory map will be closed on the final + mi_close() only. So we need to unmap explicitly here. After + renaming the new file under the hook, we couldn't use the map of + the old file any more anyway. + */ + if (info->s->file_map) + { + (void) my_munmap((char*) info->s->file_map, + (size_t) info->s->mmaped_length); + info->s->file_map= NULL; + } if (change_to_newfile(share->data_file_name,MI_NAME_DEXT, DATA_TMP_EXT, share->base.raid_chunks, (param->testflag & T_BACKUP_DATA ? diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 63d20f127a1..67b81225b13 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -103,6 +103,7 @@ #include "myrg_def.h" #include "thr_malloc.h" // int_sql_alloc #include "sql_class.h" // THD +#include "debug_sync.h" static handler *myisammrg_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -755,6 +756,7 @@ int ha_myisammrg::attach_children(void) /* Must not call this with attached children. */ DBUG_ASSERT(!this->file->children_attached); + DEBUG_SYNC(current_thd, "before_myisammrg_attach"); /* Must call this with children list in place. */ DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l); |