diff options
author | unknown <ingo@mysql.com> | 2005-06-24 19:47:18 +0200 |
---|---|---|
committer | unknown <ingo@mysql.com> | 2005-06-24 19:47:18 +0200 |
commit | 2e6d41d13202d7c7756e502592340295af1684eb (patch) | |
tree | afb4dd093ca8e3fdf8832f455c54e2b835bf00f8 /sql/ha_heap.cc | |
parent | be3d7091703c73686e4d6097734245a40151c276 (diff) | |
parent | a7e66efc2cc37b8ca32868ac8c8e3e3c05675e48 (diff) | |
download | mariadb-git-2e6d41d13202d7c7756e502592340295af1684eb.tar.gz |
Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
Bug#10568 - Function 'LAST_DAY(date)' does not return NULL for invalid argument.
Manual merge.
include/my_global.h:
Auto merged
mysql-test/t/heap_hash.test:
Auto merged
sql/ha_heap.h:
Auto merged
sql/item_timefunc.cc:
Auto merged
mysql-test/r/func_time.result:
Manual merge.
Used local for the backported fix for Bug#10568.
mysql-test/r/heap_hash.result:
Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
Manual merge.
mysql-test/t/func_time.test:
Manual merge.
Used local for the backported fix for Bug#10568.
sql/ha_heap.cc:
Bug#10178 - failure to find a row in heap table by concurrent UPDATEs
Manual merge.
Diffstat (limited to 'sql/ha_heap.cc')
-rw-r--r-- | sql/ha_heap.cc | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index cd655eeb0a9..6e609a94be3 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -65,7 +65,15 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { /* Initialize variables for the opened table */ set_keys_for_scanning(); - update_key_stats(); + /* + We cannot run update_key_stats() here because we do not have a + lock on the table. The 'records' count might just be changed + temporarily at this moment and we might get wrong statistics (Bug + #10178). Instead we request for update. This will be done in + ha_heap::info(), which is always called before key statistics are + used. + */ + key_stats_ok= FALSE; } return (file ? 0 : 1); } @@ -118,6 +126,8 @@ void ha_heap::update_key_stats() } } records_changed= 0; + /* At the end of update_key_stats() we can proudly claim they are OK. */ + key_stats_ok= TRUE; } @@ -132,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)) - update_key_stats(); + key_stats_ok= FALSE; return res; } @@ -145,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) - update_key_stats(); + key_stats_ok= FALSE; return res; } @@ -156,7 +166,7 @@ int ha_heap::delete_row(const byte * buf) res= heap_delete(file,buf); if (!res && table->s->tmp_table == NO_TMP_TABLE && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) - update_key_stats(); + key_stats_ok= FALSE; return res; } @@ -278,6 +288,13 @@ void ha_heap::info(uint flag) delete_length= info.deleted * info.reclength; if (flag & HA_STATUS_AUTO) auto_increment_value= info.auto_increment; + /* + If info() is called for the first time after open(), we will still + have to update the key statistics. Hoping that a table lock is now + in place. + */ + if (! key_stats_ok) + update_key_stats(); } int ha_heap::extra(enum ha_extra_function operation) @@ -289,7 +306,7 @@ int ha_heap::delete_all_rows() { heap_clear(file); if (table->s->tmp_table == NO_TMP_TABLE) - update_key_stats(); + key_stats_ok= FALSE; return 0; } @@ -448,6 +465,9 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, min_key->flag != HA_READ_KEY_EXACT || max_key->flag != HA_READ_AFTER_KEY) return HA_POS_ERROR; // Can only use exact keys + + /* Assert that info() did run. We need current statistics here. */ + DBUG_ASSERT(key_stats_ok); return key->rec_per_key[key->key_parts-1]; } |