Below is the list of changes that have just been committed into a local
4.1 repository of svoj. When svoj does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-09-13 15:39:16+05:00, svoj@stripped +5 -0
BUG#30590 - delete from memory table with composite btree primary key
DELETE query against memory table with btree index may remove
not all matching rows. This happens only when DELETE uses
index read method to find matching rows. E.g. for queries
like DELETE FROM t1 WHERE a=1.
Fixed by reverting fix for BUG9719 and applying proper solution.
heap/hp_delete.c@stripped, 2007-09-13 15:39:15+05:00, svoj@stripped +0 -3
Reverted fix for BUG9719 as it makes queries like
DELETE FROM t1 WHERE a=1 to remove not all matching
rows (assuming this is memory table and there is btree
key over `a`).
This happens because we calculate info->lastkey_len in
heap_rkey(). When we enter heap_rnext(), info->lastkey_len
is 0 (set by hp_rb_delete_key()). We need to preserve
info->lastkey_len in this situation, otherwise
tree_search_key() will always return smallest value in
a tree.
heap/hp_rfirst.c@stripped, 2007-09-13 15:39:15+05:00, svoj@stripped +11 -0
If we're performing index_first on a table that was taken from
table cache, info->lastkey_len is initialized to previous query.
Thus we set info->lastkey_len to proper value for subsequent
heap_rnext() calls.
This is needed for DELETE queries only, otherwise this variable is
not used.
Note that the same workaround may be needed for heap_rlast(), but
for now heap_rlast() is never used for DELETE queries.
heap/hp_rnext.c@stripped, 2007-09-13 15:39:15+05:00, svoj@stripped +29 -0
An optimization for DELETE queries that use index_first()/index_next().
Use faster tree_search_edge() instead of tree_search_key().
mysql-test/r/heap_btree.result@stripped, 2007-09-13 15:39:15+05:00, svoj@stripped +7 -0
A test case for BUG#30590.
mysql-test/t/heap_btree.test@stripped, 2007-09-13 15:39:15+05:00, svoj@stripped +9 -0
A test case for BUG#30590.
diff -Nrup a/heap/hp_delete.c b/heap/hp_delete.c
--- a/heap/hp_delete.c 2006-08-02 22:06:58 +05:00
+++ b/heap/hp_delete.c 2007-09-13 15:39:15 +05:00
@@ -73,10 +73,7 @@ int hp_rb_delete_key(HP_INFO *info, regi
int res;
if (flag)
- {
info->last_pos= NULL; /* For heap_rnext/heap_rprev */
- info->lastkey_len= 0;
- }
custom_arg.keyseg= keyinfo->seg;
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
diff -Nrup a/heap/hp_rfirst.c b/heap/hp_rfirst.c
--- a/heap/hp_rfirst.c 2004-11-22 17:53:12 +04:00
+++ b/heap/hp_rfirst.c 2007-09-13 15:39:15 +05:00
@@ -36,6 +36,17 @@ int heap_rfirst(HP_INFO *info, byte *rec
sizeof(byte*));
info->current_ptr = pos;
memcpy(record, pos, (size_t)share->reclength);
+ /*
+ If we're performing index_first on a table that was taken from
+ table cache, info->lastkey_len is initialized to previous query.
+ Thus we set info->lastkey_len to proper value for subsequent
+ heap_rnext() calls.
+ This is needed for DELETE queries only, otherwise this variable is
+ not used.
+ Note that the same workaround may be needed for heap_rlast(), but
+ for now heap_rlast() is never used for DELETE queries.
+ */
+ info->lastkey_len= 0;
info->update = HA_STATE_AKTIV;
}
else
diff -Nrup a/heap/hp_rnext.c b/heap/hp_rnext.c
--- a/heap/hp_rnext.c 2002-05-23 19:26:10 +05:00
+++ b/heap/hp_rnext.c 2007-09-13 15:39:15 +05:00
@@ -34,11 +34,40 @@ int heap_rnext(HP_INFO *info, byte *reco
heap_rb_param custom_arg;
if (info->last_pos)
+ {
+ /*
+ We enter this branch for non-DELETE queries after heap_rkey()
+ or heap_rfirst(). As last key position (info->last_pos) is available,
+ we only need to climb the tree using tree_search_next().
+ */
pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
offsetof(TREE_ELEMENT, left),
offsetof(TREE_ELEMENT, right));
+ }
+ else if (!info->lastkey_len)
+ {
+ /*
+ We enter this branch only for DELETE queries after heap_rfirst(). E.g.
+ DELETE FROM t1 WHERE a<10. As last key position is not available
+ (last key is removed by heap_delete()), we must restart search as it
+ is done in heap_rfirst().
+
+ It should be safe to handle this situation without this branch. That is
+ branch below should find smallest element in a tree as lastkey_len is
+ zero. tree_search_edge() is a kind of optimisation here as it should be
+ faster than tree_search_key().
+ */
+ pos= tree_search_edge(&keyinfo->rb_tree, info->parents,
+ &info->last_pos, offsetof(TREE_ELEMENT, left));
+ }
else
{
+ /*
+ We enter this branch only for DELETE queries after heap_rkey(). E.g.
+ DELETE FROM t1 WHERE a=10. As last key position is not available
+ (last key is removed by heap_delete()), we must restart search as it
+ is done in heap_rkey().
+ */
custom_arg.keyseg = keyinfo->seg;
custom_arg.key_length = info->lastkey_len;
custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND;
diff -Nrup a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
--- a/mysql-test/r/heap_btree.result 2007-03-28 11:51:10 +05:00
+++ b/mysql-test/r/heap_btree.result 2007-09-13 15:39:15 +05:00
@@ -307,4 +307,11 @@ UNIQUE USING BTREE(c1)
) ENGINE= MEMORY DEFAULT CHARSET= utf8;
INSERT INTO t1 VALUES('1'), ('2');
DROP TABLE t1;
+CREATE TABLE t1 (a INT, KEY USING BTREE(a)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES(1),(2),(2);
+DELETE FROM t1 WHERE a=2;
+SELECT * FROM t1;
+a
+1
+DROP TABLE t1;
End of 4.1 tests
diff -Nrup a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
--- a/mysql-test/t/heap_btree.test 2007-03-28 11:51:10 +05:00
+++ b/mysql-test/t/heap_btree.test 2007-09-13 15:39:15 +05:00
@@ -213,4 +213,13 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES('1'), ('2');
DROP TABLE t1;
+#
+# BUG#30590 - delete from memory table with composite btree primary key
+#
+CREATE TABLE t1 (a INT, KEY USING BTREE(a)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES(1),(2),(2);
+DELETE FROM t1 WHERE a=2;
+SELECT * FROM t1;
+DROP TABLE t1;
+
--echo End of 4.1 tests
| Thread |
|---|
| • bk commit into 4.1 tree (svoj:1.2680) BUG#30590 | Sergey Vojtovich | 13 Sep |