diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-01-25 14:25:48 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-02-11 18:36:54 +0100 |
commit | 7c6cf7fefe68a1a3f68e7d6436da4689ec302bca (patch) | |
tree | 86754b8b68a03cb6569d675944919452f6142c05 | |
parent | 7a63ffab71644118223aefe66094366a7b7f115e (diff) | |
download | mariadb-git-7c6cf7fefe68a1a3f68e7d6436da4689ec302bca.tar.gz |
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.
-rw-r--r-- | include/heap.h | 1 | ||||
-rw-r--r-- | storage/heap/_check.c | 2 | ||||
-rw-r--r-- | storage/heap/ha_heap.cc | 11 | ||||
-rw-r--r-- | storage/heap/hp_create.c | 8 | ||||
-rw-r--r-- | storage/heap/hp_delete.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_rrnd.c | 4 | ||||
-rw-r--r-- | storage/heap/hp_rsame.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_scan.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_write.c | 4 |
9 files changed, 15 insertions, 21 deletions
diff --git a/include/heap.h b/include/heap.h index 2b7fd28699d..eecb7084e66 100644 --- a/include/heap.h +++ b/include/heap.h @@ -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 */ diff --git a/storage/heap/_check.c b/storage/heap/_check.c index b64c9ab1831..f2fd8ab94be 100644 --- a/storage/heap/_check.c +++ b/storage/heap/_check.c @@ -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++; diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 259e54bfc59..ec76d08bf97 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -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; diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 0b5dc841ada..1daca0beeb5 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -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; diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index 1cbfe7408d4..eb9749601aa 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -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) diff --git a/storage/heap/hp_rrnd.c b/storage/heap/hp_rrnd.c index 8e0d51a78ca..d105c5c2e13 100644 --- a/storage/heap/hp_rrnd.c +++ b/storage/heap/hp_rrnd.c @@ -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); diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c index 40c5a18f974..19767fd752b 100644 --- a/storage/heap/hp_rsame.c +++ b/storage/heap/hp_rsame.c @@ -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) { diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c index 39a6f2082a3..65726c37e1f 100644 --- a/storage/heap/hp_scan.c +++ b/storage/heap/hp_scan.c @@ -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; diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c index e45c78b75f1..4a9c1ba59c0 100644 --- a/storage/heap/hp_write.c +++ b/storage/heap/hp_write.c @@ -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 */ |