#At file:///home/svoj/devel/bzr-mysql/mysql-5.0-bugteam-bug32047/
2733 Sergey Vojtovich 2009-01-29
BUG#32047 - 'Spurious' errors while opening MERGE tables
Accessing well defined MERGE table may return an error
stating that the merge table is incorrectly defined. This
happens if MERGE child tables were accessed before and we
failed to open another incorrectly defined MERGE table in
this connection.
The problem was incorrect usage of my_errno.
modified:
myisammrg/myrg_open.c
mysql-test/r/merge.result
mysql-test/t/merge.test
per-file messages:
myisammrg/myrg_open.c
Setting my_error and attempting to check it's value later in a high-level
function is generally a bad idea. Because there may be lower level function
calls, which may set my_errno, in between.
With this patch, if we failed to open compatible child table, we set
my_errno at the end (error handling part) of open function, which is
safe.
mysql-test/r/merge.result
A test case for BUG#32047.
mysql-test/t/merge.test
A test case for BUG#32047.
=== modified file 'myisammrg/myrg_open.c'
--- a/myisammrg/myrg_open.c 2007-06-05 23:42:41 +0000
+++ b/myisammrg/myrg_open.c 2009-01-29 11:51:22 +0000
@@ -40,6 +40,7 @@ MYRG_INFO *myrg_open(const char *name, i
IO_CACHE file;
MI_INFO *isam=0;
uint found_merge_insert_method= 0;
+ my_bool bad_children= FALSE;
DBUG_ENTER("myrg_open");
LINT_INIT(key_parts);
@@ -89,13 +90,13 @@ MYRG_INFO *myrg_open(const char *name, i
fn_format(buff, buff, "", "", 0);
if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
{
- my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
+ bad_children= TRUE;
if (handle_locking & HA_OPEN_FOR_REPAIR)
{
myrg_print_wrong_table(buff);
continue;
}
- goto err;
+ goto bad_children;
}
if (!m_info) /* First file */
{
@@ -122,13 +123,13 @@ MYRG_INFO *myrg_open(const char *name, i
files++;
if (m_info->reclength != isam->s->base.reclength)
{
- my_errno=HA_ERR_WRONG_MRG_TABLE_DEF;
+ bad_children= TRUE;
if (handle_locking & HA_OPEN_FOR_REPAIR)
{
myrg_print_wrong_table(buff);
continue;
}
- goto err;
+ goto bad_children;
}
m_info->options|= isam->s->options;
m_info->records+= isam->state->records;
@@ -141,8 +142,8 @@ MYRG_INFO *myrg_open(const char *name, i
m_info->tables);
}
- if (my_errno == HA_ERR_WRONG_MRG_TABLE_DEF)
- goto err;
+ if (bad_children)
+ goto bad_children;
if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO),
MYF(MY_WME | MY_ZEROFILL))))
goto err;
@@ -170,6 +171,8 @@ MYRG_INFO *myrg_open(const char *name, i
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(m_info);
+bad_children:
+ my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
err:
save_errno=my_errno;
switch (errpos) {
=== modified file 'mysql-test/r/merge.result'
--- a/mysql-test/r/merge.result 2008-03-14 15:38:22 +0000
+++ b/mysql-test/r/merge.result 2009-01-29 11:51:22 +0000
@@ -940,4 +940,15 @@ m1 CREATE TABLE `m1` (
`a` int(11) default NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, m1;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a VARCHAR(10));
+CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2);
+CREATE TABLE m2(a INT) ENGINE=MERGE UNION=(t1);
+SELECT * FROM t1;
+a
+SELECT * FROM m1;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT * FROM m2;
+a
+DROP TABLE t1, t2, m1, m2;
End of 5.0 tests
=== modified file 'mysql-test/t/merge.test'
--- a/mysql-test/t/merge.test 2008-03-14 15:38:22 +0000
+++ b/mysql-test/t/merge.test 2009-01-29 11:51:22 +0000
@@ -556,4 +556,17 @@ ALTER TABLE m1 UNION=();
SHOW CREATE TABLE m1;
DROP TABLE t1, m1;
+#
+# BUG#32047 - 'Spurious' errors while opening MERGE tables
+#
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a VARCHAR(10));
+CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2);
+CREATE TABLE m2(a INT) ENGINE=MERGE UNION=(t1);
+SELECT * FROM t1;
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM m1;
+SELECT * FROM m2;
+DROP TABLE t1, t2, m1, m2;
+
--echo End of 5.0 tests