Commit 7c6cf7fe authored by Sergei Golubchik's avatar Sergei Golubchik

bug: ha_heap was unilaterally increasing reclength

proper fix replacing the hack from b80fa400

don't confuse length of the data area (reclength) with the
offset to the "deleted" mark.
parent 7a63ffab
......@@ -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 @@ int heap_write(HP_INFO *info, const uchar *record)
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment