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 ...@@ -144,6 +144,7 @@ typedef struct st_heap_share
uint key_version; /* Updated on key change */ uint key_version; /* Updated on key change */
uint file_version; /* Update on clear */ uint file_version; /* Update on clear */
uint reclength; /* Length of one record */ uint reclength; /* Length of one record */
uint visible; /* Offset to the visible/deleted mark */
uint changed; uint changed;
uint keys,max_key_length; uint keys,max_key_length;
uint currently_disabled_keys; /* saved value from "keys" when disabled */ 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) ...@@ -79,7 +79,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status)
} }
hp_find_record(info,pos); hp_find_record(info,pos);
if (!info->current_ptr[share->reclength]) if (!info->current_ptr[share->visible])
deleted++; deleted++;
else else
records++; records++;
......
...@@ -100,15 +100,6 @@ const char **ha_heap::bas_ext() const ...@@ -100,15 +100,6 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked) 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); internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT)) 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, ...@@ -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) if (table_arg->found_next_number_field)
{ {
keydef[share->next_number_index].flag|= HA_AUTO_KEY; keydef[share->next_number_index].flag|= HA_AUTO_KEY;
......
...@@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, ...@@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
uint keys= create_info->keys; uint keys= create_info->keys;
ulong min_records= create_info->min_records; ulong min_records= create_info->min_records;
ulong max_records= create_info->max_records; ulong max_records= create_info->max_records;
uint visible_offset;
DBUG_ENTER("heap_create"); DBUG_ENTER("heap_create");
if (!create_info->internal_table) if (!create_info->internal_table)
...@@ -58,9 +59,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, ...@@ -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, 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++) 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, ...@@ -152,7 +153,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
share->keydef= (HP_KEYDEF*) (share + 1); share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1; share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys); 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 */ /* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys)); memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++) 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, ...@@ -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->max_table_size= create_info->max_table_size;
share->data_length= share->index_length= 0; share->data_length= share->index_length= 0;
share->reclength= reclength; share->reclength= reclength;
share->visible= visible_offset;
share->blength= 1; share->blength= 1;
share->keys= keys; share->keys= keys;
share->max_key_length= max_length; share->max_key_length= max_length;
......
...@@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record) ...@@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record)
info->update=HA_STATE_DELETED; info->update=HA_STATE_DELETED;
*((uchar**) pos)=share->del_link; *((uchar**) pos)=share->del_link;
share->del_link=pos; share->del_link=pos;
pos[share->reclength]=0; /* Record deleted */ pos[share->visible]=0; /* Record deleted */
share->deleted++; share->deleted++;
share->key_version++; share->key_version++;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG) #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
......
...@@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos) ...@@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos)
info->update= 0; info->update= 0;
DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE); 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; info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
...@@ -91,7 +91,7 @@ int heap_rrnd_old(register HP_INFO *info, uchar *record, ulong pos) ...@@ -91,7 +91,7 @@ int heap_rrnd_old(register HP_INFO *info, uchar *record, ulong pos)
hp_find_record(info, pos); hp_find_record(info, pos);
end: end:
if (!info->current_ptr[share->reclength]) if (!info->current_ptr[share->visible])
{ {
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
......
...@@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx) ...@@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx)
DBUG_ENTER("heap_rsame"); DBUG_ENTER("heap_rsame");
test_active(info); test_active(info);
if (info->current_ptr[share->reclength]) if (info->current_ptr[share->visible])
{ {
if (inx < -1 || inx >= (int) share->keys) if (inx < -1 || inx >= (int) share->keys)
{ {
......
...@@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record) ...@@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record)
} }
hp_find_record(info, pos); hp_find_record(info, pos);
} }
if (!info->current_ptr[share->reclength]) if (!info->current_ptr[share->visible])
{ {
DBUG_PRINT("warning",("Found deleted record")); DBUG_PRINT("warning",("Found deleted record"));
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
......
...@@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record) ...@@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record)
} }
memcpy(pos,record,(size_t) share->reclength); 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) if (++share->records == share->blength)
share->blength+= share->blength; share->blength+= share->blength;
info->s->key_version++; info->s->key_version++;
...@@ -92,7 +92,7 @@ int heap_write(HP_INFO *info, const uchar *record) ...@@ -92,7 +92,7 @@ int heap_write(HP_INFO *info, const uchar *record)
share->deleted++; share->deleted++;
*((uchar**) pos)=share->del_link; *((uchar**) pos)=share->del_link;
share->del_link=pos; share->del_link=pos;
pos[share->reclength]=0; /* Record deleted */ pos[share->visible]= 0; /* Record deleted */
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} /* heap_write */ } /* 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