~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_search.c

  • Committer: Monty Taylor
  • Date: 2008-07-05 18:10:38 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: monty@inaugust.com-20080705181038-0ih0nnamu5qrut0y
Fixed prototypes. Cleaned define a little bit.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* key handling functions */
17
17
 
18
 
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
20
 
#include <drizzled/util/test.h>
 
18
#include "fulltext.h"
 
19
#include "m_ctype.h"
21
20
 
22
 
static bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
23
 
                                unsigned char *key, unsigned char *keypos,
24
 
                                uint32_t *return_key_length);
 
21
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
 
22
                                uchar *key, uchar *keypos,
 
23
                                uint *return_key_length);
25
24
 
26
25
        /* Check index */
27
26
 
55
54
        */
56
55
 
57
56
int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
58
 
               unsigned char *key, uint32_t key_len, uint32_t nextflag, register my_off_t pos)
 
57
               uchar *key, uint key_len, uint nextflag, register my_off_t pos)
59
58
{
60
 
  bool last_key;
 
59
  my_bool last_key;
61
60
  int error,flag;
62
 
  uint32_t nod_flag;
63
 
  unsigned char *keypos,*maxpos;
64
 
  unsigned char lastkey[MI_MAX_KEY_BUFF],*buff;
 
61
  uint nod_flag;
 
62
  uchar *keypos,*maxpos;
 
63
  uchar lastkey[MI_MAX_KEY_BUFF],*buff;
 
64
  DBUG_ENTER("_mi_search");
 
65
  DBUG_PRINT("enter",("pos: %lu  nextflag: %u  lastpos: %lu",
 
66
                      (ulong) pos, nextflag, (ulong) info->lastpos));
 
67
  DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
65
68
 
66
69
  if (pos == HA_OFFSET_ERROR)
67
70
  {
68
71
    my_errno=HA_ERR_KEY_NOT_FOUND;                      /* Didn't find key */
69
72
    info->lastpos= HA_OFFSET_ERROR;
70
73
    if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
71
 
      return(-1);                          /* Not found ; return error */
72
 
    return(1);                             /* Search at upper levels */
 
74
      DBUG_RETURN(-1);                          /* Not found ; return error */
 
75
    DBUG_RETURN(1);                             /* Search at upper levels */
73
76
  }
74
77
 
75
78
  if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
76
79
                               test(!(nextflag & SEARCH_SAVE_BUFF)))))
77
80
    goto err;
 
81
  DBUG_DUMP("page",(uchar*) buff,mi_getint(buff));
78
82
 
79
83
  flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
80
84
                              &keypos,lastkey, &last_key);
81
85
  if (flag == MI_FOUND_WRONG_KEY)
82
 
    return(-1);
 
86
    DBUG_RETURN(-1);
83
87
  nod_flag=mi_test_if_nod(buff);
84
88
  maxpos=buff+mi_getint(buff)-1;
85
89
 
87
91
  {
88
92
    if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
89
93
                          _mi_kpos(nod_flag,keypos))) <= 0)
90
 
      return(error);
 
94
      DBUG_RETURN(error);
91
95
 
92
96
    if (flag >0)
93
97
    {
94
98
      if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
95
99
          keypos == buff+2+nod_flag)
96
 
        return(1);                                 /* Bigger than key */
 
100
        DBUG_RETURN(1);                                 /* Bigger than key */
97
101
    }
98
102
    else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
99
 
      return(1);                                   /* Smaller than key */
 
103
      DBUG_RETURN(1);                                   /* Smaller than key */
100
104
  }
101
105
  else
102
106
  {
107
111
      if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
108
112
                            _mi_kpos(nod_flag,keypos))) >= 0 ||
109
113
          my_errno != HA_ERR_KEY_NOT_FOUND)
110
 
        return(error);
 
114
        DBUG_RETURN(error);
111
115
      info->last_keypage= HA_OFFSET_ERROR;              /* Buffer not in mem */
112
116
    }
113
117
  }
114
118
  if (pos != info->last_keypage)
115
119
  {
116
 
    unsigned char *old_buff=buff;
 
120
    uchar *old_buff=buff;
117
121
    if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
118
122
                                 test(!(nextflag & SEARCH_SAVE_BUFF)))))
119
123
      goto err;
123
127
 
124
128
  if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
125
129
  {
126
 
    uint32_t not_used[2];
 
130
    uint not_used[2];
127
131
    if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
128
132
                         &info->lastkey_length))
129
133
      goto err;
152
156
  info->page_changed=0;
153
157
  info->buff_used= (info->buff != buff);        /* If we have to reread buff */
154
158
 
155
 
  return(0);
 
159
  DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
 
160
  DBUG_RETURN(0);
156
161
 
157
162
err:
 
163
  DBUG_PRINT("exit",("Error: %d",my_errno));
158
164
  info->lastpos= HA_OFFSET_ERROR;
159
165
  info->page_changed=1;
160
 
  return (-1);
 
166
  DBUG_RETURN (-1);
161
167
} /* _mi_search */
162
168
 
163
169
 
166
172
        /* ret_pos point to where find or bigger key starts */
167
173
        /* ARGSUSED */
168
174
 
169
 
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
170
 
                   unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
171
 
                   unsigned char *buff __attribute__((unused)), bool *last_key)
 
175
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
 
176
                   uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
 
177
                   uchar *buff __attribute__((unused)), my_bool *last_key)
172
178
{
173
179
  register int start,mid,end,save_end;
174
180
  int flag;
175
 
  uint32_t totlength,nod_flag,not_used[2];
 
181
  uint totlength,nod_flag,not_used[2];
 
182
  DBUG_ENTER("_mi_bin_search");
176
183
 
177
184
  totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page));
178
185
  start=0; mid=1;
179
186
  save_end=end=(int) ((mi_getint(page)-2-nod_flag)/totlength-1);
 
187
  DBUG_PRINT("test",("mi_getint: %d  end: %d",mi_getint(page),end));
180
188
  page+=2+nod_flag;
181
189
 
182
190
  while (start != end)
196
204
    start++;                    /* point at next, bigger key */
197
205
  *ret_pos=page+(uint) start*totlength;
198
206
  *last_key= end == save_end;
199
 
  return(flag);
 
207
  DBUG_PRINT("exit",("flag: %d  keypos: %d",flag,start));
 
208
  DBUG_RETURN(flag);
200
209
} /* _mi_bin_search */
201
210
 
202
211
 
226
235
    < 0         Not found.
227
236
*/
228
237
 
229
 
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
230
 
                   unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
231
 
                   unsigned char *buff, bool *last_key)
 
238
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
 
239
                   uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
 
240
                   uchar *buff, my_bool *last_key)
232
241
{
233
 
  int flag=0;
234
 
  uint32_t nod_flag,length=0,not_used[2];
235
 
  unsigned char t_buff[MI_MAX_KEY_BUFF],*end;
 
242
  int flag;
 
243
  uint nod_flag,length,not_used[2];
 
244
  uchar t_buff[MI_MAX_KEY_BUFF],*end;
 
245
  DBUG_ENTER("_mi_seq_search");
236
246
 
237
247
  end= page+mi_getint(page);
238
248
  nod_flag=mi_test_if_nod(page);
246
256
    {
247
257
      mi_print_error(info->s, HA_ERR_CRASHED);
248
258
      my_errno=HA_ERR_CRASHED;
249
 
      return(MI_FOUND_WRONG_KEY);
 
259
      DBUG_PRINT("error",
 
260
                 ("Found wrong key:  length: %u  page: 0x%lx  end: 0x%lx",
 
261
                  length, (long) page, (long) end));
 
262
      DBUG_RETURN(MI_FOUND_WRONG_KEY);
250
263
    }
251
264
    if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
252
265
                         not_used)) >= 0)
253
266
      break;
 
267
#ifdef EXTRA_DEBUG
 
268
    DBUG_PRINT("loop",("page: 0x%lx  key: '%s'  flag: %d", (long) page, t_buff,
 
269
                       flag));
 
270
#endif
254
271
    memcpy(buff,t_buff,length);
255
272
    *ret_pos=page;
256
273
  }
257
274
  if (flag == 0)
258
275
    memcpy(buff,t_buff,length);                 /* Result is first key */
259
276
  *last_key= page == end;
260
 
  return(flag);
 
277
  DBUG_PRINT("exit",("flag: %d  ret_pos: 0x%lx", flag, (long) *ret_pos));
 
278
  DBUG_RETURN(flag);
261
279
} /* _mi_seq_search */
262
280
 
263
281
 
264
 
int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
265
 
                      unsigned char *key, uint32_t key_len, uint32_t nextflag, unsigned char **ret_pos,
266
 
                      unsigned char *buff, bool *last_key)
 
282
int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
 
283
                      uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
 
284
                      uchar *buff, my_bool *last_key)
267
285
{
268
286
  /*
269
287
    my_flag is raw comparison result to be changed according to
271
289
    flag is the value returned by ha_key_cmp and as treated as final
272
290
  */
273
291
  int flag=0, my_flag=-1;
274
 
  uint32_t nod_flag, length=0, len, matched, cmplen, kseg_len;
275
 
  uint32_t prefix_len=0,suffix_len;
276
 
  int key_len_skip, seg_len_pack=0, key_len_left;
277
 
  unsigned char *end, *kseg, *vseg;
278
 
  unsigned char *sort_order=keyinfo->seg->charset->sort_order;
279
 
  unsigned char tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
280
 
  unsigned char *saved_from=NULL, *saved_to=NULL, *saved_vseg=NULL;
281
 
  uint32_t  saved_length=0, saved_prefix_len=0;
282
 
  uint32_t  length_pack;
283
 
 
 
292
  uint nod_flag, length, len, matched, cmplen, kseg_len;
 
293
  uint prefix_len,suffix_len;
 
294
  int key_len_skip, seg_len_pack, key_len_left;
 
295
  uchar *end, *kseg, *vseg;
 
296
  uchar *sort_order=keyinfo->seg->charset->sort_order;
 
297
  uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
 
298
  uchar *saved_from, *saved_to, *saved_vseg;
 
299
  uint  saved_length=0, saved_prefix_len=0;
 
300
  uint  length_pack;
 
301
  DBUG_ENTER("_mi_prefix_search");
284
302
 
285
303
  t_buff[0]=0;                                  /* Avoid bugs */
286
304
  end= page+mi_getint(page);
294
312
  key_len_left=(int) key_len- (int) key_len_skip;
295
313
  /* If key_len is 0, then lenght_pack is 1, then key_len_left is -1. */
296
314
  cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
 
315
  DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
297
316
 
298
317
  /*
299
318
    Keys are compressed the following way:
313
332
 
314
333
  while (page < end)
315
334
  {
316
 
    uint32_t packed= *page & 128;
 
335
    uint packed= *page & 128;
317
336
 
318
337
    vseg=page;
319
338
    if (keyinfo->seg->length >= 127)
355
374
    saved_vseg=vseg;
356
375
    saved_prefix_len=prefix_len;
357
376
 
 
377
    DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,
 
378
                       suffix_len,vseg));
358
379
    {
359
 
      unsigned char *from=vseg+suffix_len;
 
380
      uchar *from=vseg+suffix_len;
360
381
      HA_KEYSEG *keyseg;
361
 
      uint32_t l;
 
382
      uint l;
362
383
 
363
384
      for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
364
385
      {
386
407
    {
387
408
      mi_print_error(info->s, HA_ERR_CRASHED);
388
409
      my_errno=HA_ERR_CRASHED;
389
 
      return(MI_FOUND_WRONG_KEY);
 
410
      DBUG_PRINT("error",
 
411
                 ("Found wrong key:  length: %u  page: 0x%lx  end: %lx",
 
412
                  length, (long) page, (long) end));
 
413
      DBUG_RETURN(MI_FOUND_WRONG_KEY);
390
414
    }
391
415
 
392
416
    if (matched >= prefix_len)
393
417
    {
394
418
      /* We have to compare. But we can still skip part of the key */
395
 
      uint32_t  left;
396
 
      unsigned char *k=kseg+prefix_len;
 
419
      uint  left;
 
420
      uchar *k=kseg+prefix_len;
397
421
 
398
422
      /*
399
423
        If prefix_len > cmplen then we are in the end-space comparison
439
463
          else
440
464
          {
441
465
            /* We have to compare k and vseg as if they were space extended */
442
 
            unsigned char *k_end= k+ (cmplen - len);
 
466
            uchar *k_end= k+ (cmplen - len);
443
467
            for ( ; k < k_end && *k == ' '; k++) ;
444
468
            if (k == k_end)
445
469
              goto cmp_rest;            /* should never happen */
446
 
            if (*k < (unsigned char) ' ')
 
470
            if (*k < (uchar) ' ')
447
471
            {
448
472
              my_flag= 1;               /* Compared string is smaller */
449
473
              break;
453
477
        }
454
478
        else if (len > cmplen)
455
479
        {
456
 
          unsigned char *vseg_end;
 
480
          uchar *vseg_end;
457
481
          if ((nextflag & SEARCH_PREFIX) && key_len_left == 0)
458
482
            goto fix_flag;
459
483
 
460
484
          /* We have to compare k and vseg as if they were space extended */
461
485
          for (vseg_end= vseg + (len-cmplen) ;
462
 
               vseg < vseg_end && *vseg == (unsigned char) ' ';
 
486
               vseg < vseg_end && *vseg == (uchar) ' ';
463
487
               vseg++, matched++) ;
464
 
          assert(vseg < vseg_end);
 
488
          DBUG_ASSERT(vseg < vseg_end);
465
489
 
466
 
          if (*vseg > (unsigned char) ' ')
 
490
          if (*vseg > (uchar) ' ')
467
491
          {
468
492
            my_flag= 1;                 /* Compared string is smaller */
469
493
            break;
475
499
      cmp_rest:
476
500
          if (key_len_left>0)
477
501
          {
478
 
            uint32_t not_used[2];
 
502
            uint not_used[2];
479
503
            if ((flag = ha_key_cmp(keyinfo->seg+1,vseg,
480
504
                                   k, key_len_left, nextflag, not_used)) >= 0)
481
505
              break;
487
511
              visited and 0 otherwise,  i.e. flag <=0 here always !!!
488
512
            */
489
513
        fix_flag:
490
 
            assert(flag <= 0);
 
514
            DBUG_ASSERT(flag <= 0);
491
515
            if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
492
516
              flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
493
517
            if (flag>=0)
519
543
 
520
544
  *last_key= page == end;
521
545
 
522
 
  return(flag);
 
546
  DBUG_PRINT("exit",("flag: %d  ret_pos: 0x%lx", flag, (long) *ret_pos));
 
547
  DBUG_RETURN(flag);
523
548
} /* _mi_prefix_search */
524
549
 
525
550
 
526
551
        /* Get pos to a key_block */
527
552
 
528
 
my_off_t _mi_kpos(uint32_t nod_flag, unsigned char *after_key)
 
553
my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
529
554
{
530
555
  after_key-=nod_flag;
531
556
  switch (nod_flag) {
561
586
 
562
587
        /* Save pos to a key_block */
563
588
 
564
 
void _mi_kpointer(register MI_INFO *info, register unsigned char *buff, my_off_t pos)
 
589
void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
565
590
{
566
591
  pos/=MI_MIN_KEY_BLOCK_LENGTH;
567
592
  switch (info->s->base.key_reflength) {
580
605
  case 4: mi_int4store(buff,pos); break;
581
606
  case 3: mi_int3store(buff,pos); break;
582
607
  case 2: mi_int2store(buff,(uint) pos); break;
583
 
  case 1: buff[0]= (unsigned char) pos; break;
 
608
  case 1: buff[0]= (uchar) pos; break;
584
609
  default: abort();                             /* impossible */
585
610
  }
586
611
} /* _mi_kpointer */
589
614
        /* Calc pos to a data-record from a key */
590
615
 
591
616
 
592
 
my_off_t _mi_dpos(MI_INFO *info, uint32_t nod_flag, unsigned char *after_key)
 
617
my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
593
618
{
594
619
  my_off_t pos;
595
620
  after_key-=(nod_flag + info->s->rec_reflength);
619
644
 
620
645
/* Calc position from a record pointer ( in delete link chain ) */
621
646
 
622
 
my_off_t _mi_rec_pos(MYISAM_SHARE *s, unsigned char *ptr)
 
647
my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
623
648
{
624
649
  my_off_t pos;
625
650
  switch (s->rec_reflength) {
654
679
#endif
655
680
  case 4:
656
681
    pos= (my_off_t) mi_uint4korr(ptr);
657
 
    if (pos == (my_off_t) UINT32_MAX)
 
682
    if (pos == (my_off_t) (uint32) ~0L)
658
683
      return  HA_OFFSET_ERROR;
659
684
    break;
660
685
  case 3:
677
702
 
678
703
        /* save position to record */
679
704
 
680
 
void _mi_dpointer(MI_INFO *info, unsigned char *buff, my_off_t pos)
 
705
void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
681
706
{
682
707
  if (!(info->s->options &
683
708
        (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
716
741
 
717
742
        /* same as _mi_get_key but used with fixed length keys */
718
743
 
719
 
uint32_t _mi_get_static_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
720
 
                       register unsigned char **page, register unsigned char *key)
 
744
uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
 
745
                       register uchar **page, register uchar *key)
721
746
{
722
 
  memcpy(key, *page, keyinfo->keylength+nod_flag);
 
747
  memcpy((uchar*) key,(uchar*) *page,
 
748
         (size_t) (keyinfo->keylength+nod_flag));
723
749
  *page+=keyinfo->keylength+nod_flag;
724
750
  return(keyinfo->keylength);
725
751
} /* _mi_get_static_key */
739
765
    key_length + length of data pointer
740
766
*/
741
767
 
742
 
uint32_t _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
743
 
                      register unsigned char **page_pos, register unsigned char *key)
 
768
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
 
769
                      register uchar **page_pos, register uchar *key)
744
770
{
745
771
  register HA_KEYSEG *keyseg;
746
 
  unsigned char *start_key,*page=*page_pos;
747
 
  uint32_t length;
 
772
  uchar *start_key,*page=*page_pos;
 
773
  uint length;
748
774
 
749
775
  start_key=key;
750
776
  for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
752
778
    if (keyseg->flag & HA_PACK_KEY)
753
779
    {
754
780
      /* key with length, packed to previous key */
755
 
      unsigned char *start=key;
756
 
      uint32_t packed= *page & 128,tot_length,rest_length;
 
781
      uchar *start=key;
 
782
      uint packed= *page & 128,tot_length,rest_length;
757
783
      if (keyseg->length >= 127)
758
784
      {
759
785
        length=mi_uint2korr(page) & 32767;
778
804
          key+= length;                         /* Same diff_key as prev */
779
805
          if (length > keyseg->length)
780
806
          {
 
807
            DBUG_PRINT("error",
 
808
                       ("Found too long null packed key: %u of %u at 0x%lx",
 
809
                        length, keyseg->length, (long) *page_pos));
 
810
            DBUG_DUMP("key",(uchar*) *page_pos,16);
781
811
            mi_print_error(keyinfo->share, HA_ERR_CRASHED);
782
812
            my_errno=HA_ERR_CRASHED;
783
813
            return 0;
804
834
        }
805
835
        else if (tot_length < 255 && *start == 255)
806
836
        {
807
 
          memcpy(key+1,key+3,length);
 
837
          bmove(key+1,key+3,length);
808
838
          *key=tot_length;
809
839
          key+=1+length;
810
840
        }
832
862
      }
833
863
      if (length > (uint) keyseg->length)
834
864
      {
 
865
        DBUG_PRINT("error",("Found too long packed key: %u of %u at 0x%lx",
 
866
                            length, keyseg->length, (long) *page_pos));
 
867
        DBUG_DUMP("key",(uchar*) *page_pos,16);
835
868
        mi_print_error(keyinfo->share, HA_ERR_CRASHED);
836
869
        my_errno=HA_ERR_CRASHED;
837
870
        return 0;                               /* Error */
848
881
      if (keyseg->flag &
849
882
          (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
850
883
      {
851
 
        unsigned char *tmp=page;
 
884
        uchar *tmp=page;
852
885
        get_key_length(length,tmp);
853
886
        length+=(uint) (tmp-page);
854
887
      }
855
888
      else
856
889
        length=keyseg->length;
857
890
    }
858
 
    memcpy(key, page, length);
 
891
    memcpy((uchar*) key,(uchar*) page,(size_t) length);
859
892
    key+=length;
860
893
    page+=length;
861
894
  }
862
895
  length=keyseg->length+nod_flag;
863
 
  memcpy(key,page,length);
 
896
  bmove((uchar*) key,(uchar*) page,length);
864
897
  *page_pos= page+length;
865
898
  return ((uint) (key-start_key)+keyseg->length);
866
899
} /* _mi_get_pack_key */
869
902
 
870
903
/* key that is packed relatively to previous */
871
904
 
872
 
uint32_t _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
873
 
                             register unsigned char **page_pos, register unsigned char *key)
 
905
uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
 
906
                             register uchar **page_pos, register uchar *key)
874
907
{
875
908
  register HA_KEYSEG *keyseg;
876
 
  unsigned char *start_key,*page,*page_end,*from,*from_end;
877
 
  uint32_t length,tmp;
 
909
  uchar *start_key,*page,*page_end,*from,*from_end;
 
910
  uint length,tmp;
 
911
  DBUG_ENTER("_mi_get_binary_pack_key");
878
912
 
879
913
  page= *page_pos;
880
914
  page_end=page+MI_MAX_KEY_BUFF+1;
899
933
  {
900
934
    if (length > keyinfo->maxlength)
901
935
    {
 
936
      DBUG_PRINT("error",
 
937
                 ("Found too long binary packed key: %u of %u at 0x%lx",
 
938
                  length, keyinfo->maxlength, (long) *page_pos));
 
939
      DBUG_DUMP("key",(uchar*) *page_pos,16);
902
940
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
903
941
      my_errno=HA_ERR_CRASHED;
904
 
      return(0);                                 /* Wrong key */
 
942
      DBUG_RETURN(0);                                 /* Wrong key */
905
943
    }
906
944
    /* Key is packed against prev key, take prefix from prev key. */
907
945
    from= key;
954
992
      length-=tmp;
955
993
      from=page; from_end=page_end;
956
994
    }
957
 
    memmove(key, from, length);
 
995
    DBUG_PRINT("info",("key: 0x%lx  from: 0x%lx  length: %u",
 
996
                       (long) key, (long) from, length));
 
997
    memmove((uchar*) key, (uchar*) from, (size_t) length);
958
998
    key+=length;
959
999
    from+=length;
960
1000
  }
980
1020
    */
981
1021
    if (from_end != page_end)
982
1022
    {
 
1023
      DBUG_PRINT("error",("Error when unpacking key"));
983
1024
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
984
1025
      my_errno=HA_ERR_CRASHED;
985
 
      return(0);                                 /* Error */
 
1026
      DBUG_RETURN(0);                                 /* Error */
986
1027
    }
987
1028
    /* Copy data pointer and, if appropriate, key block pointer. */
988
 
    memcpy(key, from, length);
 
1029
    memcpy((uchar*) key,(uchar*) from,(size_t) length);
989
1030
    *page_pos= from+length;
990
1031
  }
991
 
  return((uint) (key-start_key)+keyseg->length);
 
1032
  DBUG_RETURN((uint) (key-start_key)+keyseg->length);
992
1033
}
993
1034
 
994
1035
 
995
1036
        /* Get key at position without knowledge of previous key */
996
1037
        /* Returns pointer to next key */
997
1038
 
998
 
unsigned char *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
999
 
                   unsigned char *key, unsigned char *keypos, uint32_t *return_key_length)
 
1039
uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
 
1040
                   uchar *key, uchar *keypos, uint *return_key_length)
1000
1041
{
1001
 
  uint32_t nod_flag;
 
1042
  uint nod_flag;
 
1043
  DBUG_ENTER("_mi_get_key");
1002
1044
 
1003
1045
  nod_flag=mi_test_if_nod(page);
1004
1046
  if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1005
1047
  {
1006
 
    memcpy(key,keypos,keyinfo->keylength+nod_flag);
1007
 
    return(keypos+keyinfo->keylength+nod_flag);
 
1048
    bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
 
1049
    DBUG_RETURN(keypos+keyinfo->keylength+nod_flag);
1008
1050
  }
1009
1051
  else
1010
1052
  {
1017
1059
      {
1018
1060
        mi_print_error(info->s, HA_ERR_CRASHED);
1019
1061
        my_errno=HA_ERR_CRASHED;
1020
 
        return(0);
 
1062
        DBUG_RETURN(0);
1021
1063
      }
1022
1064
    }
1023
1065
  }
1024
 
  return(page);
 
1066
  DBUG_PRINT("exit",("page: 0x%lx  length: %u", (long) page,
 
1067
                     *return_key_length));
 
1068
  DBUG_RETURN(page);
1025
1069
} /* _mi_get_key */
1026
1070
 
1027
1071
 
1028
1072
        /* Get key at position without knowledge of previous key */
1029
1073
        /* Returns 0 if ok */
1030
1074
 
1031
 
static bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
1032
 
                                unsigned char *key, unsigned char *keypos,
1033
 
                                uint32_t *return_key_length)
 
1075
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
 
1076
                                uchar *key, uchar *keypos,
 
1077
                                uint *return_key_length)
1034
1078
{
1035
 
  uint32_t nod_flag;
 
1079
  uint nod_flag;
 
1080
  DBUG_ENTER("_mi_get_prev_key");
1036
1081
 
1037
1082
  nod_flag=mi_test_if_nod(page);
1038
1083
  if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1039
1084
  {
1040
1085
    *return_key_length=keyinfo->keylength;
1041
 
    memcpy(key, keypos - *return_key_length-nod_flag, *return_key_length);
1042
 
    return(0);
 
1086
    bmove((uchar*) key,(uchar*) keypos- *return_key_length-nod_flag,
 
1087
          *return_key_length);
 
1088
    DBUG_RETURN(0);
1043
1089
  }
1044
1090
  else
1045
1091
  {
1052
1098
      {
1053
1099
        mi_print_error(info->s, HA_ERR_CRASHED);
1054
1100
        my_errno=HA_ERR_CRASHED;
1055
 
        return(1);
 
1101
        DBUG_RETURN(1);
1056
1102
      }
1057
1103
    }
1058
1104
  }
1059
 
  return(0);
 
1105
  DBUG_RETURN(0);
1060
1106
} /* _mi_get_key */
1061
1107
 
1062
1108
 
1064
1110
        /* Get last key from key-page */
1065
1111
        /* Return pointer to where key starts */
1066
1112
 
1067
 
unsigned char *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
1068
 
                        unsigned char *lastkey, unsigned char *endpos, uint32_t *return_key_length)
 
1113
uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
 
1114
                        uchar *lastkey, uchar *endpos, uint *return_key_length)
1069
1115
{
1070
 
  uint32_t nod_flag;
1071
 
  unsigned char *lastpos;
 
1116
  uint nod_flag;
 
1117
  uchar *lastpos;
 
1118
  DBUG_ENTER("_mi_get_last_key");
 
1119
  DBUG_PRINT("enter",("page: 0x%lx  endpos: 0x%lx", (long) page,
 
1120
                      (long) endpos));
1072
1121
 
1073
1122
  nod_flag=mi_test_if_nod(page);
1074
1123
  if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1076
1125
    lastpos=endpos-keyinfo->keylength-nod_flag;
1077
1126
    *return_key_length=keyinfo->keylength;
1078
1127
    if (lastpos > page)
1079
 
      memcpy(lastkey,lastpos,keyinfo->keylength+nod_flag);
 
1128
      bmove((uchar*) lastkey,(uchar*) lastpos,keyinfo->keylength+nod_flag);
1080
1129
  }
1081
1130
  else
1082
1131
  {
1088
1137
      *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
1089
1138
      if (*return_key_length == 0)
1090
1139
      {
 
1140
        DBUG_PRINT("error",("Couldn't find last key:  page: 0x%lx",
 
1141
                            (long) page));
1091
1142
        mi_print_error(info->s, HA_ERR_CRASHED);
1092
1143
        my_errno=HA_ERR_CRASHED;
1093
 
        return(0);
 
1144
        DBUG_RETURN(0);
1094
1145
      }
1095
1146
    }
1096
1147
  }
1097
 
  return(lastpos);
 
1148
  DBUG_PRINT("exit",("lastpos: 0x%lx  length: %u", (long) lastpos,
 
1149
                     *return_key_length));
 
1150
  DBUG_RETURN(lastpos);
1098
1151
} /* _mi_get_last_key */
1099
1152
 
1100
1153
 
1101
1154
        /* Calculate length of key */
1102
1155
 
1103
 
uint32_t _mi_keylength(MI_KEYDEF *keyinfo, register unsigned char *key)
 
1156
uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
1104
1157
{
1105
1158
  register HA_KEYSEG *keyseg;
1106
 
  unsigned char *start;
 
1159
  uchar *start;
1107
1160
 
1108
1161
  if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1109
1162
    return (keyinfo->keylength);
1116
1169
        continue;
1117
1170
    if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART))
1118
1171
    {
1119
 
      uint32_t length;
 
1172
      uint length;
1120
1173
      get_key_length(length,key);
1121
1174
      key+=length;
1122
1175
    }
1135
1188
  after '0xDF' but find 'ss'
1136
1189
*/
1137
1190
 
1138
 
uint32_t _mi_keylength_part(MI_KEYDEF *keyinfo, register unsigned char *key,
 
1191
uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
1139
1192
                        HA_KEYSEG *end)
1140
1193
{
1141
1194
  register HA_KEYSEG *keyseg;
1142
 
  unsigned char *start= key;
 
1195
  uchar *start= key;
1143
1196
 
1144
1197
  for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
1145
1198
  {
1148
1201
        continue;
1149
1202
    if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART))
1150
1203
    {
1151
 
      uint32_t length;
 
1204
      uint length;
1152
1205
      get_key_length(length,key);
1153
1206
      key+=length;
1154
1207
    }
1160
1213
 
1161
1214
        /* Move a key */
1162
1215
 
1163
 
unsigned char *_mi_move_key(MI_KEYDEF *keyinfo, unsigned char *to, unsigned char *from)
 
1216
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
1164
1217
{
1165
 
  register uint32_t length;
1166
 
  length= _mi_keylength(keyinfo, from);
1167
 
  memcpy(to, from, length);
 
1218
  register uint length;
 
1219
  memcpy((uchar*) to, (uchar*) from,
 
1220
         (size_t) (length=_mi_keylength(keyinfo,from)));
1168
1221
  return to+length;
1169
1222
}
1170
1223
 
1172
1225
        /* This can't be used when database is touched after last read */
1173
1226
 
1174
1227
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1175
 
                    unsigned char *key, uint32_t key_length, uint32_t nextflag, my_off_t pos)
 
1228
                    uchar *key, uint key_length, uint nextflag, my_off_t pos)
1176
1229
{
1177
1230
  int error;
1178
 
  uint32_t nod_flag;
1179
 
  unsigned char lastkey[MI_MAX_KEY_BUFF];
 
1231
  uint nod_flag;
 
1232
  uchar lastkey[MI_MAX_KEY_BUFF];
 
1233
  DBUG_ENTER("_mi_search_next");
 
1234
  DBUG_PRINT("enter",("nextflag: %u  lastpos: %lu  int_keypos: %lu",
 
1235
                      nextflag, (ulong) info->lastpos,
 
1236
                      (ulong) info->int_keypos));
 
1237
  DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
1180
1238
 
1181
1239
  /* Force full read if we are at last key or if we are not on a leaf
1182
1240
     and the key tree has changed since we used it last time
1189
1247
      info->page_changed ||
1190
1248
      (info->int_keytree_version != keyinfo->version &&
1191
1249
       (info->int_nod_flag || info->buff_used)))
1192
 
    return(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
 
1250
    DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1193
1251
                           nextflag | SEARCH_SAVE_BUFF, pos));
1194
1252
 
1195
1253
  if (info->buff_used)
1196
1254
  {
1197
1255
    if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
1198
1256
                           DFLT_INIT_HITS,info->buff,0))
1199
 
      return(-1);
 
1257
      DBUG_RETURN(-1);
1200
1258
    info->buff_used=0;
1201
1259
  }
1202
1260
 
1210
1268
    {
1211
1269
      if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1212
1270
                            nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
1213
 
        return(error);
 
1271
        DBUG_RETURN(error);
1214
1272
    }
1215
1273
    memcpy(lastkey,key,key_length);
1216
1274
    if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
1217
1275
                                                   &info->int_keypos,lastkey)))
1218
 
      return(-1);
 
1276
      DBUG_RETURN(-1);
1219
1277
  }
1220
1278
  else                                                  /* Previous key */
1221
1279
  {
1222
 
    uint32_t length;
 
1280
    uint length;
1223
1281
    /* Find start of previous key */
1224
1282
    info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
1225
1283
                                      info->int_keypos, &length);
1226
1284
    if (!info->int_keypos)
1227
 
      return(-1);
 
1285
      DBUG_RETURN(-1);
1228
1286
    if (info->int_keypos == info->buff+2)
1229
 
      return(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
 
1287
      DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1230
1288
                             nextflag | SEARCH_SAVE_BUFF, pos));
1231
1289
    if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1232
1290
                          nextflag | SEARCH_SAVE_BUFF,
1233
1291
                          _mi_kpos(nod_flag,info->int_keypos))) <= 0)
1234
 
      return(error);
 
1292
      DBUG_RETURN(error);
1235
1293
 
1236
1294
    /* QQ: We should be able to optimize away the following call */
1237
1295
    if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
1238
1296
                           info->int_keypos,&info->lastkey_length))
1239
 
      return(-1);
 
1297
      DBUG_RETURN(-1);
1240
1298
  }
1241
1299
  memcpy(info->lastkey,lastkey,info->lastkey_length);
1242
1300
  info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1243
 
  return(0);
 
1301
  DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
 
1302
  DBUG_RETURN(0);
1244
1303
} /* _mi_search_next */
1245
1304
 
1246
1305
 
1250
1309
int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1251
1310
                     register my_off_t pos)
1252
1311
{
1253
 
  uint32_t nod_flag;
1254
 
  unsigned char *page;
 
1312
  uint nod_flag;
 
1313
  uchar *page;
 
1314
  DBUG_ENTER("_mi_search_first");
1255
1315
 
1256
1316
  if (pos == HA_OFFSET_ERROR)
1257
1317
  {
1258
1318
    my_errno=HA_ERR_KEY_NOT_FOUND;
1259
1319
    info->lastpos= HA_OFFSET_ERROR;
1260
 
    return(-1);
 
1320
    DBUG_RETURN(-1);
1261
1321
  }
1262
1322
 
1263
1323
  do
1265
1325
    if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
1266
1326
    {
1267
1327
      info->lastpos= HA_OFFSET_ERROR;
1268
 
      return(-1);
 
1328
      DBUG_RETURN(-1);
1269
1329
    }
1270
1330
    nod_flag=mi_test_if_nod(info->buff);
1271
1331
    page=info->buff+2+nod_flag;
1273
1333
 
1274
1334
  if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
1275
1335
                                                 info->lastkey)))
1276
 
    return(-1);                            /* Crashed */
 
1336
    DBUG_RETURN(-1);                            /* Crashed */
1277
1337
 
1278
1338
  info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
1279
1339
  info->int_nod_flag=nod_flag;
1282
1342
  info->page_changed=info->buff_used=0;
1283
1343
  info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1284
1344
 
1285
 
  return(0);
 
1345
  DBUG_PRINT("exit",("found key at %lu", (ulong) info->lastpos));
 
1346
  DBUG_RETURN(0);
1286
1347
} /* _mi_search_first */
1287
1348
 
1288
1349
 
1292
1353
int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1293
1354
                    register my_off_t pos)
1294
1355
{
1295
 
  uint32_t nod_flag;
1296
 
  unsigned char *buff,*page;
 
1356
  uint nod_flag;
 
1357
  uchar *buff,*page;
 
1358
  DBUG_ENTER("_mi_search_last");
1297
1359
 
1298
1360
  if (pos == HA_OFFSET_ERROR)
1299
1361
  {
1300
1362
    my_errno=HA_ERR_KEY_NOT_FOUND;                      /* Didn't find key */
1301
1363
    info->lastpos= HA_OFFSET_ERROR;
1302
 
    return(-1);
 
1364
    DBUG_RETURN(-1);
1303
1365
  }
1304
1366
 
1305
1367
  buff=info->buff;
1308
1370
    if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
1309
1371
    {
1310
1372
      info->lastpos= HA_OFFSET_ERROR;
1311
 
      return(-1);
 
1373
      DBUG_RETURN(-1);
1312
1374
    }
1313
1375
    page= buff+mi_getint(buff);
1314
1376
    nod_flag=mi_test_if_nod(buff);
1316
1378
 
1317
1379
  if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page,
1318
1380
                        &info->lastkey_length))
1319
 
    return(-1);
 
1381
    DBUG_RETURN(-1);
1320
1382
  info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1321
1383
  info->int_keypos=info->int_maxpos=page;
1322
1384
  info->int_nod_flag=nod_flag;
1324
1386
  info->last_search_keypage=info->last_keypage;
1325
1387
  info->page_changed=info->buff_used=0;
1326
1388
 
1327
 
  return(0);
 
1389
  DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
 
1390
  DBUG_RETURN(0);
1328
1391
} /* _mi_search_last */
1329
1392
 
1330
1393
 
1345
1408
/* Static length key */
1346
1409
 
1347
1410
int
1348
 
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1349
 
                           unsigned char *next_pos  __attribute__((unused)),
1350
 
                           unsigned char *org_key  __attribute__((unused)),
1351
 
                           unsigned char *prev_key __attribute__((unused)),
1352
 
                           unsigned char *key, MI_KEY_PARAM *s_temp)
 
1411
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
 
1412
                           uchar *next_pos  __attribute__((unused)),
 
1413
                           uchar *org_key  __attribute__((unused)),
 
1414
                           uchar *prev_key __attribute__((unused)),
 
1415
                           uchar *key, MI_KEY_PARAM *s_temp)
1353
1416
{
1354
1417
  s_temp->key=key;
1355
1418
  return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
1358
1421
/* Variable length key */
1359
1422
 
1360
1423
int
1361
 
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1362
 
                        unsigned char *next_pos  __attribute__((unused)),
1363
 
                        unsigned char *org_key  __attribute__((unused)),
1364
 
                        unsigned char *prev_key __attribute__((unused)),
1365
 
                        unsigned char *key, MI_KEY_PARAM *s_temp)
 
1424
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
 
1425
                        uchar *next_pos  __attribute__((unused)),
 
1426
                        uchar *org_key  __attribute__((unused)),
 
1427
                        uchar *prev_key __attribute__((unused)),
 
1428
                        uchar *key, MI_KEY_PARAM *s_temp)
1366
1429
{
1367
1430
  s_temp->key=key;
1368
1431
  return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
1388
1451
*/
1389
1452
 
1390
1453
int
1391
 
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *next_key,
1392
 
                             unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
 
1454
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
 
1455
                             uchar *org_key, uchar *prev_key, uchar *key,
1393
1456
                             MI_KEY_PARAM *s_temp)
1394
1457
{
1395
1458
  register HA_KEYSEG *keyseg;
1396
1459
  int length;
1397
 
  uint32_t key_length,ref_length,org_key_length=0,
 
1460
  uint key_length,ref_length,org_key_length=0,
1398
1461
       length_pack,new_key_length,diff_flag,pack_marker;
1399
 
  unsigned char *start,*end,*key_end,*sort_order;
1400
 
  bool same_length;
 
1462
  uchar *start,*end,*key_end,*sort_order;
 
1463
  my_bool same_length;
1401
1464
 
1402
1465
  length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0;
1403
1466
  same_length=0; keyseg=keyinfo->seg;
1404
1467
  key_length=_mi_keylength(keyinfo,key)+nod_flag;
1405
1468
 
1406
1469
  sort_order=0;
 
1470
  if ((keyinfo->flag & HA_FULLTEXT) &&
 
1471
      ((keyseg->type == HA_KEYTYPE_TEXT) ||
 
1472
       (keyseg->type == HA_KEYTYPE_VARTEXT1) ||
 
1473
       (keyseg->type == HA_KEYTYPE_VARTEXT2)) &&
 
1474
      !use_strnxfrm(keyseg->charset))
 
1475
    sort_order=keyseg->charset->sort_order;
1407
1476
 
1408
1477
  /* diff flag contains how many bytes is needed to pack key */
1409
1478
  if (keyseg->length >= 127)
1508
1577
  }
1509
1578
  s_temp->totlength=(uint) length;
1510
1579
  s_temp->prev_length=0;
 
1580
  DBUG_PRINT("test",("tot_length: %u  length: %d  uniq_key_length: %u",
 
1581
                     key_length, length, s_temp->key_length));
1511
1582
 
1512
1583
        /* If something after that hasn't length=0, test if we can combine */
1513
1584
  if ((s_temp->next_key_pos=next_key))
1514
1585
  {
1515
 
    uint32_t packed,n_length;
 
1586
    uint packed,n_length;
1516
1587
 
1517
1588
    packed = *next_key & 128;
1518
1589
    if (diff_flag == 2)
1527
1598
 
1528
1599
    if (n_length || packed)             /* Don't pack 0 length keys */
1529
1600
    {
1530
 
      uint32_t next_length_pack, new_ref_length=s_temp->ref_length;
 
1601
      uint next_length_pack, new_ref_length=s_temp->ref_length;
1531
1602
 
1532
1603
      if (packed)
1533
1604
      {
1595
1666
        }
1596
1667
        if (ref_length+pack_marker > new_ref_length)
1597
1668
        {
1598
 
          uint32_t new_pack_length=new_ref_length-pack_marker;
 
1669
          uint new_pack_length=new_ref_length-pack_marker;
1599
1670
          /* We must copy characters from the original key to the next key */
1600
1671
          s_temp->part_of_prev_key= new_ref_length;
1601
1672
          s_temp->prev_length=      ref_length - new_pack_length;
1611
1682
        ref_length=0;
1612
1683
        next_length_pack=0;
1613
1684
      }
 
1685
      DBUG_PRINT("test",("length: %d  next_key: 0x%lx", length,
 
1686
                         (long) next_key));
1614
1687
 
1615
1688
      {
1616
 
        uint32_t tmp_length;
 
1689
        uint tmp_length;
1617
1690
        key=(start+=ref_length);
1618
1691
        if (key+n_length < key_end)             /* Normalize length based */
1619
1692
          key_end=key+n_length;
1660
1733
/* Length of key which is prefix compressed */
1661
1734
 
1662
1735
int
1663
 
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *next_key,
1664
 
                             unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
 
1736
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
 
1737
                             uchar *org_key, uchar *prev_key, uchar *key,
1665
1738
                             MI_KEY_PARAM *s_temp)
1666
1739
{
1667
 
  uint32_t length,key_length,ref_length;
 
1740
  uint length,key_length,ref_length;
1668
1741
 
1669
1742
  s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
1670
1743
#ifdef HAVE_purify
1679
1752
      As keys may be identical when running a sort in myisamchk, we
1680
1753
      have to guard against the case where keys may be identical
1681
1754
    */
1682
 
    unsigned char *end;
 
1755
    uchar *end;
1683
1756
    end=key+key_length;
1684
1757
    for ( ; *key == *prev_key && key < end; key++,prev_key++) ;
1685
1758
    s_temp->ref_length= ref_length=(uint) (key-s_temp->key);
1694
1767
  if ((s_temp->next_key_pos=next_key))          /* If another key after */
1695
1768
  {
1696
1769
    /* pack key against next key */
1697
 
    uint32_t next_length,next_length_pack;
 
1770
    uint next_length,next_length_pack;
1698
1771
    get_key_pack_length(next_length,next_length_pack,next_key);
1699
1772
 
1700
1773
    /* If first key and next key is packed (only on delete) */
1701
1774
    if (!prev_key && org_key && next_length)
1702
1775
    {
1703
 
      unsigned char *end;
 
1776
      uchar *end;
1704
1777
      for (key= s_temp->key, end=key+next_length ;
1705
1778
           *key == *org_key && key < end;
1706
1779
           key++,org_key++) ;
1742
1815
/* store key without compression */
1743
1816
 
1744
1817
void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1745
 
                          register unsigned char *key_pos,
 
1818
                          register uchar *key_pos,
1746
1819
                          register MI_KEY_PARAM *s_temp)
1747
1820
{
1748
 
  memcpy(key_pos, s_temp->key, s_temp->totlength);
 
1821
  memcpy((uchar*) key_pos,(uchar*) s_temp->key,(size_t) s_temp->totlength);
1749
1822
}
1750
1823
 
1751
1824
 
1752
1825
/* store variable length key with prefix compression */
1753
1826
 
1754
1827
#define store_pack_length(test,pos,length) { \
1755
 
  if (test) { *((pos)++) = (unsigned char) (length); } else \
1756
 
  { *((pos)++) = (unsigned char) ((length) >> 8); *((pos)++) = (unsigned char) (length);  } }
 
1828
  if (test) { *((pos)++) = (uchar) (length); } else \
 
1829
  { *((pos)++) = (uchar) ((length) >> 8); *((pos)++) = (uchar) (length);  } }
1757
1830
 
1758
1831
 
1759
1832
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo  __attribute__((unused)),
1760
 
                            register unsigned char *key_pos,
 
1833
                            register uchar *key_pos,
1761
1834
                            register MI_KEY_PARAM *s_temp)
1762
1835
{
1763
 
  uint32_t length;
1764
 
  unsigned char *start;
 
1836
  uint length;
 
1837
  uchar *start;
1765
1838
 
1766
1839
  start=key_pos;
1767
1840
 
1778
1851
    /* Not packed against previous key */
1779
1852
    store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
1780
1853
  }
1781
 
  assert(key_pos >= start);
1782
 
  length= s_temp->totlength - (key_pos - start);
1783
 
  memcpy(key_pos, s_temp->key, length);
 
1854
  bmove((uchar*) key_pos,(uchar*) s_temp->key,
 
1855
        (length=s_temp->totlength-(uint) (key_pos-start)));
1784
1856
 
1785
1857
  if (!s_temp->next_key_pos)                    /* No following key */
1786
1858
    return;
1821
1893
/* variable length key with prefix compression */
1822
1894
 
1823
1895
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo  __attribute__((unused)),
1824
 
                            register unsigned char *key_pos,
 
1896
                            register uchar *key_pos,
1825
1897
                            register MI_KEY_PARAM *s_temp)
1826
1898
{
1827
 
  assert(s_temp->totlength >= s_temp->ref_length);
1828
1899
  store_key_length_inc(key_pos,s_temp->ref_length);
1829
 
  memcpy(key_pos,s_temp->key+s_temp->ref_length,
1830
 
         s_temp->totlength - s_temp->ref_length);
 
1900
  memcpy((char*) key_pos,(char*) s_temp->key+s_temp->ref_length,
 
1901
          (size_t) s_temp->totlength-s_temp->ref_length);
1831
1902
 
1832
1903
  if (s_temp->next_key_pos)
1833
1904
  {