summaryrefslogtreecommitdiff
path: root/storage/heap
diff options
context:
space:
mode:
Diffstat (limited to 'storage/heap')
-rw-r--r--storage/heap/CMakeLists.txt3
-rw-r--r--storage/heap/ha_heap.cc46
-rw-r--r--storage/heap/ha_heap.h4
-rw-r--r--storage/heap/hp_clear.c2
-rw-r--r--storage/heap/hp_create.c18
-rw-r--r--storage/heap/hp_delete.c1
-rw-r--r--storage/heap/hp_hash.c58
-rw-r--r--storage/heap/hp_rfirst.c16
-rw-r--r--storage/heap/hp_rkey.c5
-rw-r--r--storage/heap/hp_rlast.c8
-rw-r--r--storage/heap/hp_rnext.c16
-rw-r--r--storage/heap/hp_rprev.c16
-rw-r--r--storage/heap/hp_rsame.c2
-rw-r--r--storage/heap/hp_scan.c2
-rw-r--r--storage/heap/hp_test2.c9
-rw-r--r--storage/heap/hp_update.c4
-rw-r--r--storage/heap/hp_write.c1
17 files changed, 166 insertions, 45 deletions
diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt
index 74f6ce8d333..4d8dc2bdd3e 100644
--- a/storage/heap/CMakeLists.txt
+++ b/storage/heap/CMakeLists.txt
@@ -13,9 +13,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(HEAP_PLUGIN_STATIC "heap")
-SET(HEAP_PLUGIN_MANDATORY TRUE)
-
SET(HEAP_SOURCES _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create.c
ha_heap.cc
hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 9701bc40499..7c5fc133679 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -197,6 +197,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++)
@@ -227,7 +240,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])
@@ -251,7 +263,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);
@@ -270,7 +281,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)
@@ -289,7 +299,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;
@@ -299,7 +308,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;
@@ -310,7 +318,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;
@@ -319,7 +326,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;
@@ -328,7 +334,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;
@@ -337,7 +342,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;
@@ -346,7 +350,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;
@@ -359,7 +362,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;
@@ -369,7 +371,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(&heap_position, pos, sizeof(HEAP_PTR));
error=heap_rrnd(file, buf, heap_position);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -384,6 +385,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;
@@ -579,7 +584,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();
}
@@ -670,7 +675,8 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
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;
@@ -702,6 +708,18 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table,
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 c8652d6db69..42c41c69ee0 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
@@ -53,6 +53,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);
}
@@ -94,6 +95,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 9c04684e269..254e5d1a8ec 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 67fe0b3136f..adc507aa28e 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -43,6 +43,10 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
hp_free(share);
share= 0;
}
+ }
+ else
+ {
+ DBUG_PRINT("info", ("Creating internal (no named) temporary table"));
}
*created_new_share= (share == NULL);
@@ -110,6 +114,14 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
*/
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;
}
@@ -256,10 +268,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;
}
@@ -278,6 +295,7 @@ int heap_delete_table(const char *name)
else
{
result= my_errno=ENOENT;
+ DBUG_PRINT("error", ("Could not find table '%s'", name));
}
mysql_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 af388867c3c..5dab8443f53 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -1,5 +1,5 @@
-/* Copyright (C) 2000, 2011, Oracle and/or its affiliates. All rights
- reserved
+/* Copyright (C) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 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
@@ -310,7 +310,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)]--;
@@ -517,7 +518,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;