16
16
/* Read record based on a key */
18
18
#include "myisamdef.h"
20
21
/* Read a record using key */
21
22
/* Ordinary search_flag is 0 ; Give error if no record with key */
23
int mi_rkey(MI_INFO *info, unsigned char *buf, int inx, const unsigned char *key,
24
int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
24
25
key_part_map keypart_map, enum ha_rkey_function search_flag)
26
unsigned char *key_buff;
27
28
MYISAM_SHARE *share=info->s;
28
29
MI_KEYDEF *keyinfo;
29
30
HA_KEYSEG *last_used_keyseg;
30
uint32_t pack_key_length, use_key_length, nextflag;
31
uint32_t myisam_search_flag;
31
uint pack_key_length, use_key_length, nextflag;
32
uint myisam_search_flag;
34
DBUG_ENTER("mi_rkey");
35
DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
36
(long) info, (long) buf, inx, search_flag));
34
38
if ((inx = _mi_check_index(info,inx)) < 0)
39
DBUG_RETURN(my_errno);
37
41
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
38
42
info->last_key_func= search_flag;
48
52
key_buff=info->lastkey+info->s->base.max_key_length;
49
53
pack_key_length= keypart_map;
50
memcpy(key_buff, key, pack_key_length);
54
bmove(key_buff, key, pack_key_length);
51
55
last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
59
DBUG_ASSERT(keypart_map);
56
60
/* Save the packed key for later use in the second buffer of lastkey. */
57
61
key_buff=info->lastkey+info->s->base.max_key_length;
58
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (unsigned char*) key,
62
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
59
63
keypart_map, &last_used_keyseg);
60
64
/* Save packed_key_length for use by the MERGE engine. */
61
65
info->pack_key_length= pack_key_length;
62
info->last_used_keyseg= (uint16_t) (last_used_keyseg -
66
info->last_used_keyseg= (uint16) (last_used_keyseg -
63
67
info->s->keyinfo[inx].seg);
68
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
69
key_buff, pack_key_length););
66
72
if (fast_mi_readinfo(info))
75
81
use_key_length=USE_WHOLE_KEY;
77
83
switch (info->s->keyinfo[inx].key_alg) {
84
#ifdef HAVE_RTREE_KEYS
85
case HA_KEY_ALG_RTREE:
86
if (rtree_find_first(info,inx,key_buff,use_key_length,nextflag) < 0)
88
mi_print_error(info->s, HA_ERR_CRASHED);
89
my_errno=HA_ERR_CRASHED;
78
94
case HA_KEY_ALG_BTREE:
80
96
myisam_search_flag= myisam_read_vec[search_flag];
104
120
(info->index_cond_func &&
105
121
!(res= mi_check_index_cond(info, inx, buf))))
107
uint32_t not_used[2];
109
125
Skip rows that are inserted by other threads since we got a lock
110
126
Note that this can only happen if we are not searching after an
135
151
info->lastpos= HA_OFFSET_ERROR;
136
152
if (share->concurrent_insert)
137
153
rw_unlock(&share->key_root_lock[inx]);
138
return((my_errno= HA_ERR_KEY_NOT_FOUND));
154
DBUG_RETURN((my_errno= HA_ERR_KEY_NOT_FOUND));
141
157
Error if no row found within the data file. (Bug #29838)
163
179
/* Check if we don't want to have record back, only error message */
165
return(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
181
DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
167
183
if (!(*info->read_record)(info,info->lastpos,buf))
169
185
info->update|= HA_STATE_AKTIV; /* Record is read */
173
189
info->lastpos = HA_OFFSET_ERROR; /* Didn't find key */
175
191
/* Store last used key as a base for read next */
176
192
memcpy(info->lastkey,key_buff,pack_key_length);
177
193
info->last_rkey_length= pack_key_length;
178
memset(info->lastkey+pack_key_length, 0, info->s->base.rec_reflength);
194
bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength);
179
195
info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
181
197
if (search_flag == HA_READ_AFTER_KEY)
182
198
info->update|=HA_STATE_NEXT_FOUND; /* Previous gives last row */
200
DBUG_RETURN(my_errno);