summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorVenkata Sidagam <venkata.sidagam@oracle.com>2012-11-07 09:00:17 +0530
committerVenkata Sidagam <venkata.sidagam@oracle.com>2012-11-07 09:00:17 +0530
commit2226b1084ce0209ad4ff8e3805ed944600af3abb (patch)
tree6f50c8ef6668e8b5c684cfd9cc5bff7e96ee6eca /storage
parentb6d3362948b0d0fb29fe4bb5bcef03b88e8052e3 (diff)
downloadmariadb-git-2226b1084ce0209ad4ff8e3805ed944600af3abb.tar.gz
Bug #11759445: CAN'T DELETE ROWS FROM MEMORY TABLE WITH HASH KEY.
Brief description: After insert some rows to MEMORY table with HASH key some rows can't be deleted in one step. Problem Analysis/solution: info->current_ptr will have the information about the current hash pointer from where we can traverse to the list to get all the remaining tuples. In hp_delete_key we are updating info->current_ptr with the last_pos based on the flag parameter(which is the keydef and last index are same). As part of the fix we are making it to zero only when the code flow reaches to the end of the function hp_delete_key() it means that the next record which has to get deleted will be at the starting of the list so, that in the next call to read record(heap_rnext()) will take line number 100 path instead of 102 path, please see the below code in file hp_rnext.c, function heap_rnext(). 99 else if (!info->current_ptr) /* Deleted or first call */ 100 pos= hp_search(info, keyinfo, info->lastkey, 0); 101 else 102 pos= hp_search(info, keyinfo, info->lastkey, 1); with that change the hp_search() will update the info->current_ptr with the record which needs to be deleted. storage/heap/hp_delete.c: In heap_delete_key() function we are making info->current_ptr to 0 if flag is enabled.
Diffstat (limited to 'storage')
-rw-r--r--storage/heap/hp_delete.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index ceba0fcf12e..3090b60d611 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -104,7 +104,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const uchar *record, uchar *recpos, int flag)
{
- ulong blength,pos2,pos_hashnr,lastpos_hashnr;
+ ulong blength, pos2, pos_hashnr, lastpos_hashnr, key_pos;
HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
HP_SHARE *share=info->s;
DBUG_ENTER("hp_delete_key");
@@ -116,9 +116,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
last_ptr=0;
/* Search after record with key */
- pos= hp_find_hash(&keyinfo->block,
- hp_mask(hp_rec_hashnr(keyinfo, record), blength,
- share->records + 1));
+ key_pos= hp_mask(hp_rec_hashnr(keyinfo, record), blength, share->records + 1);
+ pos= hp_find_hash(&keyinfo->block, key_pos);
+
gpos = pos3 = 0;
while (pos->ptr_to_rec != recpos)
@@ -188,6 +188,16 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_RETURN(0);
}
pos3= pos; /* Link pos->next after lastpos */
+ /*
+ One of elements from the bucket we're scanning is moved to the
+ beginning of the list. Reset search since this element may not have
+ been processed yet.
+ */
+ if (flag && pos2 == key_pos)
+ {
+ info->current_ptr= 0;
+ info->current_hash_ptr= 0;
+ }
}
else
{