Commit 8f521b41 authored by Alexander Nozdrin's avatar Alexander Nozdrin

Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111

   Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
 
   The server crashed on an attempt to optimize a MERGE table with
   non-existent child table.
 
   mysql_admin_table() relied on the table to be successfully open
   if a table object had been allocated.
 
   Changed code to check return value of the open function before
   calling a handler:: function on it.

mysql-test/r/merge.result:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Updated result file.
mysql-test/t/merge.test:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Changed tests to respect changed TEMPORARY MERGE locking (unrelated).
      Changed tests to respect changed CREATE TABLE ... LIKE (unrelated).
      Changed tests to respect that no new tables can be created
      under LOCK TABLE (unrelated).
      Added test for Bug#47633.
  Changed error numbers to symbolic names.
  Added test for child locking for ALTER under LOCK TABLE.
  
  Since Bug 36171 is not pushed yet, not the whole patch has been backported.
mysys/my_delete.c:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Fixed error reporting.
      Fixed indentation.
mysys/my_mmap.c:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Added DBUG.
sql/item_func.cc:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
  Added Debug Sync point, required by merge_sync.test.
sql/sql_table.cc:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Do not call handler:: functions if the table was not opened
      successfully.
  Added Debug Sync point, required by merge_sync.test.
storage/myisam/mi_check.c:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
      Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
      Unmap memory before exchanging data files. Needed on Windows.
storage/myisammrg/ha_myisammrg.cc:
  Backport of revid:ingo.struewing@sun.com-20091223200354-r2uzbdkj2v6yv111
  Added Debug Sync point, required by merge_sync.test.
  
  merge_sync.test will be introduced by a patch for Bug 36171,
  which is not pushed yet.
parent 47edc4ca
......@@ -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;
......
......@@ -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;
#
......@@ -2104,6 +2108,14 @@ DROP TRIGGER t2_au;
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
......@@ -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"
......
......@@ -102,9 +102,19 @@ int nt_share_delete(const char *name, myf MyFlags)
{
if (DeleteFile(buf))
DBUG_RETURN(0);
else if ((my_errno= GetLastError()) == 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
else
my_errno= errno;
}
else
my_errno= errno;
if (MyFlags & (MY_FAE+MY_WME))
......
......@@ -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)
......
......@@ -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))))
......
......@@ -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)
......
......@@ -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 ?
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment