66
66
uchar lastkey[MI_MAX_KEY_BUFF],*buff;
67
67
DBUG_ENTER("_mi_search");
68
68
DBUG_PRINT("enter",("pos: %ld nextflag: %d lastpos: %ld",
69
pos,nextflag,info->lastpos));
69
pos,nextflag,info->lastpos));
70
70
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
72
72
if (pos == HA_OFFSET_ERROR)
74
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
74
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
75
75
info->lastpos= HA_OFFSET_ERROR;
76
76
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
77
DBUG_RETURN(-1); /* Not found ; return error */
78
DBUG_RETURN(1); /* Search at upper levels */
77
DBUG_RETURN(-1); /* Not found ; return error */
78
DBUG_RETURN(1); /* Search at upper levels */
81
81
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
82
test(!(nextflag & SEARCH_SAVE_BUFF)))))
82
test(!(nextflag & SEARCH_SAVE_BUFF)))))
84
84
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
86
86
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
87
&keypos,lastkey, &last_key);
87
&keypos,lastkey, &last_key);
88
88
if (flag == MI_FOUND_WRONG_KEY)
90
90
nod_flag=mi_test_if_nod(buff);
95
95
if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
96
_mi_kpos(nod_flag,keypos))) <= 0)
96
_mi_kpos(nod_flag,keypos))) <= 0)
97
97
DBUG_RETURN(error);
101
101
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
102
keypos == buff+2+nod_flag)
103
DBUG_RETURN(1); /* Bigger than key */
102
keypos == buff+2+nod_flag)
103
DBUG_RETURN(1); /* Bigger than key */
105
105
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
106
DBUG_RETURN(1); /* Smaller than key */
106
DBUG_RETURN(1); /* Smaller than key */
110
110
if (nextflag & SEARCH_FIND && (!(keyinfo->flag & HA_NOSAME)
111
|| key_len) && nod_flag)
111
|| key_len) && nod_flag)
113
113
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
114
_mi_kpos(nod_flag,keypos))) >= 0 ||
115
my_errno != HA_ERR_KEY_NOT_FOUND)
117
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */
114
_mi_kpos(nod_flag,keypos))) >= 0 ||
115
my_errno != HA_ERR_KEY_NOT_FOUND)
117
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */
120
120
if (pos != info->last_keypage)
122
122
uchar *old_buff=buff;
123
123
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
124
test(!(nextflag & SEARCH_SAVE_BUFF)))))
124
test(!(nextflag & SEARCH_SAVE_BUFF)))))
126
126
keypos=buff+(keypos-old_buff);
127
127
maxpos=buff+(maxpos-old_buff);
253
memcpy(buff,t_buff,length); /* Result is first key */
253
memcpy(buff,t_buff,length); /* Result is first key */
254
254
*last_key= page == end;
255
255
DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
256
256
DBUG_RETURN(flag);
257
257
} /* _mi_seq_search */
260
/* Get pos to a key_block */
259
int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
260
uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
261
uchar *buff, my_bool *last_key)
263
/* my_flag is raw comparison result to be changed according to
264
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
265
flag is the value returned by _mi_key_cmp and as treated as final */
266
int flag=0, my_flag=-1;
267
uint nod_flag, length, len, matched, cmplen, kseg_len, key_len_left;
268
uint prefix_len,suffix_len;
269
int key_len_skip, seg_len_pack;
270
uchar *end, *kseg, *vseg;
271
uchar *sort_order=keyinfo->seg->charset->sort_order;
272
uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
273
uchar *saved_from, *saved_to, *saved_vseg;
274
uint saved_length=0, saved_prefix_len=0;
275
DBUG_ENTER("_mi_prefix_search");
277
t_buff[0]=0; /* Avoid bugs */
278
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
279
key_len=USE_WHOLE_KEY;
280
end= page+mi_getint(page);
281
nod_flag=mi_test_if_nod(page);
287
get_key_pack_length(kseg_len,lenght_pack,kseg);
288
key_len_skip=lenght_pack+kseg_len;
289
key_len_left=key_len-key_len_skip;
290
cmplen=(key_len_left>=0) ? kseg_len : key_len-lenght_pack;
294
Keys are compressed the following way:
296
If the max length of first key segment <= 127 characters the prefix is
297
1 byte else it's 2 byte
299
prefix The high bit is set if this is a prefix for the prev key
300
length Packed length if the previous was a prefix byte
301
[length] Length character of data
302
next-key-seg Next key segments
305
matched=0; /* how many char's from prefix were alredy matched */
306
len=0; /* length of previous key unpacked */
310
uint packed= *page & 128;
313
if (keyinfo->seg->length >= 127)
315
suffix_len=mi_uint2korr(vseg) & 32767;
319
suffix_len= *vseg++ & 127;
323
if (suffix_len == 0) /* Same key */
327
prefix_len=suffix_len;
328
get_key_length(suffix_len,vseg);
334
len=prefix_len+suffix_len;
335
seg_len_pack=get_pack_length(len);
336
t_buff=tt_buff+3-seg_len_pack;
337
store_key_length(t_buff,len);
339
if (prefix_len > saved_prefix_len)
340
memcpy(t_buff+seg_len_pack+saved_prefix_len,saved_vseg,
341
prefix_len-saved_prefix_len);
343
saved_prefix_len=prefix_len;
346
uchar *from=vseg+suffix_len;
350
for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
353
if (keyseg->flag & HA_NULL_PART)
358
if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
360
get_key_length(l,from);
367
from+=keyseg->length;
374
my_errno=HA_ERR_CRASHED;
375
DBUG_PRINT("error",("Found wrong key: length: %d page: %lx end: %lx",
377
DBUG_RETURN(MI_FOUND_WRONG_KEY);
380
if (matched >= prefix_len)
382
/* We have to compare. But we can still skip part of the key */
384
uchar *k=kseg+prefix_len;
386
left=(len>cmplen) ? cmplen-prefix_len : suffix_len;
388
matched=prefix_len+left;
390
for(my_flag=0;left;left--)
391
if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++]))
394
if (my_flag>0) /* mismatch */
396
else if (my_flag==0) /* match */
398
** len cmplen seg_left_len more_segs
399
** < matched=len; continue search
400
** > = prefix ? found : (matched=len; continue search)
410
else if (len > cmplen)
412
if(my_flag = !(nextflag & SEARCH_PREFIX) && key_len_left>0)
416
else if (key_len_left>0)
419
if ((flag = _mi_key_cmp(keyinfo->seg+1,vseg,
420
k,key_len_left,nextflag,¬_used)) >= 0)
425
/* at this line flag==-1 if the following lines were already
426
visited and 0 otherwise, i.e. flag <=0 here always !!! */
428
if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
429
flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
435
/* else (matched < prefix_len) ---> do nothing. */
437
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
438
saved_to=buff+saved_length;
439
saved_from=saved_vseg;
444
flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag;
447
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
448
saved_to=buff+saved_length;
449
saved_from=saved_vseg;
453
memcpy(saved_to,saved_from,saved_length);
455
*last_key= page == end;
457
DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
459
} /* _mi_prefix_search */
462
/* Get pos to a key_block */
262
464
my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
525
flag = (int) *a - (int) *b;
526
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
727
flag = (int) *a - (int) *b;
728
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
529
if (!*a++) /* If key was NULL */
731
if (!*a++) /* If key was NULL */
531
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
532
nextflag=SEARCH_SAME; /* Allow duplicate keys */
533
next_key_length=key_length;
534
continue; /* To next key part */
733
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
734
nextflag=SEARCH_SAME; /* Allow duplicate keys */
735
next_key_length=key_length;
736
continue; /* To next key part */
537
739
end= a+ min(keyseg->length,key_length);
538
740
next_key_length=key_length-keyseg->length;
540
742
switch ((enum ha_base_keytype) keyseg->type) {
541
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
743
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
542
744
if (keyseg->flag & HA_SPACE_PACK)
544
int a_length,b_length,pack_length;
545
get_key_length(a_length,a);
546
get_key_pack_length(b_length,pack_length,b);
547
next_key_length=key_length-b_length-pack_length;
746
int a_length,b_length,pack_length;
747
get_key_length(a_length,a);
748
get_key_pack_length(b_length,pack_length,b);
749
next_key_length=key_length-b_length-pack_length;
549
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
550
(my_bool) ((nextflag & SEARCH_PREFIX) &&
551
next_key_length <= 0))))
552
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
751
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
752
(my_bool) ((nextflag & SEARCH_PREFIX) &&
753
next_key_length <= 0))))
754
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
559
uint length=(uint) (end-a);
560
if ((flag=_mi_compare_text(keyseg->charset,a,length,b,length,
561
(my_bool) ((nextflag & SEARCH_PREFIX) &&
562
next_key_length <= 0))))
563
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
761
uint length=(uint) (end-a);
762
if ((flag=_mi_compare_text(keyseg->charset,a,length,b,length,
763
(my_bool) ((nextflag & SEARCH_PREFIX) &&
764
next_key_length <= 0))))
765
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
568
770
case HA_KEYTYPE_BINARY:
569
771
if (keyseg->flag & HA_SPACE_PACK)
571
int a_length,b_length,pack_length;
572
get_key_length(a_length,a);
573
get_key_pack_length(b_length,pack_length,b);
574
next_key_length=key_length-b_length-pack_length;
773
int a_length,b_length,pack_length;
774
get_key_length(a_length,a);
775
get_key_pack_length(b_length,pack_length,b);
776
next_key_length=key_length-b_length-pack_length;
576
if ((flag=compare_bin(a,a_length,b,b_length,
577
(my_bool) ((nextflag & SEARCH_PREFIX) &&
578
next_key_length <= 0))))
579
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
778
if ((flag=compare_bin(a,a_length,b,b_length,
779
(my_bool) ((nextflag & SEARCH_PREFIX) &&
780
next_key_length <= 0))))
781
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
586
uint length=keyseg->length;
587
if ((flag=compare_bin(a,length,b,length,
588
(my_bool) ((nextflag & SEARCH_PREFIX) &&
589
next_key_length <= 0))))
590
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
788
uint length=keyseg->length;
789
if ((flag=compare_bin(a,length,b,length,
790
(my_bool) ((nextflag & SEARCH_PREFIX) &&
791
next_key_length <= 0))))
792
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
595
797
case HA_KEYTYPE_VARTEXT:
597
int a_length,b_length,pack_length;
598
get_key_length(a_length,a);
599
get_key_pack_length(b_length,pack_length,b);
600
next_key_length=key_length-b_length-pack_length;
799
int a_length,b_length,pack_length;
800
get_key_length(a_length,a);
801
get_key_pack_length(b_length,pack_length,b);
802
next_key_length=key_length-b_length-pack_length;
602
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
603
(my_bool) ((nextflag & SEARCH_PREFIX) &&
604
next_key_length <= 0))))
605
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
804
if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
805
(my_bool) ((nextflag & SEARCH_PREFIX) &&
806
next_key_length <= 0))))
807
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
611
813
case HA_KEYTYPE_VARBINARY:
613
int a_length,b_length,pack_length;
614
get_key_length(a_length,a);
615
get_key_pack_length(b_length,pack_length,b);
616
next_key_length=key_length-b_length-pack_length;
815
int a_length,b_length,pack_length;
816
get_key_length(a_length,a);
817
get_key_pack_length(b_length,pack_length,b);
818
next_key_length=key_length-b_length-pack_length;
618
if ((flag=compare_bin(a,a_length,b,b_length,
619
(my_bool) ((nextflag & SEARCH_PREFIX) &&
620
next_key_length <= 0))))
621
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
820
if ((flag=compare_bin(a,a_length,b,b_length,
821
(my_bool) ((nextflag & SEARCH_PREFIX) &&
822
next_key_length <= 0))))
823
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
627
829
case HA_KEYTYPE_INT8:
697
899
mi_float8get(d_1,a);
698
900
mi_float8get(d_2,b);
699
901
if ((flag = CMP(d_1,d_2)))
700
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
902
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
702
904
b+= 8; /* sizeof(double); */
704
case HA_KEYTYPE_NUM: /* Numeric key */
906
case HA_KEYTYPE_NUM: /* Numeric key */
706
908
int swap_flag= 0;
707
909
int alength,blength;
709
911
if (keyseg->flag & HA_REVERSE_SORT)
712
swap_flag=1; /* Remember swap of a & b */
914
swap_flag=1; /* Remember swap of a & b */
713
915
end= a+ (int) (end-b);
715
917
if (keyseg->flag & HA_SPACE_PACK)
717
alength= *a++; blength= *b++;
719
next_key_length=key_length-blength-1;
919
alength= *a++; blength= *b++;
921
next_key_length=key_length-blength-1;
723
alength= (int) (end-a);
724
blength=keyseg->length;
725
/* remove pre space from keys */
726
for ( ; alength && *a == ' ' ; a++, alength--) ;
727
for ( ; blength && *b == ' ' ; b++, blength--) ;
925
alength= (int) (end-a);
926
blength=keyseg->length;
927
/* remove pre space from keys */
928
for ( ; alength && *a == ' ' ; a++, alength--) ;
929
for ( ; blength && *b == ' ' ; b++, blength--) ;
736
swap(int,alength,blength);
737
swap_flag=1-swap_flag;
738
alength--; blength--;
938
swap(int,alength,blength);
939
swap_flag=1-swap_flag;
940
alength--; blength--;
741
943
else if (*b == '-')
743
945
while (alength && (*a == '+' || *a == '0'))
747
949
while (blength && (*b == '+' || *b == '0'))
751
953
if (alength != blength)
752
return (alength < blength) ? -1 : 1;
954
return (alength < blength) ? -1 : 1;
755
return ((int) a[-1] - (int) b[-1]);
957
return ((int) a[-1] - (int) b[-1]);
757
if (swap_flag) /* Restore pointers */
959
if (swap_flag) /* Restore pointers */
761
963
#ifdef HAVE_LONG_LONG
799
1001
if (*a++ != *b++)
801
flag= FCMP(a[-1],b[-1]);
1003
flag= FCMP(a[-1],b[-1]);
805
1007
if (nextflag & SEARCH_SAME)
806
return (flag); /* read same */
1008
return (flag); /* read same */
807
1009
if (nextflag & SEARCH_BIGGER)
808
return (flag <= 0 ? -1 : 1); /* read next */
809
return (flag < 0 ? -1 : 1); /* read previous */
1010
return (flag <= 0 ? -1 : 1); /* read next */
1011
return (flag < 0 ? -1 : 1); /* read previous */
812
1014
} /* _mi_key_cmp */
815
/* Get key from key-block */
816
/* page points at previous key; its advanced to point at next key */
817
/* key should contain previous key */
818
/* Returns length of found key + pointers */
819
/* nod_flag is a flag if we are on nod */
1017
/* Get key from key-block */
1018
/* page points at previous key; its advanced to point at next key */
1019
/* key should contain previous key */
1020
/* Returns length of found key + pointers */
1021
/* nod_flag is a flag if we are on nod */
821
/* same as _mi_get_key but used with fixed length keys */
1023
/* same as _mi_get_key but used with fixed length keys */
823
1025
uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
824
register uchar **page, register uchar *key)
1026
register uchar **page, register uchar *key)
826
1028
memcpy((byte*) key,(byte*) *page,
827
(size_t) (keyinfo->keylength+nod_flag));
1029
(size_t) (keyinfo->keylength+nod_flag));
828
1030
*page+=keyinfo->keylength+nod_flag;
829
1031
return(keyinfo->keylength);
830
1032
} /* _mi_get_static_key */
1192
1391
} /* _mi_keylength */
1197
1396
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
1199
1398
reg1 uint length;
1200
1399
memcpy((byte*) to, (byte*) from,
1201
(size_t) (length=_mi_keylength(keyinfo,from)));
1400
(size_t) (length=_mi_keylength(keyinfo,from)));
1202
1401
return to+length;
1205
/* Find next/previous record with same key */
1206
/* This can't be used when database is touched after last read */
1404
/* Find next/previous record with same key */
1405
/* This can't be used when database is touched after last read */
1208
1407
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1209
uchar *key, uint key_length, uint nextflag, my_off_t pos)
1408
uchar *key, uint key_length, uint nextflag, my_off_t pos)
1213
1412
uchar lastkey[MI_MAX_KEY_BUFF];
1214
1413
DBUG_ENTER("_mi_search_next");
1215
1414
DBUG_PRINT("enter",("nextflag: %d lastpos: %ld int_keypos: %lx",
1216
nextflag,(long) info->lastpos,info->int_keypos));
1415
nextflag,(long) info->lastpos,info->int_keypos));
1217
1416
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
1219
1418
/* Force full read if we are at last key or if we are not on a leaf
1242
1441
nod_flag=mi_test_if_nod(info->buff);
1243
1442
memcpy(lastkey,key,key_length);
1245
if (nextflag & SEARCH_BIGGER) /* Next key */
1444
if (nextflag & SEARCH_BIGGER) /* Next key */
1247
1446
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1248
1447
if (tmp_pos != HA_OFFSET_ERROR)
1250
1449
if ((error=_mi_search(info,keyinfo,key,key_length,
1251
nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
1450
nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
1254
1453
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
1255
&info->int_keypos,lastkey)))
1454
&info->int_keypos,lastkey)))
1256
1455
DBUG_RETURN(-1);
1258
else /* Previous key */
1457
else /* Previous key */
1261
1460
/* Find start of previous key */
1262
1461
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
1263
info->int_keypos, &length);
1462
info->int_keypos, &length);
1264
1463
if (!info->int_keypos)
1265
1464
DBUG_RETURN(-1);
1266
1465
if (info->int_keypos == info->buff+2)
1267
1466
DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
1268
nextflag | SEARCH_SAVE_BUFF, pos));
1467
nextflag | SEARCH_SAVE_BUFF, pos));
1269
1468
if ((error=_mi_search(info,keyinfo,key,0,nextflag | SEARCH_SAVE_BUFF,
1270
_mi_kpos(nod_flag,info->int_keypos))) <= 0)
1469
_mi_kpos(nod_flag,info->int_keypos))) <= 0)
1271
1470
DBUG_RETURN(error);
1273
1472
if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
1274
info->int_keypos,&info->lastkey_length))
1473
info->int_keypos,&info->lastkey_length))
1275
1474
DBUG_RETURN(-1);
1277
1476
memcpy(info->lastkey,lastkey,info->lastkey_length);
1373
1572
** Functions to store and pack a key in a page
1375
1574
** mi_calc_xx_key_length takes the following arguments:
1376
** nod_flag If nod: Length of nod-pointer
1377
** next_key Position to pos after the new key in buffer
1378
** org_key Key that was before the next key in buffer
1379
** prev_key Last key before current key
1380
** key Key that will be stored
1381
** s_temp Information how next key will be packed
1575
** nod_flag If nod: Length of nod-pointer
1576
** next_key Position to pos after the new key in buffer
1577
** org_key Key that was before the next key in buffer
1578
** prev_key Last key before current key
1579
** key Key that will be stored
1580
** s_temp Information how next key will be packed
1382
1581
****************************************************************************/
1384
1583
/* Static length key */
1387
1586
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
1388
uchar *next_pos __attribute__((unused)),
1389
uchar *org_key __attribute__((unused)),
1390
uchar *prev_key __attribute__((unused)),
1391
uchar *key, MI_KEY_PARAM *s_temp)
1587
uchar *next_pos __attribute__((unused)),
1588
uchar *org_key __attribute__((unused)),
1589
uchar *prev_key __attribute__((unused)),
1590
uchar *key, MI_KEY_PARAM *s_temp)
1393
1592
s_temp->key=key;
1394
1593
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
1572
1771
n_length-= s_temp->store_not_null;
1574
if (n_length || packed) /* Don't pack 0 length keys */
1773
if (n_length || packed) /* Don't pack 0 length keys */
1576
1775
uint next_length_pack, new_ref_length=s_temp->ref_length;
1580
/* If first key and next key is packed (only on delete) */
1581
if (!prev_key && org_key)
1583
get_key_length(org_key_length,org_key);
1585
if (sort_order) /* SerG */
1587
while (key < end && sort_order[*key] == sort_order[*org_key])
1594
while (key < end && *key == *org_key)
1599
if ((new_ref_length= (uint) (key - start)))
1600
new_ref_length+=pack_marker;
1606
We put a different key between two identical variable length keys
1607
Extend next key to have same prefix as this key
1609
if (new_ref_length) /* prefix of previus key */
1610
{ /* make next key longer */
1611
s_temp->part_of_prev_key= new_ref_length;
1612
s_temp->prev_length= org_key_length -
1613
(new_ref_length-pack_marker);
1614
s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
1615
n_length= get_pack_length(s_temp->prev_length);
1616
s_temp->prev_key+= (new_ref_length - pack_marker);
1617
length+= s_temp->prev_length + n_length;
1620
{ /* Can't use prev key */
1621
s_temp->part_of_prev_key=0;
1622
s_temp->prev_length= org_key_length;
1623
s_temp->n_ref_length=s_temp->n_length= org_key_length;
1624
length+= org_key_length;
1625
/* +get_pack_length(org_key_length); */
1627
return (int) length;
1630
ref_length=n_length;
1631
get_key_pack_length(n_length,next_length_pack,next_key);
1633
/* Test if new keys has fewer characters that match the previous key */
1634
if (!new_ref_length)
1635
{ /* Can't use prev key */
1636
s_temp->part_of_prev_key= 0;
1637
s_temp->prev_length= ref_length;
1638
s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
1639
/* s_temp->prev_key+= get_pack_length(org_key_length); */
1640
return (int) length+ref_length-next_length_pack;
1642
if (ref_length+pack_marker > new_ref_length)
1644
uint new_pack_length=new_ref_length-pack_marker;
1645
/* We must copy characters from the original key to the next key */
1646
s_temp->part_of_prev_key= new_ref_length;
1647
s_temp->prev_length= ref_length - new_pack_length;
1648
s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
1649
s_temp->prev_key+= new_pack_length;
1650
/* +get_pack_length(org_key_length); */
1651
length= length-get_pack_length(ref_length)+
1652
get_pack_length(new_pack_length);
1653
return (int) length + s_temp->prev_length;
1779
/* If first key and next key is packed (only on delete) */
1780
if (!prev_key && org_key)
1782
get_key_length(org_key_length,org_key);
1784
if (sort_order) /* SerG */
1786
while (key < end && sort_order[*key] == sort_order[*org_key])
1793
while (key < end && *key == *org_key)
1798
if ((new_ref_length= (uint) (key - start)))
1799
new_ref_length+=pack_marker;
1805
We put a different key between two identical variable length keys
1806
Extend next key to have same prefix as this key
1808
if (new_ref_length) /* prefix of previus key */
1809
{ /* make next key longer */
1810
s_temp->part_of_prev_key= new_ref_length;
1811
s_temp->prev_length= org_key_length -
1812
(new_ref_length-pack_marker);
1813
s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
1814
n_length= get_pack_length(s_temp->prev_length);
1815
s_temp->prev_key+= (new_ref_length - pack_marker);
1816
length+= s_temp->prev_length + n_length;
1819
{ /* Can't use prev key */
1820
s_temp->part_of_prev_key=0;
1821
s_temp->prev_length= org_key_length;
1822
s_temp->n_ref_length=s_temp->n_length= org_key_length;
1823
length+= org_key_length;
1824
/* +get_pack_length(org_key_length); */
1826
return (int) length;
1829
ref_length=n_length;
1830
get_key_pack_length(n_length,next_length_pack,next_key);
1832
/* Test if new keys has fewer characters that match the previous key */
1833
if (!new_ref_length)
1834
{ /* Can't use prev key */
1835
s_temp->part_of_prev_key= 0;
1836
s_temp->prev_length= ref_length;
1837
s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
1838
/* s_temp->prev_key+= get_pack_length(org_key_length); */
1839
return (int) length+ref_length-next_length_pack;
1841
if (ref_length+pack_marker > new_ref_length)
1843
uint new_pack_length=new_ref_length-pack_marker;
1844
/* We must copy characters from the original key to the next key */
1845
s_temp->part_of_prev_key= new_ref_length;
1846
s_temp->prev_length= ref_length - new_pack_length;
1847
s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
1848
s_temp->prev_key+= new_pack_length;
1849
/* +get_pack_length(org_key_length); */
1850
length= length-get_pack_length(ref_length)+
1851
get_pack_length(new_pack_length);
1852
return (int) length + s_temp->prev_length;
1658
/* Next key wasn't a prefix of previous key */
1857
/* Next key wasn't a prefix of previous key */
1662
1861
DBUG_PRINT("test",("length: %d next_key: %lx",length,next_key));
1666
key=(start+=ref_length);
1667
if (key+n_length < key_end) /* Normalize length based */
1668
key_end=key+n_length;
1669
if (sort_order) /* SerG */
1865
key=(start+=ref_length);
1866
if (key+n_length < key_end) /* Normalize length based */
1867
key_end=key+n_length;
1868
if (sort_order) /* SerG */
1671
1870
while (key < key_end && sort_order[*key] ==
1672
sort_order[*next_key])
1679
while (key < key_end && *key == *next_key)
1684
if (!(tmp_length=(uint) (key-start)))
1685
{ /* Key can't be re-packed */
1686
s_temp->next_key_pos=0;
1689
ref_length+=tmp_length;
1690
n_length-=tmp_length;
1691
length-=tmp_length+next_length_pack; /* We gained these chars */
1871
sort_order[*next_key])
1878
while (key < key_end && *key == *next_key)
1883
if (!(tmp_length=(uint) (key-start)))
1884
{ /* Key can't be re-packed */
1885
s_temp->next_key_pos=0;
1888
ref_length+=tmp_length;
1889
n_length-=tmp_length;
1890
length-=tmp_length+next_length_pack; /* We gained these chars */
1693
1892
if (n_length == 0)
1695
s_temp->n_ref_length=pack_marker; /* Same as prev key */
1894
s_temp->n_ref_length=pack_marker; /* Same as prev key */
1699
s_temp->n_ref_length=ref_length | pack_marker;
1700
length+= get_pack_length(n_length);
1701
s_temp->n_length=n_length;
1898
s_temp->n_ref_length=ref_length | pack_marker;
1899
length+= get_pack_length(n_length);
1900
s_temp->n_length=n_length;