00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "myisam_priv.h"
00019
00020 using namespace drizzled;
00021
00022
00023
00024
00025 int mi_rkey(MI_INFO *info, unsigned char *buf, int inx, const unsigned char *key,
00026 key_part_map keypart_map, enum ha_rkey_function search_flag)
00027 {
00028 unsigned char *key_buff;
00029 MYISAM_SHARE *share=info->s;
00030 MI_KEYDEF *keyinfo;
00031 HA_KEYSEG *last_used_keyseg;
00032 uint32_t pack_key_length, use_key_length, nextflag;
00033 uint32_t myisam_search_flag;
00034 int res= 0;
00035
00036 if ((inx = _mi_check_index(info,inx)) < 0)
00037 return(errno);
00038
00039 info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
00040 info->last_key_func= search_flag;
00041 keyinfo= share->keyinfo + inx;
00042
00043 if (info->once_flags & USE_PACKED_KEYS)
00044 {
00045 info->once_flags&= ~USE_PACKED_KEYS;
00046
00047
00048
00049
00050 key_buff=info->lastkey+info->s->base.max_key_length;
00051 pack_key_length= keypart_map;
00052 memmove(key_buff, key, pack_key_length);
00053 last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
00054 }
00055 else
00056 {
00057 assert(keypart_map);
00058
00059 key_buff=info->lastkey+info->s->base.max_key_length;
00060 pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (unsigned char*) key,
00061 keypart_map, &last_used_keyseg);
00062
00063 info->pack_key_length= pack_key_length;
00064 info->last_used_keyseg= (uint16_t) (last_used_keyseg -
00065 info->s->keyinfo[inx].seg);
00066 }
00067
00068 if (fast_mi_readinfo(info))
00069 goto err;
00070
00071 nextflag=myisam_read_vec[search_flag];
00072 use_key_length=pack_key_length;
00073 if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
00074 use_key_length=USE_WHOLE_KEY;
00075
00076 switch (info->s->keyinfo[inx].key_alg) {
00077 case HA_KEY_ALG_BTREE:
00078 default:
00079 myisam_search_flag= myisam_read_vec[search_flag];
00080 if (!_mi_search(info, keyinfo, key_buff, use_key_length,
00081 myisam_search_flag, info->s->state.key_root[inx]))
00082 {
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 while ((info->lastpos >= info->state->data_file_length &&
00101 (search_flag != HA_READ_KEY_EXACT ||
00102 last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) ||
00103 (info->index_cond_func &&
00104 !(res= mi_check_index_cond(info, inx, buf))))
00105 {
00106 uint32_t not_used[2];
00107
00108
00109
00110
00111
00112
00113 if (_mi_search_next(info, keyinfo, info->lastkey,
00114 info->lastkey_length,
00115 myisam_readnext_vec[search_flag],
00116 info->s->state.key_root[inx]))
00117 break;
00118
00119
00120
00121
00122
00123 if (search_flag == HA_READ_KEY_EXACT &&
00124 ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
00125 SEARCH_FIND, not_used))
00126 {
00127 errno= HA_ERR_KEY_NOT_FOUND;
00128 info->lastpos= HA_OFFSET_ERROR;
00129 break;
00130 }
00131 }
00132 if (res == 2)
00133 {
00134 info->lastpos= HA_OFFSET_ERROR;
00135 return((errno= HA_ERR_KEY_NOT_FOUND));
00136 }
00137
00138
00139
00140
00141 if (info->lastpos != HA_OFFSET_ERROR &&
00142 info->lastpos >= info->state->data_file_length)
00143 {
00144 info->lastpos= HA_OFFSET_ERROR;
00145 errno= HA_ERR_KEY_NOT_FOUND;
00146 }
00147 }
00148 }
00149
00150
00151 if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg &&
00152 info->lastpos != HA_OFFSET_ERROR)
00153 info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
00154 last_used_keyseg);
00155 else
00156 info->last_rkey_length= pack_key_length;
00157
00158
00159 if (!buf)
00160 return(info->lastpos == HA_OFFSET_ERROR ? errno : 0);
00161
00162 if (!(*info->read_record)(info,info->lastpos,buf))
00163 {
00164 info->update|= HA_STATE_AKTIV;
00165 return(0);
00166 }
00167
00168 info->lastpos = HA_OFFSET_ERROR;
00169
00170
00171 memcpy(info->lastkey,key_buff,pack_key_length);
00172 info->last_rkey_length= pack_key_length;
00173 memset(info->lastkey+pack_key_length, 0, info->s->base.rec_reflength);
00174 info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
00175
00176 if (search_flag == HA_READ_AFTER_KEY)
00177 info->update|=HA_STATE_NEXT_FOUND;
00178 err:
00179 return(errno);
00180 }