31
31
static uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key);
32
32
static int hp_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec, const unsigned char *key);
35
Find out how many rows there is in the given range
38
hp_rb_records_in_range()
41
min_key Min key. Is = 0 if no min range
42
max_key Max key. Is = 0 if no max range
45
min_key.flag can have one of the following values:
46
HA_READ_KEY_EXACT Include the key in the range
47
HA_READ_AFTER_KEY Don't include key in range
49
max_key.flag can have one of the following values:
50
HA_READ_BEFORE_KEY Don't include key in range
51
HA_READ_AFTER_KEY Include all 'end_key' values in the range
54
HA_POS_ERROR Something is wrong with the index tree.
55
0 There is no matching keys in the given range
56
number > 0 There is approximately 'number' matching rows in
60
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key,
63
ha_rows start_pos, end_pos;
64
HP_KEYDEF *keyinfo= info->s->keydef + inx;
65
TREE *rb_tree = &keyinfo->rb_tree;
66
heap_rb_param custom_arg;
69
custom_arg.keyseg= keyinfo->seg;
70
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
73
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
74
(unsigned char*) min_key->key,
75
min_key->keypart_map);
76
start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag,
86
custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
87
(unsigned char*) max_key->key,
88
max_key->keypart_map);
89
end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag,
94
end_pos= rb_tree->elements_in_tree + (ha_rows)1;
97
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
99
return(end_pos < start_pos ? (ha_rows) 0 :
100
(end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos));
35
104
/* Search after a record based on a key */
36
105
/* Sets info->current_ptr to found record */
511
580
set_if_smaller(char_length,length); \
584
uint32_t hp_rb_make_key(HP_KEYDEF *keydef, unsigned char *key,
585
const unsigned char *rec, unsigned char *recpos)
587
unsigned char *start_key= key;
588
HA_KEYSEG *seg, *endseg;
590
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
592
uint32_t char_length;
595
if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
598
if (seg->flag & HA_SWAP_KEY)
600
uint32_t length= seg->length;
601
unsigned char *pos= (unsigned char*) rec + seg->start;
603
if (seg->type == HA_KEYTYPE_DOUBLE)
609
memset(key, 0, length);
622
if (seg->flag & HA_VAR_LENGTH_PART)
624
unsigned char *pos= (unsigned char*) rec + seg->start;
625
uint32_t length= seg->length;
626
uint32_t pack_length= seg->bit_start;
627
uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
629
const CHARSET_INFO * const cs= seg->charset;
630
char_length= length/cs->mbmaxlen;
632
pos+= pack_length; /* Skip VARCHAR length */
633
set_if_smaller(length,tmp_length);
634
FIX_LENGTH(cs, pos, length, char_length);
635
store_key_length_inc(key,char_length);
636
memcpy(key,pos,(size_t) char_length);
641
char_length= seg->length;
642
if (seg->charset->mbmaxlen > 1)
644
char_length= my_charpos(seg->charset,
645
rec + seg->start, rec + seg->start + char_length,
646
char_length / seg->charset->mbmaxlen);
647
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
648
if (char_length < seg->length)
649
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
650
seg->length - char_length, ' ');
652
memcpy(key, rec + seg->start, (size_t) char_length);
655
memcpy(key, &recpos, sizeof(unsigned char*));
656
return (uint32_t) (key - start_key);
660
uint32_t hp_rb_pack_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *old,
661
key_part_map keypart_map)
663
HA_KEYSEG *seg, *endseg;
664
unsigned char *start_key= key;
666
for (seg= keydef->seg, endseg= seg + keydef->keysegs;
667
seg < endseg && keypart_map; old+= seg->length, seg++)
669
uint32_t char_length;
673
if (!(*key++= (char) 1 - *old++))
676
if (seg->flag & HA_SWAP_KEY)
678
uint32_t length= seg->length;
679
unsigned char *pos= (unsigned char*) old + length;
687
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
689
/* Length of key-part used with heap_rkey() always 2 */
690
uint32_t tmp_length=uint2korr(old);
691
uint32_t length= seg->length;
692
const CHARSET_INFO * const cs= seg->charset;
693
char_length= length/cs->mbmaxlen;
696
set_if_smaller(length,tmp_length); /* Safety */
697
FIX_LENGTH(cs, old, length, char_length);
698
store_key_length_inc(key,char_length);
699
memcpy(key, old,(size_t) char_length);
703
char_length= seg->length;
704
if (seg->charset->mbmaxlen > 1)
706
char_length= my_charpos(seg->charset, old, old+char_length,
707
char_length / seg->charset->mbmaxlen);
708
set_if_smaller(char_length, (uint32_t)seg->length); /* QQ: ok to remove? */
709
if (char_length < seg->length)
710
seg->charset->cset->fill(seg->charset, (char*) key + char_length,
711
seg->length - char_length, ' ');
713
memcpy(key, old, (size_t) char_length);
716
return (uint) (key - start_key);
720
uint32_t hp_rb_key_length(HP_KEYDEF *keydef, const unsigned char *not_used)
723
return keydef->length;
727
uint32_t hp_rb_null_key_length(HP_KEYDEF *keydef, const unsigned char *key)
729
const unsigned char *start_key= key;
730
HA_KEYSEG *seg, *endseg;
732
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
734
if (seg->null_bit && !*key++)
738
return (uint) (key - start_key);
742
uint32_t hp_rb_var_key_length(HP_KEYDEF *keydef, const unsigned char *key)
744
const unsigned char *start_key= key;
745
HA_KEYSEG *seg, *endseg;
747
for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
749
uint32_t length= seg->length;
750
if (seg->null_bit && !*key++)
752
if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
754
get_key_length(length, key);
758
return (uint) (key - start_key);
515
763
Test if any of the key parts are NULL.