diff options
author | unknown <antony@pcg5ppc.xiphis.org> | 2007-10-19 13:04:30 -0700 |
---|---|---|
committer | unknown <antony@pcg5ppc.xiphis.org> | 2007-10-19 13:04:30 -0700 |
commit | 893dc3009e2507a956531e18bab493a912986ddc (patch) | |
tree | 1d419e4dfdb8c4328c5b9aaba767d6d5ae5eb904 | |
parent | d14ada56b8efa02889b926689ca1d88792d41ea7 (diff) | |
parent | 01b3173e03071afef367394a6c352f8022483f7e (diff) | |
download | mariadb-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.c | 3 | ||||
-rw-r--r-- | heap/hp_rfirst.c | 11 | ||||
-rw-r--r-- | heap/hp_rnext.c | 29 | ||||
-rw-r--r-- | mysql-test/r/heap_btree.result | 7 | ||||
-rw-r--r-- | mysql-test/r/merge.result | 5 | ||||
-rw-r--r-- | mysql-test/t/heap_btree.test | 9 | ||||
-rw-r--r-- | mysql-test/t/merge.test | 14 |
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 |