summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <antony@pcg5ppc.xiphis.org>2007-10-19 13:04:30 -0700
committerunknown <antony@pcg5ppc.xiphis.org>2007-10-19 13:04:30 -0700
commit893dc3009e2507a956531e18bab493a912986ddc (patch)
tree1d419e4dfdb8c4328c5b9aaba767d6d5ae5eb904
parentd14ada56b8efa02889b926689ca1d88792d41ea7 (diff)
parent01b3173e03071afef367394a6c352f8022483f7e (diff)
downloadmariadb-git-893dc3009e2507a956531e18bab493a912986ddc.tar.gz
Merge anubis.xiphis.org:/usr/home/antony/work/mysql-5.0-engines
into anubis.xiphis.org:/usr/home/antony/work/mysql-5.0-engines.merge mysql-test/r/heap_btree.result: Auto merged mysql-test/t/heap_btree.test: Auto merged
-rw-r--r--heap/hp_delete.c3
-rw-r--r--heap/hp_rfirst.c11
-rw-r--r--heap/hp_rnext.c29
-rw-r--r--mysql-test/r/heap_btree.result7
-rw-r--r--mysql-test/r/merge.result5
-rw-r--r--mysql-test/t/heap_btree.test9
-rw-r--r--mysql-test/t/merge.test14
7 files changed, 75 insertions, 3 deletions
diff --git a/heap/hp_delete.c b/heap/hp_delete.c
index 637e5f1a497..e5c8dfcef01 100644
--- a/heap/hp_delete.c
+++ b/heap/hp_delete.c
@@ -72,10 +72,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
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 --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c
index d1842949421..6acfe8e0ed6 100644
--- a/heap/hp_rfirst.c
+++ b/heap/hp_rfirst.c
@@ -35,6 +35,17 @@ int heap_rfirst(HP_INFO *info, byte *record, int inx)
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 --git a/heap/hp_rnext.c b/heap/hp_rnext.c
index 3b436fe87aa..4ecbe779107 100644
--- a/heap/hp_rnext.c
+++ b/heap/hp_rnext.c
@@ -33,11 +33,40 @@ int heap_rnext(HP_INFO *info, byte *record)
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 --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index 21f5a549529..c20dfbe80d2 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -307,6 +307,13 @@ 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
CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
INSERT INTO t1 VALUES(0);
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 42669eeb66f..24a56fbf575 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -876,4 +876,9 @@ CHECK TABLE tm1;
Table Op Msg_type Msg_text
test.tm1 check status OK
DROP TABLE tm1, t1, t2;
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
+CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index 5a238fc32c8..76c319c0bc1 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -213,6 +213,15 @@ 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
#
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index c3e5cef5e63..b5c1a01fe8e 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -507,4 +507,18 @@ SELECT * FROM tm1;
CHECK TABLE tm1;
DROP TABLE tm1, t1, t2;
+#
+# Bug#15522 - create ... select and with merge tables
+#
+# This was fixed together with Bug#20662 (Infinite loop in CREATE TABLE
+# IF NOT EXISTS ... SELECT with locked tables).
+# The new behavior for MERGE tables is consistent with the
+# CREATE TABLE SELECT behavior for ordinary tables.
+#
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
+--error ER_UPDATE_TABLE_USED
+CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests