diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
commit | 65ca700def99289cc31a7040537f5aa6e12bf485 (patch) | |
tree | 97b3a07299b626c519da0e80c122b5b79b933914 /storage/myisam/mi_rkey.c | |
parent | 2ab57de38d13d927ddff2d51aed4af34e13998f5 (diff) | |
parent | 6e5bcca7935d3c62f84bb640e5357664a210ee12 (diff) | |
download | mariadb-git-65ca700def99289cc31a7040537f5aa6e12bf485.tar.gz |
merge.
checkpoint.
does not compile.
Diffstat (limited to 'storage/myisam/mi_rkey.c')
-rw-r--r-- | storage/myisam/mi_rkey.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index d3744c9a053..f5b3514faf6 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -29,6 +29,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, MI_KEYDEF *keyinfo; HA_KEYSEG *last_used_keyseg; uint pack_key_length, use_key_length, nextflag; + ICP_RESULT res= ICP_NO_MATCH; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d", (long) info, (long) buf, inx, search_flag)); @@ -85,6 +86,8 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, { mi_print_error(info->s, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; + if (share->concurrent_insert) + rw_unlock(&share->key_root_lock[inx]); goto err; } break; @@ -103,55 +106,62 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, 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 we are 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. + + We do also continue searching if an index condition check function + is available. */ - if (info->lastpos >= info->state->data_file_length) + while ((info->lastpos >= info->state->data_file_length && + (search_flag != HA_READ_KEY_EXACT || + last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) || + (info->index_cond_func && + (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) { - /* The key references a concurrently inserted record. */ + 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 (search_flag == HA_READ_KEY_EXACT && - last_used_keyseg == keyinfo->seg + keyinfo->keysegs) + ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length, + SEARCH_FIND, not_used)) { - /* Simply ignore the key if it matches exactly. (Bug #29838) */ my_errno= HA_ERR_KEY_NOT_FOUND; info->lastpos= HA_OFFSET_ERROR; + break; } - else - { - /* - 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. - */ - do - { - 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); - } + } + if (res == ICP_OUT_OF_RANGE) + { + info->lastpos= HA_OFFSET_ERROR; + if (share->concurrent_insert) + rw_unlock(&share->key_root_lock[inx]); + DBUG_RETURN((my_errno= HA_ERR_KEY_NOT_FOUND)); + } + /* + Error if no row found within the data file. (Bug #29838) + Do not overwrite my_errno if already at HA_OFFSET_ERROR. + */ + if (info->lastpos != HA_OFFSET_ERROR && + info->lastpos >= info->state->data_file_length) + { + info->lastpos= HA_OFFSET_ERROR; + my_errno= HA_ERR_KEY_NOT_FOUND; } } } |