59
59
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
62
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
63
(unsigned char*) min_key->key,
62
custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
63
(uchar*) min_key->key,
64
64
min_key->keypart_map);
65
65
start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag,
75
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
76
(unsigned char*) max_key->key,
75
custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
76
(uchar*) max_key->key,
77
77
max_key->keypart_map);
78
78
end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag,
94
94
/* Sets info->current_ptr to found record */
95
95
/* next_flag: Search=0, next=1, prev =2, same =3 */
97
unsigned char *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *key,
97
uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
100
100
register HASH_INFO *pos,*prev_ptr;
102
uint32_t old_nextflag;
103
103
HP_SHARE *share=info->s;
104
104
old_nextflag=nextflag;
169
169
since last read !
172
unsigned char *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *key,
172
uchar *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
175
175
while ((pos= pos->next_key))
199
199
Array index, in [0..maxlength)
202
uint32_t hp_mask(uint32_t hashnr, uint32_t buffmax, uint32_t maxlength)
202
ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
204
204
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
205
205
return (hashnr & ((buffmax >> 1) -1));
230
230
/* Calc hashvalue for a key */
232
uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key)
232
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
235
uint32_t nr=1, nr2=4;
236
236
HA_KEYSEG *seg,*endseg;
238
238
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
240
unsigned char *pos=(unsigned char*) key;
240
uchar *pos=(uchar*) key;
241
241
key+=seg->length;
242
242
if (seg->null_bit)
255
255
if (seg->type == HA_KEYTYPE_TEXT)
257
const CHARSET_INFO * const cs= seg->charset;
258
uint32_t length= seg->length;
257
CHARSET_INFO *cs= seg->charset;
258
uint length= seg->length;
259
259
if (cs->mbmaxlen > 1)
261
uint32_t char_length;
262
262
char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
263
263
set_if_smaller(length, char_length);
267
267
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
269
const CHARSET_INFO * const cs= seg->charset;
270
uint32_t pack_length= 2; /* Key packing is constant */
271
uint32_t length= uint2korr(pos);
269
CHARSET_INFO *cs= seg->charset;
270
uint pack_length= 2; /* Key packing is constant */
271
uint length= uint2korr(pos);
272
272
if (cs->mbmaxlen > 1)
274
uint32_t char_length;
275
275
char_length= my_charpos(cs, pos +pack_length,
276
276
pos +pack_length + length,
277
277
seg->length/cs->mbmaxlen);
285
for (; pos < (unsigned char*) key ; pos++)
285
for (; pos < (uchar*) key ; pos++)
287
nr^=(uint32_t) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
287
nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
292
return((uint32_t) nr);
295
295
/* Calc hashvalue for a key in a record */
297
uint32_t hp_rec_hashnr(register HP_KEYDEF *keydef, register const unsigned char *rec)
297
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
299
uint32_t nr=1, nr2=4;
300
300
HA_KEYSEG *seg,*endseg;
302
302
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
304
unsigned char *pos=(unsigned char*) rec+seg->start,*end=pos+seg->length;
304
uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
305
305
if (seg->null_bit)
307
307
if (rec[seg->null_pos] & seg->null_bit)
313
313
if (seg->type == HA_KEYTYPE_TEXT)
315
const CHARSET_INFO * const cs= seg->charset;
316
uint32_t char_length= seg->length;
315
CHARSET_INFO *cs= seg->charset;
316
uint char_length= seg->length;
317
317
if (cs->mbmaxlen > 1)
319
319
char_length= my_charpos(cs, pos, pos + char_length,
325
325
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
327
const CHARSET_INFO * const cs= seg->charset;
328
uint32_t pack_length= seg->bit_start;
329
uint32_t length= (pack_length == 1 ? (uint) *(unsigned char*) pos : uint2korr(pos));
327
CHARSET_INFO *cs= seg->charset;
328
uint pack_length= seg->bit_start;
329
uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
330
330
if (cs->mbmaxlen > 1)
332
uint32_t char_length;
333
333
char_length= my_charpos(cs, pos + pack_length,
334
334
pos + pack_length + length,
335
335
seg->length/cs->mbmaxlen);
366
366
* far, and works well on both numbers and strings.
369
uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key)
369
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
372
372
Note, if a key consists of a combination of numeric and
374
374
Making text columns work with NEW_HASH_FUNCTION
375
375
needs also changes in strings/ctype-xxx.c.
377
uint32_t nr= 1, nr2= 4;
378
378
HA_KEYSEG *seg,*endseg;
380
380
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
382
unsigned char *pos=(unsigned char*) key;
382
uchar *pos=(uchar*) key;
383
383
key+=seg->length;
384
384
if (seg->null_bit)
397
397
if (seg->type == HA_KEYTYPE_TEXT)
399
seg->charset->coll->hash_sort(seg->charset, pos, ((unsigned char*)key)-pos,
399
seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos,
402
402
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
404
uint32_t pack_length= 2; /* Key packing is constant */
405
uint32_t length= uint2korr(pos);
404
uint pack_length= 2; /* Key packing is constant */
405
uint length= uint2korr(pos);
406
406
seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
408
408
key+= pack_length;
412
for ( ; pos < (unsigned char*) key ; pos++)
412
for ( ; pos < (uchar*) key ; pos++)
415
415
nr ^=(uint) *pos;
422
422
/* Calc hashvalue for a key in a record */
424
uint32_t hp_rec_hashnr(register HP_KEYDEF *keydef, register const unsigned char *rec)
424
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
426
uint32_t nr= 1, nr2= 4;
427
427
HA_KEYSEG *seg,*endseg;
429
429
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
431
unsigned char *pos=(unsigned char*) rec+seg->start;
431
uchar *pos=(uchar*) rec+seg->start;
432
432
if (seg->null_bit)
434
434
if (rec[seg->null_pos] & seg->null_bit)
440
440
if (seg->type == HA_KEYTYPE_TEXT)
442
uint32_t char_length= seg->length; /* TODO: fix to use my_charpos() */
442
uint char_length= seg->length; /* TODO: fix to use my_charpos() */
443
443
seg->charset->coll->hash_sort(seg->charset, pos, char_length,
446
446
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
448
uint32_t pack_length= seg->bit_start;
449
uint32_t length= (pack_length == 1 ? (uint) *(unsigned char*) pos : uint2korr(pos));
448
uint pack_length= seg->bit_start;
449
uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
450
450
seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
451
451
length, &nr, &nr2);
455
unsigned char *end= pos+seg->length;
455
uchar *end= pos+seg->length;
456
456
for ( ; pos < end ; pos++)
486
486
<> 0 Key differes
489
int hp_rec_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec1, const unsigned char *rec2,
490
bool diff_if_only_endspace_difference)
489
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
490
my_bool diff_if_only_endspace_difference)
492
492
HA_KEYSEG *seg,*endseg;
504
504
if (seg->type == HA_KEYTYPE_TEXT)
506
const CHARSET_INFO * const cs= seg->charset;
507
uint32_t char_length1;
508
uint32_t char_length2;
509
unsigned char *pos1= (unsigned char*)rec1 + seg->start;
510
unsigned char *pos2= (unsigned char*)rec2 + seg->start;
506
CHARSET_INFO *cs= seg->charset;
509
uchar *pos1= (uchar*)rec1 + seg->start;
510
uchar *pos2= (uchar*)rec2 + seg->start;
511
511
if (cs->mbmaxlen > 1)
513
uint32_t char_length= seg->length / cs->mbmaxlen;
513
uint char_length= seg->length / cs->mbmaxlen;
514
514
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
515
515
set_if_smaller(char_length1, seg->length);
516
516
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
528
528
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
530
unsigned char *pos1= (unsigned char*) rec1 + seg->start;
531
unsigned char *pos2= (unsigned char*) rec2 + seg->start;
532
uint32_t char_length1, char_length2;
533
uint32_t pack_length= seg->bit_start;
534
const CHARSET_INFO * const cs= seg->charset;
530
uchar *pos1= (uchar*) rec1 + seg->start;
531
uchar *pos2= (uchar*) rec2 + seg->start;
532
uint char_length1, char_length2;
533
uint pack_length= seg->bit_start;
534
CHARSET_INFO *cs= seg->charset;
535
535
if (pack_length == 1)
537
char_length1= (uint) *(unsigned char*) pos1++;
538
char_length2= (uint) *(unsigned char*) pos2++;
537
char_length1= (uint) *(uchar*) pos1++;
538
char_length2= (uint) *(uchar*) pos2++;
547
547
if (cs->mbmaxlen > 1)
549
uint32_t safe_length1= char_length1;
550
uint32_t safe_length2= char_length2;
551
uint32_t char_length= seg->length / cs->mbmaxlen;
549
uint safe_length1= char_length1;
550
uint safe_length2= char_length2;
551
uint char_length= seg->length / cs->mbmaxlen;
552
552
char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
553
553
set_if_smaller(char_length1, safe_length1);
554
554
char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
574
574
/* Compare a key in a record to a whole key */
576
int hp_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec, const unsigned char *key)
576
int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
578
578
HA_KEYSEG *seg,*endseg;
597
597
if (seg->type == HA_KEYTYPE_TEXT)
599
const CHARSET_INFO * const cs= seg->charset;
600
uint32_t char_length_key;
601
uint32_t char_length_rec;
602
unsigned char *pos= (unsigned char*) rec + seg->start;
599
CHARSET_INFO *cs= seg->charset;
600
uint char_length_key;
601
uint char_length_rec;
602
uchar *pos= (uchar*) rec + seg->start;
603
603
if (cs->mbmaxlen > 1)
605
uint32_t char_length= seg->length / cs->mbmaxlen;
605
uint char_length= seg->length / cs->mbmaxlen;
606
606
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
607
607
set_if_smaller(char_length_key, seg->length);
608
608
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
617
617
if (seg->charset->coll->strnncollsp(seg->charset,
618
(unsigned char*) pos, char_length_rec,
619
(unsigned char*) key, char_length_key, 0))
618
(uchar*) pos, char_length_rec,
619
(uchar*) key, char_length_key, 0))
622
622
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
624
unsigned char *pos= (unsigned char*) rec + seg->start;
625
const CHARSET_INFO * const cs= seg->charset;
626
uint32_t pack_length= seg->bit_start;
627
uint32_t char_length_rec= (pack_length == 1 ? (uint) *(unsigned char*) pos :
624
uchar *pos= (uchar*) rec + seg->start;
625
CHARSET_INFO *cs= seg->charset;
626
uint pack_length= seg->bit_start;
627
uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos :
629
629
/* Key segments are always packed with 2 bytes */
630
uint32_t char_length_key= uint2korr(key);
630
uint char_length_key= uint2korr(key);
631
631
pos+= pack_length;
632
632
key+= 2; /* skip key pack length */
633
633
if (cs->mbmaxlen > 1)
635
uint32_t char_length1, char_length2;
635
uint char_length1, char_length2;
636
636
char_length1= char_length2= seg->length / cs->mbmaxlen;
637
637
char_length1= my_charpos(cs, key, key + char_length_key, char_length1);
638
638
set_if_smaller(char_length_key, char_length1);
643
643
if (cs->coll->strnncollsp(seg->charset,
644
(unsigned char*) pos, char_length_rec,
645
(unsigned char*) key, char_length_key, 0))
644
(uchar*) pos, char_length_rec,
645
(uchar*) key, char_length_key, 0))
650
if (memcmp(rec+seg->start,key,seg->length))
650
if (bcmp(rec+seg->start,key,seg->length))
658
658
/* Copy a key from a record to a keybuffer */
660
void hp_make_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *rec)
660
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
662
662
HA_KEYSEG *seg,*endseg;
664
664
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
666
const CHARSET_INFO * const cs= seg->charset;
667
uint32_t char_length= seg->length;
668
unsigned char *pos= (unsigned char*) rec + seg->start;
666
CHARSET_INFO *cs= seg->charset;
667
uint char_length= seg->length;
668
uchar *pos= (uchar*) rec + seg->start;
669
669
if (seg->null_bit)
670
670
*key++= test(rec[seg->null_pos] & seg->null_bit);
671
671
if (cs->mbmaxlen > 1)
692
uint32_t hp_rb_make_key(HP_KEYDEF *keydef, unsigned char *key,
693
const unsigned char *rec, unsigned char *recpos)
692
uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key,
693
const uchar *rec, uchar *recpos)
695
unsigned char *start_key= key;
695
uchar *start_key= key;
696
696
HA_KEYSEG *seg, *endseg;
698
698
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
700
uint32_t char_length;
701
701
if (seg->null_bit)
703
703
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
706
706
if (seg->flag & HA_SWAP_KEY)
708
uint32_t length= seg->length;
709
unsigned char *pos= (unsigned char*) rec + seg->start;
708
uint length= seg->length;
709
uchar *pos= (uchar*) rec + seg->start;
711
711
#ifdef HAVE_ISNAN
712
712
if (seg->type == HA_KEYTYPE_FLOAT)
744
744
if (seg->flag & HA_VAR_LENGTH_PART)
746
unsigned char *pos= (unsigned char*) rec + seg->start;
747
uint32_t length= seg->length;
748
uint32_t pack_length= seg->bit_start;
749
uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
746
uchar *pos= (uchar*) rec + seg->start;
747
uint length= seg->length;
748
uint pack_length= seg->bit_start;
749
uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
751
const CHARSET_INFO * const cs= seg->charset;
751
CHARSET_INFO *cs= seg->charset;
752
752
char_length= length/cs->mbmaxlen;
754
754
pos+= pack_length; /* Skip VARCHAR length */
755
755
set_if_smaller(length,tmp_length);
756
756
FIX_LENGTH(cs, pos, length, char_length);
757
757
store_key_length_inc(key,char_length);
758
memcpy(key,pos,(size_t) char_length);
758
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
759
759
key+= char_length;
774
774
memcpy(key, rec + seg->start, (size_t) char_length);
775
775
key+= seg->length;
777
memcpy(key, &recpos, sizeof(unsigned char*));
777
memcpy(key, &recpos, sizeof(uchar*));
778
778
return (uint) (key - start_key);
782
uint32_t hp_rb_pack_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *old,
782
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
783
783
key_part_map keypart_map)
785
785
HA_KEYSEG *seg, *endseg;
786
unsigned char *start_key= key;
786
uchar *start_key= key;
788
788
for (seg= keydef->seg, endseg= seg + keydef->keysegs;
789
789
seg < endseg && keypart_map; old+= seg->length, seg++)
791
uint32_t char_length;
792
792
keypart_map>>= 1;
793
793
if (seg->null_bit)
798
798
if (seg->flag & HA_SWAP_KEY)
800
uint32_t length= seg->length;
801
unsigned char *pos= (unsigned char*) old + length;
800
uint length= seg->length;
801
uchar *pos= (uchar*) old + length;
809
809
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
811
811
/* Length of key-part used with heap_rkey() always 2 */
812
uint32_t tmp_length=uint2korr(old);
813
uint32_t length= seg->length;
814
const CHARSET_INFO * const cs= seg->charset;
812
uint tmp_length=uint2korr(old);
813
uint length= seg->length;
814
CHARSET_INFO *cs= seg->charset;
815
815
char_length= length/cs->mbmaxlen;
818
818
set_if_smaller(length,tmp_length); /* Safety */
819
819
FIX_LENGTH(cs, old, length, char_length);
820
820
store_key_length_inc(key,char_length);
821
memcpy(key, old,(size_t) char_length);
821
memcpy((uchar*) key, old,(size_t) char_length);
822
822
key+= char_length;
842
uint32_t hp_rb_key_length(HP_KEYDEF *keydef,
843
const unsigned char *key __attribute__((unused)))
842
uint hp_rb_key_length(HP_KEYDEF *keydef,
843
const uchar *key __attribute__((unused)))
845
845
return keydef->length;
849
uint32_t hp_rb_null_key_length(HP_KEYDEF *keydef, const unsigned char *key)
849
uint hp_rb_null_key_length(HP_KEYDEF *keydef, const uchar *key)
851
const unsigned char *start_key= key;
851
const uchar *start_key= key;
852
852
HA_KEYSEG *seg, *endseg;
854
854
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
864
uint32_t hp_rb_var_key_length(HP_KEYDEF *keydef, const unsigned char *key)
864
uint hp_rb_var_key_length(HP_KEYDEF *keydef, const uchar *key)
866
const unsigned char *start_key= key;
866
const uchar *start_key= key;
867
867
HA_KEYSEG *seg, *endseg;
869
869
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
871
uint32_t length= seg->length;
871
uint length= seg->length;
872
872
if (seg->null_bit && !*key++)
874
874
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
891
bool hp_if_null_in_key(HP_KEYDEF *keydef, const unsigned char *record)
891
my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const uchar *record)
893
893
HA_KEYSEG *seg,*endseg;
894
894
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
917
void heap_update_auto_increment(HP_INFO *info, const unsigned char *record)
917
void heap_update_auto_increment(HP_INFO *info, const uchar *record)
919
919
uint64_t value= 0; /* Store unsigned values here */
920
920
int64_t s_value= 0; /* Store signed values here */
922
922
HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
923
const unsigned char *key= (unsigned char*) record + keyseg->start;
923
const uchar *key= (uchar*) record + keyseg->start;
925
925
switch (info->s->auto_key_type) {
926
926
case HA_KEYTYPE_INT8:
927
927
s_value= (int64_t) *(char*)key;
929
929
case HA_KEYTYPE_BINARY:
930
value=(uint64_t) *(unsigned char*) key;
930
value=(uint64_t) *(uchar*) key;
932
932
case HA_KEYTYPE_SHORT_INT:
933
933
s_value= (int64_t) sint2korr(key);