#At file:///home/anurag/mysqlsrc/mysql-5.1-bugteam/ based on revid:bernt.johnsen@stripped
2827 Anurag Shekhar 2009-02-27
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 faut.
To fix this problem disabled delete while scanning if the table appears in
join list.
modified:
mysql-test/r/heap_btree.result
mysql-test/t/heap_btree.test
sql/sql_delete.cc
per-file messages:
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 to test delete while self join on heap engine.
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 file 'mysql-test/r/heap_btree.result'
--- a/mysql-test/r/heap_btree.result 2007-10-19 20:12:14 +0000
+++ b/mysql-test/r/heap_btree.result 2009-02-27 10:18:37 +0000
@@ -337,3 +337,7 @@ NULL NULL
NULL 1
drop table t1;
End of 5.0 tests
+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;
=== modified file 'mysql-test/t/heap_btree.test'
--- a/mysql-test/t/heap_btree.test 2007-10-19 20:12:14 +0000
+++ b/mysql-test/t/heap_btree.test 2009-02-27 10:18:37 +0000
@@ -255,3 +255,12 @@ drop table t1;
--echo End of 5.0 tests
+#
+# 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;
+
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-02-09 22:51:59 +0000
+++ b/sql/sql_delete.cc 2009-02-27 10:18:37 +0000
@@ -582,6 +582,11 @@ int mysql_multi_delete_prepare(THD *thd)
}
}
}
+ /*
+ Reset the exclude flag to false so it doesn't interfares
+ with further calles to unique_table
+ */
+ lex->select_lex.exclude_from_table_unique_test = false;
DBUG_RETURN(FALSE);
}
@@ -617,11 +622,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++)