summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/merge.result33
-rw-r--r--mysql-test/t/merge.test44
-rw-r--r--mysys/my_delete.c32
-rw-r--r--mysys/my_mmap.c18
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/sql_table.cc7
-rw-r--r--storage/myisam/mi_check.c15
-rw-r--r--storage/myisammrg/ha_myisammrg.cc2
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);