mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fixed BUG#51763 Can't delete rows from MEMORY table with HASH key
This commit is contained in:
@ -738,3 +738,23 @@ SELECT c2 FROM t1;
|
||||
c2
|
||||
0
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
color enum('GREEN', 'WHITE') DEFAULT NULL,
|
||||
ts int,
|
||||
PRIMARY KEY (id),
|
||||
KEY color (color) USING HASH
|
||||
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
|
||||
INSERT INTO t1 VALUES("1","GREEN",1);
|
||||
INSERT INTO t1 VALUES("2","GREEN",1);
|
||||
INSERT INTO t1 VALUES("3","GREEN",1);
|
||||
INSERT INTO t1 VALUES("4","GREEN",1);
|
||||
INSERT INTO t1 VALUES("5","GREEN",1);
|
||||
INSERT INTO t1 VALUES("6","GREEN",1);
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
INSERT INTO t1 VALUES("7","GREEN", 2);
|
||||
DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN';
|
||||
SELECT * from t1;
|
||||
id color ts
|
||||
7 GREEN 2
|
||||
DROP TABLE t1;
|
||||
|
@ -485,3 +485,30 @@ INSERT INTO t1 VALUES('', 0);
|
||||
ALTER TABLE t1 MODIFY c1 VARCHAR(101);
|
||||
SELECT c2 FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#51763 Can't delete rows from MEMORY table with HASH key
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
color enum('GREEN', 'WHITE') DEFAULT NULL,
|
||||
ts int,
|
||||
PRIMARY KEY (id),
|
||||
KEY color (color) USING HASH
|
||||
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO t1 VALUES("1","GREEN",1);
|
||||
INSERT INTO t1 VALUES("2","GREEN",1);
|
||||
INSERT INTO t1 VALUES("3","GREEN",1);
|
||||
INSERT INTO t1 VALUES("4","GREEN",1);
|
||||
INSERT INTO t1 VALUES("5","GREEN",1);
|
||||
INSERT INTO t1 VALUES("6","GREEN",1);
|
||||
DELETE FROM t1 WHERE id = 1;
|
||||
INSERT INTO t1 VALUES("7","GREEN", 2);
|
||||
DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN';
|
||||
SELECT * from t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 5.1 tests
|
||||
|
||||
|
@ -47,7 +47,6 @@ int heap_delete(HP_INFO *info, const uchar *record)
|
||||
share->del_link=pos;
|
||||
pos[share->reclength]=0; /* Record deleted */
|
||||
share->deleted++;
|
||||
info->current_hash_ptr=0;
|
||||
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
|
||||
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
|
||||
#endif
|
||||
@ -180,21 +179,50 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
|
||||
}
|
||||
pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
|
||||
if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
|
||||
{ /* Identical key-positions */
|
||||
{
|
||||
/* lastpos and the row in the main bucket entry (pos) has the same hash */
|
||||
if (pos2 != share->records)
|
||||
{
|
||||
empty[0]=lastpos[0];
|
||||
/*
|
||||
The bucket entry was not deleted. Copy lastpos over the
|
||||
deleted entry and update previous link to point to it.
|
||||
*/
|
||||
empty[0]= lastpos[0];
|
||||
hp_movelink(lastpos, pos, empty);
|
||||
if (last_ptr == lastpos)
|
||||
{
|
||||
/*
|
||||
We moved the row that info->current_hash_ptr points to.
|
||||
Update info->current_hash_ptr to point to the new position.
|
||||
*/
|
||||
info->current_hash_ptr= empty;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
pos3= pos; /* Link pos->next after lastpos */
|
||||
}
|
||||
else
|
||||
{
|
||||
pos3= 0; /* Different positions merge */
|
||||
keyinfo->hash_buckets--;
|
||||
/*
|
||||
Shrinking the hash table deleted the main bucket entry for this hash.
|
||||
In this case the last entry was the first key in the key chain.
|
||||
We move things around so that we keep the original key order to ensure
|
||||
that heap_rnext() works.
|
||||
|
||||
- Move the row at the main bucket entry to the empty spot.
|
||||
- Move the last entry first in the new chain.
|
||||
- Link in the first element of the hash.
|
||||
*/
|
||||
empty[0]= pos[0];
|
||||
pos[0]= lastpos[0];
|
||||
hp_movelink(pos, pos, empty);
|
||||
|
||||
/* Update current_hash_ptr if the entry moved */
|
||||
if (last_ptr == lastpos)
|
||||
info->current_hash_ptr= pos;
|
||||
else if (last_ptr == pos)
|
||||
info->current_hash_ptr= empty;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
pos3= 0; /* Different positions merge */
|
||||
keyinfo->hash_buckets--;
|
||||
empty[0]=lastpos[0];
|
||||
hp_movelink(pos3, empty, pos->next_key);
|
||||
pos->next_key=empty;
|
||||
|
Reference in New Issue
Block a user