18 #include "myisamdef.h"
27 #define FIX_LENGTH(cs, pos, length, char_length) \
29 if (length > char_length) \
30 char_length= my_charpos(cs, pos, pos+length, char_length); \
31 set_if_smaller(char_length,length); \
34 static int _mi_put_key_in_record(
MI_INFO *info, uint keynr,
35 my_bool unpack_blobs, uchar *
record);
52 uint _mi_make_key(
register MI_INFO *info, uint keynr, uchar *key,
53 const uchar *
record, my_off_t filepos)
58 my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
59 DBUG_ENTER(
"_mi_make_key");
61 if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
67 DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos));
74 for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
76 enum ha_base_keytype
type=(
enum ha_base_keytype) keyseg->type;
77 uint length=keyseg->length;
83 if (record[keyseg->null_pos] & keyseg->null_bit)
91 char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
94 pos= (uchar*) record+keyseg->start;
95 if (type == HA_KEYTYPE_BIT)
97 if (keyseg->bit_length)
99 uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
100 keyseg->bit_start, keyseg->bit_length);
104 memcpy((uchar*) key, pos, length);
108 if (keyseg->flag & HA_SPACE_PACK)
110 if (type != HA_KEYTYPE_NUM)
112 length= cs->cset->lengthsp(cs, (
char*) pos, length);
116 uchar *end= pos + length;
117 while (pos < end && pos[0] ==
' ')
119 length=(uint) (end-pos);
121 FIX_LENGTH(cs, pos, length, char_length);
122 store_key_length_inc(key,char_length);
123 memcpy((uchar*) key,(uchar*) pos,(
size_t) char_length);
127 if (keyseg->flag & HA_VAR_LENGTH_PART)
129 uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
130 uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
133 set_if_smaller(length,tmp_length);
134 FIX_LENGTH(cs, pos, length, char_length);
135 store_key_length_inc(key,char_length);
136 memcpy((uchar*) key,(uchar*) pos,(
size_t) char_length);
140 else if (keyseg->flag & HA_BLOB_PART)
142 uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
143 memcpy(&pos,pos+keyseg->bit_start,
sizeof(
char*));
144 set_if_smaller(length,tmp_length);
145 FIX_LENGTH(cs, pos, length, char_length);
146 store_key_length_inc(key,char_length);
147 memcpy((uchar*) key,(uchar*) pos,(
size_t) char_length);
151 else if (keyseg->flag & HA_SWAP_KEY)
154 if (type == HA_KEYTYPE_FLOAT)
161 memset(key, 0, length);
166 else if (type == HA_KEYTYPE_DOUBLE)
172 memset(key, 0, length);
185 FIX_LENGTH(cs, pos, length, char_length);
186 memcpy((uchar*) key, pos, char_length);
187 if (length > char_length)
188 cs->cset->fill(cs, (
char*) key+char_length, length-char_length,
' ');
191 _mi_dpointer(info,key,filepos);
192 DBUG_PRINT(
"exit",(
"keynr: %d",keynr));
193 DBUG_DUMP(
"key",(uchar*) start,(uint) (key-start)+keyseg->length);
195 _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
196 (uint) (key-start)););
197 DBUG_RETURN((uint) (key-start));
219 uint _mi_pack_key(
register MI_INFO *info, uint keynr, uchar *key, uchar *old,
220 key_part_map keypart_map,
HA_KEYSEG **last_used_keyseg)
222 uchar *start_key=key;
224 my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
225 DBUG_ENTER(
"_mi_pack_key");
228 if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
229 keypart_map= (((key_part_map)1) << (2*SPDIMS)) - 1;
232 DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
234 for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
235 old+= keyseg->length, keyseg++)
237 enum ha_base_keytype type= (
enum ha_base_keytype) keyseg->type;
238 uint length= keyseg->length;
244 if (keyseg->null_bit)
246 if (!(*key++= (
char) 1-*old++))
248 if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
253 char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
255 if (keyseg->flag & HA_SPACE_PACK)
257 if (type == HA_KEYTYPE_NUM)
259 uchar *end= pos + length;
260 while (pos < end && pos[0] ==
' ')
262 length= (uint) (end - pos);
264 else if (type != HA_KEYTYPE_BINARY)
266 length= cs->cset->lengthsp(cs, (
char*) pos, length);
268 FIX_LENGTH(cs, pos, length, char_length);
269 store_key_length_inc(key,char_length);
270 memcpy((uchar*) key,pos,(
size_t) char_length);
274 else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
277 uint tmp_length=uint2korr(pos);
279 set_if_smaller(length,tmp_length);
280 FIX_LENGTH(cs, pos, length, char_length);
281 store_key_length_inc(key,char_length);
283 memcpy((uchar*) key, pos,(
size_t) char_length);
287 else if (keyseg->flag & HA_SWAP_KEY)
294 FIX_LENGTH(cs, pos, length, char_length);
295 memcpy((uchar*) key, pos, char_length);
296 if (length > char_length)
297 cs->cset->fill(cs, (
char*) key+char_length, length-char_length,
' ');
300 if (last_used_keyseg)
301 *last_used_keyseg= keyseg;
303 DBUG_RETURN((uint) (key-start_key));
330 static int _mi_put_key_in_record(
register MI_INFO *info, uint keynr,
331 my_bool unpack_blobs, uchar *record)
337 DBUG_ENTER(
"_mi_put_key_in_record");
339 blob_ptr= (uchar*) info->lastkey2;
340 key=(uchar*) info->lastkey;
341 key_end=key+info->lastkey_length;
342 for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
344 if (keyseg->null_bit)
348 record[keyseg->null_pos]|= keyseg->null_bit;
351 record[keyseg->null_pos]&= ~keyseg->null_bit;
353 if (keyseg->type == HA_KEYTYPE_BIT)
355 uint length= keyseg->length;
357 if (keyseg->bit_length)
360 set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
366 clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
369 memcpy(record + keyseg->start, (uchar*) key, length);
373 if (keyseg->flag & HA_SPACE_PACK)
376 get_key_length(length,key);
378 if (length > keyseg->length || key+length > key_end)
381 pos= record+keyseg->start;
382 if (keyseg->type != (
int) HA_KEYTYPE_NUM)
384 memcpy(pos,key,(
size_t) length);
385 keyseg->charset->cset->fill(keyseg->charset,
386 (
char*) pos + length,
387 keyseg->length - length,
392 memset(pos,
' ', keyseg->length-length);
393 memcpy(pos+keyseg->length-length,key,(
size_t) length);
399 if (keyseg->flag & HA_VAR_LENGTH_PART)
402 get_key_length(length,key);
404 if (length > keyseg->length || key+length > key_end)
408 if (keyseg->bit_start == 1)
409 *(uchar*) (record+keyseg->start)= (uchar) length;
411 int2store(record+keyseg->start, length);
413 memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
416 else if (keyseg->flag & HA_BLOB_PART)
419 get_key_length(length,key);
421 if (length > keyseg->length || key+length > key_end)
426 memcpy(record+keyseg->start+keyseg->bit_start,
427 &blob_ptr,
sizeof(
char*));
428 memcpy(blob_ptr,key,length);
431 info->update&= ~HA_STATE_RNEXT_SAME;
432 _mi_store_blob_length(record+keyseg->start,
433 (uint) keyseg->bit_start,length);
437 else if (keyseg->flag & HA_SWAP_KEY)
439 uchar *
to= record+keyseg->start+keyseg->length;
440 uchar *end= key+keyseg->length;
448 }
while (key != end);
454 if (key+keyseg->length > key_end)
457 memcpy(record+keyseg->start,(uchar*) key,
458 (
size_t) keyseg->length);
459 key+= keyseg->length;
471 int _mi_read_key_record(
MI_INFO *info, my_off_t filepos, uchar *
buf)
473 fast_mi_writeinfo(info);
474 if (filepos != HA_OFFSET_ERROR)
476 if (info->lastinx >= 0)
478 if (_mi_put_key_in_record(info, (uint)info->lastinx, TRUE, buf))
480 mi_print_error(info->s, HA_ERR_CRASHED);
481 my_errno=HA_ERR_CRASHED;
484 info->update|= HA_STATE_AKTIV;
487 my_errno=HA_ERR_WRONG_INDEX;
510 int mi_check_index_cond(
register MI_INFO *info, uint keynr, uchar *record)
512 if (_mi_put_key_in_record(info, keynr, FALSE, record))
514 mi_print_error(info->s, HA_ERR_CRASHED);
515 my_errno=HA_ERR_CRASHED;
518 return info->index_cond_func(info->index_cond_func_arg);
535 ulonglong retrieve_auto_increment(
MI_INFO *info,
const uchar *record)
539 HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
540 const uchar *key= (uchar*) record + keyseg->start;
543 case HA_KEYTYPE_INT8:
544 s_value= (longlong) *(
char*)key;
546 case HA_KEYTYPE_BINARY:
547 value=(ulonglong) *(uchar*) key;
549 case HA_KEYTYPE_SHORT_INT:
550 s_value= (longlong) sint2korr(key);
552 case HA_KEYTYPE_USHORT_INT:
553 value=(ulonglong) uint2korr(key);
555 case HA_KEYTYPE_LONG_INT:
556 s_value= (longlong) sint4korr(key);
558 case HA_KEYTYPE_ULONG_INT:
559 value=(ulonglong) uint4korr(key);
561 case HA_KEYTYPE_INT24:
562 s_value= (longlong) sint3korr(key);
564 case HA_KEYTYPE_UINT24:
565 value=(ulonglong) uint3korr(key);
567 case HA_KEYTYPE_FLOAT:
572 value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
575 case HA_KEYTYPE_DOUBLE:
580 value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
583 case HA_KEYTYPE_LONGLONG:
584 s_value= sint8korr(key);
586 case HA_KEYTYPE_ULONGLONG:
587 value= uint8korr(key);
600 return (s_value > 0) ? (ulonglong) s_value : value;