bug: ha_heap was unilaterally increasing reclength
proper fix replacing the hack from b80fa4000d6 don't confuse length of the data area (reclength) with the offset to the "deleted" mark.
This commit is contained in:
parent
7a63ffab71
commit
7c6cf7fefe
@ -144,6 +144,7 @@ typedef struct st_heap_share
|
||||
uint key_version; /* Updated on key change */
|
||||
uint file_version; /* Update on clear */
|
||||
uint reclength; /* Length of one record */
|
||||
uint visible; /* Offset to the visible/deleted mark */
|
||||
uint changed;
|
||||
uint keys,max_key_length;
|
||||
uint currently_disabled_keys; /* saved value from "keys" when disabled */
|
||||
|
@ -79,7 +79,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
|
||||
}
|
||||
hp_find_record(info,pos);
|
||||
|
||||
if (!info->current_ptr[share->reclength])
|
||||
if (!info->current_ptr[share->visible])
|
||||
deleted++;
|
||||
else
|
||||
records++;
|
||||
|
@ -100,15 +100,6 @@ const char **ha_heap::bas_ext() const
|
||||
|
||||
int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
if (table->s->reclength < sizeof (char*))
|
||||
{
|
||||
MEM_UNDEFINED(table->s->default_values + table->s->reclength,
|
||||
sizeof(char*) - table->s->reclength);
|
||||
table->s->reclength= sizeof(char*);
|
||||
MEM_UNDEFINED(table->record[0], table->s->reclength);
|
||||
MEM_UNDEFINED(table->record[1], table->s->reclength);
|
||||
}
|
||||
|
||||
internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
|
||||
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
|
||||
{
|
||||
@ -736,7 +727,7 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
|
||||
}
|
||||
}
|
||||
}
|
||||
mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
|
||||
mem_per_row+= MY_ALIGN(max(share->reclength, sizeof(char*)) + 1, sizeof(char*));
|
||||
if (table_arg->found_next_number_field)
|
||||
{
|
||||
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
|
||||
|
@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
||||
uint keys= create_info->keys;
|
||||
ulong min_records= create_info->min_records;
|
||||
ulong max_records= create_info->max_records;
|
||||
uint visible_offset;
|
||||
DBUG_ENTER("heap_create");
|
||||
|
||||
if (!create_info->internal_table)
|
||||
@ -58,9 +59,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
||||
|
||||
/*
|
||||
We have to store sometimes uchar* del_link in records,
|
||||
so the record length should be at least sizeof(uchar*)
|
||||
so the visible_offset must be least at sizeof(uchar*)
|
||||
*/
|
||||
set_if_bigger(reclength, sizeof (uchar*));
|
||||
visible_offset= max(reclength, sizeof (char*));
|
||||
|
||||
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
|
||||
{
|
||||
@ -152,7 +153,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
||||
share->keydef= (HP_KEYDEF*) (share + 1);
|
||||
share->key_stat_version= 1;
|
||||
keyseg= (HA_KEYSEG*) (share->keydef + keys);
|
||||
init_block(&share->block, reclength + 1, min_records, max_records);
|
||||
init_block(&share->block, visible_offset + 1, min_records, max_records);
|
||||
/* Fix keys */
|
||||
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
|
||||
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
|
||||
@ -192,6 +193,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
|
||||
share->max_table_size= create_info->max_table_size;
|
||||
share->data_length= share->index_length= 0;
|
||||
share->reclength= reclength;
|
||||
share->visible= visible_offset;
|
||||
share->blength= 1;
|
||||
share->keys= keys;
|
||||
share->max_key_length= max_length;
|
||||
|
@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
|
||||
info->update=HA_STATE_DELETED;
|
||||
*((uchar**) pos)=share->del_link;
|
||||
share->del_link=pos;
|
||||
pos[share->reclength]=0; /* Record deleted */
|
||||
pos[share->visible]=0; /* Record deleted */
|
||||
share->deleted++;
|
||||
share->key_version++;
|
||||
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
|
||||
|
@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos)
|
||||
info->update= 0;
|
||||
DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE);
|
||||
}
|
||||
if (!info->current_ptr[share->reclength])
|
||||
if (!info->current_ptr[share->visible])
|
||||
{
|
||||
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
|
||||
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
|
||||
@ -91,7 +91,7 @@ int heap_rrnd_old(register HP_INFO *info, uchar *record, ulong pos)
|
||||
hp_find_record(info, pos);
|
||||
|
||||
end:
|
||||
if (!info->current_ptr[share->reclength])
|
||||
if (!info->current_ptr[share->visible])
|
||||
{
|
||||
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
|
||||
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
|
||||
|
@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx)
|
||||
DBUG_ENTER("heap_rsame");
|
||||
|
||||
test_active(info);
|
||||
if (info->current_ptr[share->reclength])
|
||||
if (info->current_ptr[share->visible])
|
||||
{
|
||||
if (inx < -1 || inx >= (int) share->keys)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record)
|
||||
}
|
||||
hp_find_record(info, pos);
|
||||
}
|
||||
if (!info->current_ptr[share->reclength])
|
||||
if (!info->current_ptr[share->visible])
|
||||
{
|
||||
DBUG_PRINT("warning",("Found deleted record"));
|
||||
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
|
||||
|
@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record)
|
||||
}
|
||||
|
||||
memcpy(pos,record,(size_t) share->reclength);
|
||||
pos[share->reclength]=1; /* Mark record as not deleted */
|
||||
pos[share->visible]= 1; /* Mark record as not deleted */
|
||||
if (++share->records == share->blength)
|
||||
share->blength+= share->blength;
|
||||
info->s->key_version++;
|
||||
@ -92,7 +92,7 @@ err:
|
||||
share->deleted++;
|
||||
*((uchar**) pos)=share->del_link;
|
||||
share->del_link=pos;
|
||||
pos[share->reclength]=0; /* Record deleted */
|
||||
pos[share->visible]= 0; /* Record deleted */
|
||||
|
||||
DBUG_RETURN(my_errno);
|
||||
} /* heap_write */
|
||||
|
Loading…
x
Reference in New Issue
Block a user