18 #include "myisamdef.h"
24 int mi_rkey(
MI_INFO *info, uchar *
buf,
int inx,
const uchar *key,
25 key_part_map keypart_map,
enum ha_rkey_function 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));
38 if ((inx = _mi_check_index(info,inx)) < 0)
39 DBUG_RETURN(my_errno);
41 info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
42 info->last_key_func= search_flag;
43 keyinfo= share->keyinfo + inx;
45 if (info->once_flags & USE_PACKED_KEYS)
47 info->once_flags&= ~USE_PACKED_KEYS;
52 key_buff=info->lastkey+info->s->base.max_key_length;
53 pack_key_length= keypart_map;
54 bmove(key_buff, key, pack_key_length);
55 last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
59 DBUG_ASSERT(keypart_map);
61 key_buff=info->lastkey+info->s->base.max_key_length;
62 pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
63 keypart_map, &last_used_keyseg);
65 info->pack_key_length= pack_key_length;
66 info->last_used_keyseg= (uint16) (last_used_keyseg -
67 info->s->keyinfo[inx].seg);
68 DBUG_EXECUTE(
"info",_mi_print_key(DBUG_FILE, keyinfo->seg,
69 key_buff, pack_key_length););
72 if (fast_mi_readinfo(info))
75 if (share->concurrent_insert)
78 nextflag=myisam_read_vec[search_flag];
79 use_key_length=pack_key_length;
80 if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
81 use_key_length=USE_WHOLE_KEY;
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;
90 if (share->concurrent_insert)
96 case HA_KEY_ALG_BTREE:
98 myisam_search_flag= myisam_read_vec[search_flag];
99 if (!_mi_search(info, keyinfo, key_buff, use_key_length,
100 myisam_search_flag, info->s->state.key_root[inx]))
119 while ((info->lastpos >= info->state->data_file_length &&
120 (search_flag != HA_READ_KEY_EXACT ||
121 last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) ||
122 (info->index_cond_func &&
123 !(res= mi_check_index_cond(info, inx, buf))))
132 if (_mi_search_next(info, keyinfo, info->lastkey,
133 info->lastkey_length,
134 myisam_readnext_vec[search_flag],
135 info->s->state.key_root[inx]))
142 if (search_flag == HA_READ_KEY_EXACT &&
143 ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
144 SEARCH_FIND, not_used))
146 my_errno= HA_ERR_KEY_NOT_FOUND;
147 info->lastpos= HA_OFFSET_ERROR;
153 info->lastpos= HA_OFFSET_ERROR;
154 if (share->concurrent_insert)
156 DBUG_RETURN((my_errno= HA_ERR_KEY_NOT_FOUND));
162 if (info->lastpos != HA_OFFSET_ERROR &&
163 info->lastpos >= info->state->data_file_length)
165 info->lastpos= HA_OFFSET_ERROR;
166 my_errno= HA_ERR_KEY_NOT_FOUND;
170 if (share->concurrent_insert)
174 if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg &&
175 info->lastpos != HA_OFFSET_ERROR)
176 info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
179 info->last_rkey_length= pack_key_length;
183 DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
185 if (!(*info->read_record)(info,info->lastpos,buf))
187 info->update|= HA_STATE_AKTIV;
191 info->lastpos = HA_OFFSET_ERROR;
194 memcpy(info->lastkey,key_buff,pack_key_length);
195 info->last_rkey_length= pack_key_length;
196 memset(info->lastkey+pack_key_length, 0, info->s->base.rec_reflength);
197 info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
199 if (search_flag == HA_READ_AFTER_KEY)
200 info->update|=HA_STATE_NEXT_FOUND;
202 DBUG_RETURN(my_errno);