summaryrefslogtreecommitdiff
path: root/sql/ha_heap.cc
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-06-24 19:47:18 +0200
committerunknown <ingo@mysql.com>2005-06-24 19:47:18 +0200
commit2e6d41d13202d7c7756e502592340295af1684eb (patch)
treeafb4dd093ca8e3fdf8832f455c54e2b835bf00f8 /sql/ha_heap.cc
parentbe3d7091703c73686e4d6097734245a40151c276 (diff)
parenta7e66efc2cc37b8ca32868ac8c8e3e3c05675e48 (diff)
downloadmariadb-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.cc30
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];
}