summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
authorAnurag Shekhar <anurag.shekhar@sun.com>2009-05-06 13:37:10 +0530
committerAnurag Shekhar <anurag.shekhar@sun.com>2009-05-06 13:37:10 +0530
commit609a794b15fe44408fa47582e798147d1ffe3463 (patch)
treef1f1fdf120a0888c698826d038a5087ebfa0fd5c /sql/sql_delete.cc
parentf0791b8b6b02286a7a01b7659050f3bd900a3529 (diff)
downloadmariadb-git-609a794b15fe44408fa47582e798147d1ffe3463.tar.gz
Bug #39918 memory (heap) engine crashing with b-tree index and DELETE
with seg fault Multiple-table DELETE from a table joined to itself may cause server crash. This was originally discovered with MEMORY engine, but may affect other engines with different symptoms. The problem was that the server violated SE API by performing parallel table scan in one handler and removing records in another (delete on the fly optimization). mysql-test/r/heap_btree.result: Updated test result after adding new test for this bug. mysql-test/t/heap_btree.test: Updated test result after adding new test for the bug report. 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.
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a757b7c28a5..5307a4426c5 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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,24 @@ multi_delete::initialize_tables(JOIN *join)
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 (delete_while_scanning &&
+ 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++)