mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +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
|
c2
|
||||||
0
|
0
|
||||||
DROP TABLE t1;
|
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);
|
ALTER TABLE t1 MODIFY c1 VARCHAR(101);
|
||||||
SELECT c2 FROM t1;
|
SELECT c2 FROM t1;
|
||||||
DROP TABLE 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;
|
share->del_link=pos;
|
||||||
pos[share->reclength]=0; /* Record deleted */
|
pos[share->reclength]=0; /* Record deleted */
|
||||||
share->deleted++;
|
share->deleted++;
|
||||||
info->current_hash_ptr=0;
|
|
||||||
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
|
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
|
||||||
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
|
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
|
||||||
#endif
|
#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);
|
pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
|
||||||
if (pos2 == hp_mask(pos_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)
|
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);
|
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);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
pos3= pos; /* Link pos->next after lastpos */
|
/*
|
||||||
}
|
Shrinking the hash table deleted the main bucket entry for this hash.
|
||||||
else
|
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
|
||||||
pos3= 0; /* Different positions merge */
|
that heap_rnext() works.
|
||||||
keyinfo->hash_buckets--;
|
|
||||||
|
- 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];
|
empty[0]=lastpos[0];
|
||||||
hp_movelink(pos3, empty, pos->next_key);
|
hp_movelink(pos3, empty, pos->next_key);
|
||||||
pos->next_key=empty;
|
pos->next_key=empty;
|
||||||
|
Reference in New Issue
Block a user