diff options
Diffstat (limited to 'storage/heap')
-rw-r--r-- | storage/heap/ha_heap.cc | 46 | ||||
-rw-r--r-- | storage/heap/ha_heap.h | 4 | ||||
-rw-r--r-- | storage/heap/hp_clear.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_create.c | 18 | ||||
-rw-r--r-- | storage/heap/hp_delete.c | 1 | ||||
-rw-r--r-- | storage/heap/hp_hash.c | 58 | ||||
-rw-r--r-- | storage/heap/hp_rfirst.c | 16 | ||||
-rw-r--r-- | storage/heap/hp_rkey.c | 5 | ||||
-rw-r--r-- | storage/heap/hp_rlast.c | 8 | ||||
-rw-r--r-- | storage/heap/hp_rnext.c | 16 | ||||
-rw-r--r-- | storage/heap/hp_rprev.c | 16 | ||||
-rw-r--r-- | storage/heap/hp_rsame.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_scan.c | 2 | ||||
-rw-r--r-- | storage/heap/hp_test2.c | 8 | ||||
-rw-r--r-- | storage/heap/hp_update.c | 4 | ||||
-rw-r--r-- | storage/heap/hp_write.c | 1 |
16 files changed, 164 insertions, 43 deletions
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 7757d0a6210..ae45e85c1b3 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -183,6 +183,19 @@ void ha_heap::set_keys_for_scanning(void) } +int ha_heap::can_continue_handler_scan() +{ + int error= 0; + if ((file->key_version != file->s->key_version && inited == INDEX) || + (file->file_version != file->s->file_version && inited == RND)) + { + /* Data changed, not safe to do index or rnd scan */ + error= HA_ERR_RECORD_CHANGED; + } + return error; +} + + void ha_heap::update_key_stats() { for (uint i= 0; i < table->s->keys; i++) @@ -213,7 +226,6 @@ void ha_heap::update_key_stats() int ha_heap::write_row(uchar * buf) { int res; - ha_statistic_increment(&SSV::ha_write_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -237,7 +249,6 @@ int ha_heap::write_row(uchar * buf) int ha_heap::update_row(const uchar * old_data, uchar * new_data) { int res; - ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); res= heap_update(file,old_data,new_data); @@ -256,7 +267,6 @@ int ha_heap::update_row(const uchar * old_data, uchar * new_data) int ha_heap::delete_row(const uchar * buf) { int res; - ha_statistic_increment(&SSV::ha_delete_count); res= heap_delete(file,buf); if (!res && table->s->tmp_table == NO_TMP_TABLE && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) @@ -275,7 +285,6 @@ int ha_heap::index_read_map(uchar *buf, const uchar *key, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -285,7 +294,6 @@ int ha_heap::index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_key_count); int error= heap_rkey(file, buf, active_index, key, keypart_map, HA_READ_PREFIX_LAST); table->status= error ? STATUS_NOT_FOUND : 0; @@ -296,7 +304,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) { - ha_statistic_increment(&SSV::ha_read_key_count); int error = heap_rkey(file, buf, index, key, keypart_map, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -305,7 +312,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key, int ha_heap::index_next(uchar * buf) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_next_count); int error=heap_rnext(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -314,7 +320,6 @@ int ha_heap::index_next(uchar * buf) int ha_heap::index_prev(uchar * buf) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_prev_count); int error=heap_rprev(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -323,7 +328,6 @@ int ha_heap::index_prev(uchar * buf) int ha_heap::index_first(uchar * buf) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_first_count); int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -332,7 +336,6 @@ int ha_heap::index_first(uchar * buf) int ha_heap::index_last(uchar * buf) { DBUG_ASSERT(inited==INDEX); - ha_statistic_increment(&SSV::ha_read_last_count); int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -345,7 +348,6 @@ int ha_heap::rnd_init(bool scan) int ha_heap::rnd_next(uchar *buf) { - ha_statistic_increment(&SSV::ha_read_rnd_next_count); int error=heap_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -355,7 +357,6 @@ int ha_heap::rnd_pos(uchar * buf, uchar *pos) { int error; HEAP_PTR heap_position; - ha_statistic_increment(&SSV::ha_read_rnd_count); memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR)); error=heap_rrnd(file, buf, heap_position); table->status=error ? STATUS_NOT_FOUND: 0; @@ -370,6 +371,10 @@ void ha_heap::position(const uchar *record) int ha_heap::info(uint flag) { HEAPINFO hp_info; + + if (!table) + return 1; + (void) heap_info(file,&hp_info,flag); errkey= hp_info.errkey; @@ -565,7 +570,7 @@ int ha_heap::delete_table(const char *name) void ha_heap::drop_table(const char *name) { file->s->delete_on_close= 1; - close(); + ha_close(); } @@ -654,7 +659,8 @@ int ha_heap::create(const char *name, TABLE *table_arg, seg->type != HA_KEYTYPE_VARTEXT1 && seg->type != HA_KEYTYPE_VARTEXT2 && seg->type != HA_KEYTYPE_VARBINARY1 && - seg->type != HA_KEYTYPE_VARBINARY2) + seg->type != HA_KEYTYPE_VARBINARY2 && + seg->type != HA_KEYTYPE_BIT) seg->type= HA_KEYTYPE_BINARY; } seg->start= (uint) key_part->offset; @@ -686,6 +692,18 @@ int ha_heap::create(const char *name, TABLE *table_arg, auto_key= key+ 1; auto_key_type= field->key_type(); } + if (seg->type == HA_KEYTYPE_BIT) + { + seg->bit_length= ((Field_bit *) field)->bit_len; + seg->bit_start= ((Field_bit *) field)->bit_ofs; + seg->bit_pos= (uint) (((Field_bit *) field)->bit_ptr - + (uchar*) table_arg->record[0]); + } + else + { + seg->bit_length= seg->bit_start= 0; + seg->bit_pos= 0; + } } } mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*)); diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 69751101645..799e52d903b 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (C) 2000-2006 MySQL AB, 2009-2011 Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -52,6 +52,7 @@ public: { return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | + HA_CAN_SQL_HANDLER | HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS | HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT); } @@ -93,6 +94,7 @@ public: int rnd_next(uchar *buf); int rnd_pos(uchar * buf, uchar *pos); void position(const uchar *record); + int can_continue_handler_scan(); int info(uint); int extra(enum ha_extra_function operation); int reset(); diff --git a/storage/heap/hp_clear.c b/storage/heap/hp_clear.c index babfcbd6f41..b999f1ff5e8 100644 --- a/storage/heap/hp_clear.c +++ b/storage/heap/hp_clear.c @@ -40,6 +40,8 @@ void hp_clear(HP_SHARE *info) info->blength=1; info->changed=0; info->del_link=0; + info->key_version++; + info->file_version++; DBUG_VOID_RETURN; } diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index bc8183bf777..f9d0a48324d 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -39,6 +39,10 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, share= 0; } } + else + { + DBUG_PRINT("info", ("Creating internal (no named) temporary table")); + } if (!share) { @@ -104,6 +108,14 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, */ keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1; break; + case HA_KEYTYPE_BIT: + /* + The odd bits which stored separately (if they are present + (bit_pos, bit_length)) are already present in seg[j].length as + additional byte. + See field.h, function key_length() + */ + break; default: break; } @@ -247,10 +259,15 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, static inline void heap_try_free(HP_SHARE *share) { + DBUG_ENTER("heap_try_free"); if (share->open_count == 0) hp_free(share); else + { + DBUG_PRINT("info", ("Table is still in use. Will be freed on close")); share->delete_on_close= 1; + } + DBUG_VOID_RETURN; } @@ -269,6 +286,7 @@ int heap_delete_table(const char *name) else { result= my_errno=ENOENT; + DBUG_PRINT("error", ("Could not find table '%s'", name)); } pthread_mutex_unlock(&THR_LOCK_heap); DBUG_RETURN(result); diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index ceba0fcf12e..db2c0df6128 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -47,6 +47,7 @@ int heap_delete(HP_INFO *info, const uchar *record) share->del_link=pos; pos[share->reclength]=0; /* Record deleted */ share->deleted++; + share->key_version++; info->current_hash_ptr=0; #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG) DBUG_EXECUTE("check_heap",heap_check_heap(info, 0);); diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index aaaa0fe833f..fb9ea44a424 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -349,6 +349,15 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) } else { + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) bits))+ (nr << 8); + nr2+=3; + end--; + } + for (; pos < end ; pos++) { nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8); @@ -465,6 +474,14 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec) else { uchar *end= pos+seg->length; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + nr *=16777619; + nr ^=(uint) bits; + end--; + } for ( ; pos < end ; pos++) { nr *=16777619; @@ -577,7 +594,18 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, } else { - if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) + uint dec= 0; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits1= get_rec_bits(rec1 + seg->bit_pos, + seg->bit_start, seg->bit_length); + uchar bits2= get_rec_bits(rec2 + seg->bit_pos, + seg->bit_start, seg->bit_length); + if (bits1 != bits2) + return 1; + dec= 1; + } + if (bcmp(rec1 + seg->start, rec2 + seg->start, seg->length - dec)) return 1; } } @@ -660,7 +688,18 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) } else { - if (bcmp(rec+seg->start,key,seg->length)) + uint dec= 0; + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + uchar bits= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + if (bits != (*key)) + return 1; + dec= 1; + key++; + } + + if (bcmp(rec + seg->start, key, seg->length - dec)) return 1; } } @@ -689,6 +728,12 @@ void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec) } if (seg->type == HA_KEYTYPE_VARTEXT1) char_length+= seg->bit_start; /* Copy also length */ + else if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + *key++= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + char_length--; + } memcpy(key,rec+seg->start,(size_t) char_length); key+= char_length; } @@ -720,7 +765,8 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, { uint length= seg->length; uchar *pos= (uchar*) rec + seg->start; - + DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT); + #ifdef HAVE_ISNAN if (seg->type == HA_KEYTYPE_FLOAT) { @@ -784,6 +830,12 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, seg->charset->cset->fill(seg->charset, (char*) key + char_length, seg->length - char_length, ' '); } + if (seg->type == HA_KEYTYPE_BIT && seg->bit_length) + { + *key++= get_rec_bits(rec + seg->bit_pos, + seg->bit_start, seg->bit_length); + char_length--; + } memcpy(key, rec + seg->start, (size_t) char_length); key+= seg->length; } diff --git a/storage/heap/hp_rfirst.c b/storage/heap/hp_rfirst.c index d0d2ec9b506..e45af4a219f 100644 --- a/storage/heap/hp_rfirst.c +++ b/storage/heap/hp_rfirst.c @@ -24,6 +24,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx) DBUG_ENTER("heap_rfirst"); info->lastinx= inx; + info->key_version= info->s->key_version; + if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { uchar *pos; @@ -50,6 +52,7 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx) } else { + info->update= HA_STATE_NO_KEY; my_errno = HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno); } @@ -57,15 +60,8 @@ int heap_rfirst(HP_INFO *info, uchar *record, int inx) } else { - if (!(info->s->records)) - { - my_errno=HA_ERR_END_OF_FILE; - DBUG_RETURN(my_errno); - } - DBUG_ASSERT(0); /* TODO fix it */ - info->current_record=0; - info->current_hash_ptr=0; - info->update=HA_STATE_PREV_FOUND; - DBUG_RETURN(heap_rnext(info,record)); + /* We can't scan a non existing key value with hash index */ + my_errno= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(my_errno); } } diff --git a/storage/heap/hp_rkey.c b/storage/heap/hp_rkey.c index 27d1114770e..166ed28aed0 100644 --- a/storage/heap/hp_rkey.c +++ b/storage/heap/hp_rkey.c @@ -30,6 +30,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, } info->lastinx= inx; info->current_record= (ulong) ~0L; /* For heap_rrnd() */ + info->key_version= info->s->key_version; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { @@ -50,7 +51,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, if (!(pos= tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, find_flag, &custom_arg))) { - info->update= 0; + info->update= HA_STATE_NO_KEY; DBUG_RETURN(my_errno= HA_ERR_KEY_NOT_FOUND); } memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*)); @@ -60,7 +61,7 @@ int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key, { if (!(pos= hp_search(info, share->keydef + inx, key, 0))) { - info->update= 0; + info->update= HA_STATE_NO_KEY; DBUG_RETURN(my_errno); } if (!(keyinfo->flag & HA_NOSAME)) diff --git a/storage/heap/hp_rlast.c b/storage/heap/hp_rlast.c index 45ad7c21f49..0710401e5a5 100644 --- a/storage/heap/hp_rlast.c +++ b/storage/heap/hp_rlast.c @@ -25,6 +25,7 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx) DBUG_ENTER("heap_rlast"); info->lastinx= inx; + info->key_version= info->s->key_version; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { uchar *pos; @@ -47,9 +48,8 @@ int heap_rlast(HP_INFO *info, uchar *record, int inx) } else { - info->current_ptr=0; - info->current_hash_ptr=0; - info->update=HA_STATE_NEXT_FOUND; - DBUG_RETURN(heap_rprev(info,record)); + /* We can't scan a non existing key value with hash index */ + my_errno= HA_ERR_WRONG_COMMAND; + DBUG_RETURN(my_errno); } } diff --git a/storage/heap/hp_rnext.c b/storage/heap/hp_rnext.c index 3d715f4e6d3..7a759e70972 100644 --- a/storage/heap/hp_rnext.c +++ b/storage/heap/hp_rnext.c @@ -32,7 +32,20 @@ int heap_rnext(HP_INFO *info, uchar *record) { heap_rb_param custom_arg; - if (info->last_pos) + /* If no active record and last was not deleted */ + if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY | + HA_STATE_DELETED))) + { + if (info->update & HA_STATE_NEXT_FOUND) + pos= 0; /* Can't search after last row */ + else + { + /* Last was 'prev' before first record; search after first record */ + pos= tree_search_edge(&keyinfo->rb_tree, info->parents, + &info->last_pos, offsetof(TREE_ELEMENT, left)); + } + } + else if (info->last_pos) { /* We enter this branch for non-DELETE queries after heap_rkey() @@ -70,6 +83,7 @@ int heap_rnext(HP_INFO *info, uchar *record) custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = info->lastkey_len; custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND; + info->last_find_flag= HA_READ_KEY_OR_NEXT; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } diff --git a/storage/heap/hp_rprev.c b/storage/heap/hp_rprev.c index 63bfffffba9..8a50444bb5f 100644 --- a/storage/heap/hp_rprev.c +++ b/storage/heap/hp_rprev.c @@ -32,7 +32,20 @@ int heap_rprev(HP_INFO *info, uchar *record) { heap_rb_param custom_arg; - if (info->last_pos) + /* If no active record and last was not deleted */ + if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY | + HA_STATE_DELETED))) + { + if (info->update & HA_STATE_PREV_FOUND) + pos= 0; /* Can't search before first row */ + else + { + /* Last was 'next' after last record; search after last record */ + pos= tree_search_edge(&keyinfo->rb_tree, info->parents, + &info->last_pos, offsetof(TREE_ELEMENT, right)); + } + } + else if (info->last_pos) pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, right), offsetof(TREE_ELEMENT, left)); @@ -41,6 +54,7 @@ int heap_rprev(HP_INFO *info, uchar *record) custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = keyinfo->length; custom_arg.search_flag = SEARCH_SAME; + info->last_find_flag= HA_READ_KEY_OR_PREV; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c index 1a3724672b6..f93a443aa48 100644 --- a/storage/heap/hp_rsame.c +++ b/storage/heap/hp_rsame.c @@ -43,7 +43,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx) hp_make_key(share->keydef + inx, info->lastkey, record); if (!hp_search(info, share->keydef + inx, info->lastkey, 3)) { - info->update=0; + info->update= 0; DBUG_RETURN(my_errno); } } diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c index e8913e92c86..397dd8b54d4 100644 --- a/storage/heap/hp_scan.c +++ b/storage/heap/hp_scan.c @@ -31,6 +31,8 @@ int heap_scan_init(register HP_INFO *info) info->current_record= (ulong) ~0L; /* No current record */ info->update=0; info->next_block=0; + info->key_version= info->s->key_version; + info->file_version= info->s->file_version; DBUG_RETURN(0); } diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 67471e93a7a..ba593f31cb0 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -21,9 +21,6 @@ #ifdef DBUG_OFF #undef DBUG_OFF #endif -#ifndef SAFEMALLOC -#define SAFEMALLOC 1 -#endif #include "heapdef.h" /* Because of hp_find_block */ #include <signal.h> @@ -319,7 +316,8 @@ int main(int argc, char *argv[]) if (!silent) printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n"); - if (heap_rlast(file,record3,0)) goto err; + if (heap_rprev(file,record)) + goto err; if (heap_delete(file,record3)) goto err; key_check-=atoi((char*) record3); key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; @@ -526,7 +524,7 @@ int main(int argc, char *argv[]) } ant=0; - for (error=heap_rlast(file,record,0) ; + for (error=heap_rprev(file,record) ; ! error ; error=heap_rprev(file,record)) { diff --git a/storage/heap/hp_update.c b/storage/heap/hp_update.c index 7f469af3c96..ab831382325 100644 --- a/storage/heap/hp_update.c +++ b/storage/heap/hp_update.c @@ -21,7 +21,7 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) { HP_KEYDEF *keydef, *end, *p_lastinx; uchar *pos; - my_bool auto_key_changed= 0; + my_bool auto_key_changed= 0, key_changed= 0; HP_SHARE *share= info->s; DBUG_ENTER("heap_update"); @@ -54,6 +54,8 @@ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new) #endif if (auto_key_changed) heap_update_auto_increment(info, heap_new); + if (key_changed) + share->key_version++; DBUG_RETURN(0); err: diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c index 4e8fa7e3580..bf27503de9b 100644 --- a/storage/heap/hp_write.c +++ b/storage/heap/hp_write.c @@ -56,6 +56,7 @@ int heap_write(HP_INFO *info, const uchar *record) pos[share->reclength]=1; /* Mark record as not deleted */ if (++share->records == share->blength) share->blength+= share->blength; + info->s->key_version++; info->current_ptr=pos; info->current_hash_ptr=0; info->update|=HA_STATE_AKTIV; |