#At file:///home/anurag/mysqlsrc/mysql-5.0-bugteam-39918/ based on revid:sergey.glukhov@stripped
2725 Anurag Shekhar 2009-04-15
Bug #39918 memory (heap) engine crashing with b-tree index and DELETE with seg fault
While evaluating self join with delete server uses two instance of handler
(with both holding reference to same file). During query evaluation last_pos
is cached in handler to improve search performance. But in the mean while
second handler is used to delete the node last_pos is holding. This makes
the last_pos an invalid and when accessed results in segmentation fault.
To fix this problem disabled delete while scanning if the table appears in
join list.
@ mysql-test/r/heap_btree.result
Updated test result after adding new test for this bug.
@ mysql-test/t/heap_btree.test
Added a new test based on the bug.
@ sql/sql_delete.cc
Updated to check if the files in delete list appears in join list and disable
delete while scanning, if it appears.
modified:
mysql-test/r/heap_btree.result
mysql-test/t/heap_btree.test
sql/sql_delete.cc
=== modified file 'mysql-test/r/heap_btree.result'
--- a/mysql-test/r/heap_btree.result 2007-10-19 20:04:30 +0000
+++ b/mysql-test/r/heap_btree.result 2009-04-15 11:00:45 +0000
@@ -336,4 +336,8 @@ a b
NULL NULL
NULL 1
drop table t1;
+CREATE TABLE t1(a INT, KEY USING BTREE (a)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES(1),(1);
+DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
+DROP TABLE t1;
End of 5.0 tests
=== modified file 'mysql-test/t/heap_btree.test'
--- a/mysql-test/t/heap_btree.test 2007-10-19 20:04:30 +0000
+++ b/mysql-test/t/heap_btree.test 2009-04-15 11:00:45 +0000
@@ -253,5 +253,13 @@ insert into t1 values (1, 1), (3, 3), (2
select * from t1 where a is null;
drop table t1;
+#
+# bug#39918 - memory (heap) engine crashing while executing self join with delete
+#
+
+CREATE TABLE t1(a INT, KEY USING BTREE (a)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES(1),(1);
+DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a;
+DROP TABLE t1;
--echo End of 5.0 tests
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-03-27 05:19:50 +0000
+++ b/sql/sql_delete.cc 2009-04-15 11:00:45 +0000
@@ -503,6 +503,11 @@ int mysql_multi_delete_prepare(THD *thd)
}
}
}
+ /*
+ Reset the exclude flag to false so it doesn't interfare
+ with further calls to unique_table
+ */
+ lex->select_lex.exclude_from_table_unique_test= FALSE;
DBUG_RETURN(FALSE);
}
@@ -538,11 +543,23 @@ multi_delete::initialize_tables(JOIN *jo
DBUG_RETURN(1);
table_map tables_to_delete_from=0;
+ delete_while_scanning= 1;
for (walk= delete_tables; walk; walk= walk->next_local)
+ {
tables_to_delete_from|= walk->table->map;
+ if (unique_table (thd, walk, join->tables_list, false))
+ {
+ /*
+ If the table we are going to delete from appears
+ in join, we need to defer delete. So the delete
+ doesn't interfers with the scaning of results.
+ */
+ delete_while_scanning= 0;
+ }
+ }
+
walk= delete_tables;
- delete_while_scanning= 1;
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
tab < end;
tab++)
Attachment: [text/bzr-bundle] bzr/anurag.shekhar@sun.com-20090415110045-1ohym9xuxehzba53.bundle