summaryrefslogtreecommitdiff
path: root/storage/myisam/mi_rkey.c
diff options
context:
space:
mode:
authorunknown <istruewing@chilla.local>2007-08-01 14:44:04 +0200
committerunknown <istruewing@chilla.local>2007-08-01 14:44:04 +0200
commit551f5b53c9ac92def1406aac4e2e47cfc7e1ad49 (patch)
tree7a69d4525aea4479cee69cf236a19523f5044527 /storage/myisam/mi_rkey.c
parent4a19d50071c024c08c2071c13302f92a0124d723 (diff)
parent374ff87951fbb128fd6efac02e6be0d9b5042d1f (diff)
downloadmariadb-git-551f5b53c9ac92def1406aac4e2e47cfc7e1ad49.tar.gz
Merge chilla.local:/home/mydev/mysql-5.0-bug29838
into chilla.local:/home/mydev/mysql-5.1-bug29838 storage/myisam/mi_rkey.c: Auto merged
Diffstat (limited to 'storage/myisam/mi_rkey.c')
-rw-r--r--storage/myisam/mi_rkey.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
index 3dcaa27d3ca..856bb07b2e7 100644
--- a/storage/myisam/mi_rkey.c
+++ b/storage/myisam/mi_rkey.c
@@ -94,42 +94,63 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
myisam_read_vec[search_flag], info->s->state.key_root[inx]))
{
/*
- If we searching for a partial key (or using >, >=, < or <=) and
- the data is outside of the data file, we need to continue searching
- for the first key inside the data file
+ Found a key, but it might not be usable. We cannot use rows that
+ are inserted by other threads after we got our table lock
+ ("concurrent inserts"). The record may not even be present yet.
+ Keys are inserted into the index(es) before the record is
+ inserted into the data file. When we got our table lock, we
+ saved the current data_file_length. Concurrent inserts always go
+ to the end of the file. So we can test if the found key
+ references a new record.
*/
- if (info->lastpos >= info->state->data_file_length &&
- (search_flag != HA_READ_KEY_EXACT ||
- last_used_keyseg != keyinfo->seg + keyinfo->keysegs))
+ if (info->lastpos >= info->state->data_file_length)
{
- do
+ /* The key references a concurrently inserted record. */
+ if (search_flag == HA_READ_KEY_EXACT &&
+ last_used_keyseg == keyinfo->seg + keyinfo->keysegs)
+ {
+ /* Simply ignore the key if it matches exactly. (Bug #29838) */
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ info->lastpos= HA_OFFSET_ERROR;
+ }
+ else
{
- uint not_used[2];
- /*
- Skip rows that are inserted by other threads since we got a lock
- Note that this can only happen if we are not searching after an
- full length exact key, because the keys are sorted
- according to position
- */
- if (_mi_search_next(info, keyinfo, info->lastkey,
- info->lastkey_length,
- myisam_readnext_vec[search_flag],
- info->s->state.key_root[inx]))
- break;
/*
- Check that the found key does still match the search.
- _mi_search_next() delivers the next key regardless of its
- value.
+ If searching for a partial key (or using >, >=, < or <=) and
+ the data is outside of the data file, we need to continue
+ searching for the first key inside the data file.
*/
- if (search_flag == HA_READ_KEY_EXACT &&
- ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
- SEARCH_FIND, not_used))
+ do
{
- my_errno= HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
- break;
- }
- } while (info->lastpos >= info->state->data_file_length);
+ uint not_used[2];
+ /*
+ Skip rows that are inserted by other threads since we got
+ a lock. Note that this can only happen if we are not
+ searching after a full length exact key, because the keys
+ are sorted according to position.
+ */
+ if (_mi_search_next(info, keyinfo, info->lastkey,
+ info->lastkey_length,
+ myisam_readnext_vec[search_flag],
+ info->s->state.key_root[inx]))
+ break; /* purecov: inspected */
+ /*
+ Check that the found key does still match the search.
+ _mi_search_next() delivers the next key regardless of its
+ value.
+ */
+ if (search_flag == HA_READ_KEY_EXACT &&
+ ha_key_cmp(keyinfo->seg, key_buff, info->lastkey,
+ use_key_length, SEARCH_FIND, not_used))
+ {
+ /* purecov: begin inspected */
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ info->lastpos= HA_OFFSET_ERROR;
+ break;
+ /* purecov: end */
+ }
+ } while (info->lastpos >= info->state->data_file_length);
+ }
}
}
}