diff options
author | unknown <pappa@c-5608e253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2005-11-08 00:26:37 -0500 |
---|---|---|
committer | unknown <pappa@c-5608e253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2005-11-08 00:26:37 -0500 |
commit | bba73a091031e9c324fedd6ad1bb26bcd4e635f9 (patch) | |
tree | c9d5aa727d72266be0ab83ff53f139f4209b6e51 /sql | |
parent | 0e878d7e541983757bc0b31e7caa8a16a5fd2896 (diff) | |
download | mariadb-git-bba73a091031e9c324fedd6ad1bb26bcd4e635f9.tar.gz |
Bug #12796: Record lost in HEAP table
Two handler objects were present, one was used for an insert and the other for a select
The state of the statistics was local to the handler object and thus the other handler
object didn't notice the insert.
Fix included:
1) Add a new variable key_stat_version added to whenever statistics was considered in need
of update (previously key_stats_ok= FALSE in those places)
2) Add a new handler variable key_stat_version assigned whenever key_stats_ok= TRUE was set
previously
3) Fix records_in_range to return records if records <= 1
4) Fix records_in_range to add 2 to rec_per_key to ensure we don't specify 0 or 1 when it isn't
and thus invoking incorrect optimisations.
5) Fix unique key handling for HEAP table in records_in_range
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_heap.cc | 38 | ||||
-rw-r--r-- | sql/ha_heap.h | 4 |
2 files changed, 27 insertions, 15 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index f8c2e6cc338..61e5ce89693 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -68,7 +68,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) ha_heap::info(), which is always called before key statistics are used. */ - key_stats_ok= FALSE; + key_stat_version= file->s->key_stat_version-1; } return (file ? 0 : 1); } @@ -114,14 +114,21 @@ void ha_heap::update_key_stats() continue; if (key->algorithm != HA_KEY_ALG_BTREE) { - ha_rows hash_buckets= file->s->keydef[i].hash_buckets; - key->rec_per_key[key->key_parts-1]= - hash_buckets ? file->s->records/hash_buckets : 0; + if (key->flags & HA_NOSAME) + key->rec_per_key[key->key_parts-1]= 1; + else + { + ha_rows hash_buckets= file->s->keydef[i].hash_buckets; + uint no_records= hash_buckets ? file->s->records/hash_buckets : 2; + if (no_records < 2) + no_records= 2; + key->rec_per_key[key->key_parts-1]= no_records; + } } } records_changed= 0; /* At the end of update_key_stats() we can proudly claim they are OK. */ - key_stats_ok= TRUE; + key_stat_version= file->s->key_stat_version; } int ha_heap::write_row(byte * buf) @@ -135,7 +142,7 @@ int ha_heap::write_row(byte * buf) res= heap_write(file,buf); if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -148,7 +155,7 @@ int ha_heap::update_row(const byte * old_data, byte * new_data) res= heap_update(file,old_data,new_data); if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -159,7 +166,7 @@ int ha_heap::delete_row(const byte * buf) res= heap_delete(file,buf); if (!res && table->tmp_table == NO_TMP_TABLE && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) - key_stats_ok= FALSE; + file->s->key_stat_version++; return res; } @@ -277,7 +284,7 @@ void ha_heap::info(uint flag) have to update the key statistics. Hoping that a table lock is now in place. */ - if (! key_stats_ok) + if (key_stat_version != file->s->key_stat_version) update_key_stats(); } @@ -290,7 +297,7 @@ int ha_heap::delete_all_rows() { heap_clear(file); if (table->tmp_table == NO_TMP_TABLE) - key_stats_ok= FALSE; + file->s->key_stat_version++; return 0; } @@ -451,9 +458,14 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, return HA_POS_ERROR; // Can only use exact keys else { - /* Assert that info() did run. We need current statistics here. */ - DBUG_ASSERT(key_stats_ok); - return key->rec_per_key[key->key_parts-1]; + if (records <= 1) + return records; + else + { + /* Assert that info() did run. We need current statistics here. */ + DBUG_ASSERT(key_stat_version == file->s->key_stat_version); + return key->rec_per_key[key->key_parts-1]; + } } } diff --git a/sql/ha_heap.h b/sql/ha_heap.h index cbe2474492d..0a087fde1b0 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -29,10 +29,10 @@ class ha_heap: public handler key_map btree_keys; /* number of records changed since last statistics update */ uint records_changed; - bool key_stats_ok; + uint key_stat_version; public: ha_heap(TABLE *table): handler(table), file(0), records_changed(0), - key_stats_ok(0) {} + key_stat_version(0) {} ~ha_heap() {} const char *table_type() const { return "HEAP"; } const char *index_type(uint inx) |