Loading heap/hp_delete.c +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading heap/hp_rfirst.c +11 −0 Original line number Diff line number Diff line Loading @@ -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 Loading heap/hp_rnext.c +29 −0 Original line number Diff line number Diff line Loading @@ -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; Loading mysql-test/r/heap_btree.result +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading mysql-test/r/merge.result +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
heap/hp_delete.c +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading
heap/hp_rfirst.c +11 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
heap/hp_rnext.c +29 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
mysql-test/r/heap_btree.result +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
mysql-test/r/merge.result +5 −0 Original line number Diff line number Diff line Loading @@ -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