12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* key handling functions */
18
#include "myisam_priv.h"
19
#include "drizzled/charset_info.h"
20
#include "drizzled/internal/m_string.h"
21
#include <drizzled/util/test.h>
23
using namespace drizzled;
18
#include "myisamdef.h"
19
#include <mystrings/m_ctype.h>
25
21
static bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
26
22
unsigned char *key, unsigned char *keypos,
35
31
if (inx < 0 || ! mi_is_key_active(info->s->state.key_map, inx))
37
errno=HA_ERR_WRONG_INDEX;
33
my_errno=HA_ERR_WRONG_INDEX;
40
36
if (info->lastinx != inx) /* Index changed */
60
56
int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
61
unsigned char *key, uint32_t key_len, uint32_t nextflag, register internal::my_off_t pos)
57
unsigned char *key, uint32_t key_len, uint32_t nextflag, register my_off_t pos)
69
65
if (pos == HA_OFFSET_ERROR)
71
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
67
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
72
68
info->lastpos= HA_OFFSET_ERROR;
73
69
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
74
70
return(-1); /* Not found ; return error */
110
106
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
111
107
_mi_kpos(nod_flag,keypos))) >= 0 ||
112
errno != HA_ERR_KEY_NOT_FOUND)
108
my_errno != HA_ERR_KEY_NOT_FOUND)
114
110
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
134
130
ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
137
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
133
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
172
168
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
173
169
unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
174
unsigned char *buff, bool *last_key)
170
unsigned char *buff __attribute__((unused)), bool *last_key)
177
172
register int start,mid,end,save_end;
179
174
uint32_t totlength,nod_flag,not_used[2];
181
176
totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page));
234
229
unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
235
230
unsigned char *buff, bool *last_key)
238
233
uint32_t nod_flag,length=0,not_used[2];
239
234
unsigned char t_buff[MI_MAX_KEY_BUFF],*end;
249
244
if (length == 0 || page > end)
251
246
mi_print_error(info->s, HA_ERR_CRASHED);
252
errno=HA_ERR_CRASHED;
247
my_errno=HA_ERR_CRASHED;
253
248
return(MI_FOUND_WRONG_KEY);
255
250
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
552
return ((internal::my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
547
return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
554
return ((internal::my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
549
return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
556
return (internal::my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
551
return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
558
553
return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
559
554
case 0: /* At leaf page */
566
561
/* Save pos to a key_block */
568
void _mi_kpointer(register MI_INFO *info, register unsigned char *buff, internal::my_off_t pos)
563
void _mi_kpointer(register MI_INFO *info, register unsigned char *buff, my_off_t pos)
570
565
pos/=MI_MIN_KEY_BLOCK_LENGTH;
571
566
switch (info->s->base.key_reflength) {
593
588
/* Calc pos to a data-record from a key */
596
internal::my_off_t _mi_dpos(MI_INFO *info, uint32_t nod_flag, unsigned char *after_key)
591
my_off_t _mi_dpos(MI_INFO *info, uint32_t nod_flag, unsigned char *after_key)
598
internal::my_off_t pos;
599
594
after_key-=(nod_flag + info->s->rec_reflength);
600
595
switch (info->s->rec_reflength) {
601
596
#if SIZEOF_OFF_T > 4
602
case 8: pos= (internal::my_off_t) mi_uint8korr(after_key); break;
603
case 7: pos= (internal::my_off_t) mi_uint7korr(after_key); break;
604
case 6: pos= (internal::my_off_t) mi_uint6korr(after_key); break;
605
case 5: pos= (internal::my_off_t) mi_uint5korr(after_key); break;
597
case 8: pos= (my_off_t) mi_uint8korr(after_key); break;
598
case 7: pos= (my_off_t) mi_uint7korr(after_key); break;
599
case 6: pos= (my_off_t) mi_uint6korr(after_key); break;
600
case 5: pos= (my_off_t) mi_uint5korr(after_key); break;
607
case 8: pos= (internal::my_off_t) mi_uint4korr(after_key+4); break;
608
case 7: pos= (internal::my_off_t) mi_uint4korr(after_key+3); break;
609
case 6: pos= (internal::my_off_t) mi_uint4korr(after_key+2); break;
610
case 5: pos= (internal::my_off_t) mi_uint4korr(after_key+1); break;
602
case 8: pos= (my_off_t) mi_uint4korr(after_key+4); break;
603
case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
604
case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
605
case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
612
case 4: pos= (internal::my_off_t) mi_uint4korr(after_key); break;
613
case 3: pos= (internal::my_off_t) mi_uint3korr(after_key); break;
614
case 2: pos= (internal::my_off_t) mi_uint2korr(after_key); break;
607
case 4: pos= (my_off_t) mi_uint4korr(after_key); break;
608
case 3: pos= (my_off_t) mi_uint3korr(after_key); break;
609
case 2: pos= (my_off_t) mi_uint2korr(after_key); break;
616
611
pos=0L; /* Shut compiler up */
624
619
/* Calc position from a record pointer ( in delete link chain ) */
626
internal::my_off_t _mi_rec_pos(MYISAM_SHARE *s, unsigned char *ptr)
621
my_off_t _mi_rec_pos(MYISAM_SHARE *s, unsigned char *ptr)
628
internal::my_off_t pos;
629
624
switch (s->rec_reflength) {
630
625
#if SIZEOF_OFF_T > 4
632
pos= (internal::my_off_t) mi_uint8korr(ptr);
627
pos= (my_off_t) mi_uint8korr(ptr);
633
628
if (pos == HA_OFFSET_ERROR)
634
629
return HA_OFFSET_ERROR; /* end of list */
637
pos= (internal::my_off_t) mi_uint7korr(ptr);
638
if (pos == (((internal::my_off_t) 1) << 56) -1)
632
pos= (my_off_t) mi_uint7korr(ptr);
633
if (pos == (((my_off_t) 1) << 56) -1)
639
634
return HA_OFFSET_ERROR; /* end of list */
642
pos= (internal::my_off_t) mi_uint6korr(ptr);
643
if (pos == (((internal::my_off_t) 1) << 48) -1)
637
pos= (my_off_t) mi_uint6korr(ptr);
638
if (pos == (((my_off_t) 1) << 48) -1)
644
639
return HA_OFFSET_ERROR; /* end of list */
647
pos= (internal::my_off_t) mi_uint5korr(ptr);
648
if (pos == (((internal::my_off_t) 1) << 40) -1)
642
pos= (my_off_t) mi_uint5korr(ptr);
643
if (pos == (((my_off_t) 1) << 40) -1)
649
644
return HA_OFFSET_ERROR; /* end of list */
657
652
/* fall through */
660
pos= (internal::my_off_t) mi_uint4korr(ptr);
661
if (pos == (internal::my_off_t) UINT32_MAX)
655
pos= (my_off_t) mi_uint4korr(ptr);
656
if (pos == (my_off_t) UINT32_MAX)
662
657
return HA_OFFSET_ERROR;
665
pos= (internal::my_off_t) mi_uint3korr(ptr);
666
if (pos == (internal::my_off_t) (1 << 24) -1)
660
pos= (my_off_t) mi_uint3korr(ptr);
661
if (pos == (my_off_t) (1 << 24) -1)
667
662
return HA_OFFSET_ERROR;
670
pos= (internal::my_off_t) mi_uint2korr(ptr);
671
if (pos == (internal::my_off_t) (1 << 16) -1)
665
pos= (my_off_t) mi_uint2korr(ptr);
666
if (pos == (my_off_t) (1 << 16) -1)
672
667
return HA_OFFSET_ERROR;
674
669
default: abort(); /* Impossible */
682
677
/* save position to record */
684
void _mi_dpointer(MI_INFO *info, unsigned char *buff, internal::my_off_t pos)
679
void _mi_dpointer(MI_INFO *info, unsigned char *buff, my_off_t pos)
686
681
if (!(info->s->options &
687
682
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
801
796
if (tot_length >= 255 && *start != 255)
803
798
/* length prefix changed from a length of one to a length of 3 */
804
internal::bmove_upp(key+length+3, key+length+1, length);
799
bmove_upp(key+length+3, key+length+1, length);
806
801
mi_int2store(key+1,tot_length);
809
804
else if (tot_length < 255 && *start == 255)
811
memmove(key+1,key+3,length);
806
memcpy(key+1,key+3,length);
904
899
if (length > keyinfo->maxlength)
906
901
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
907
errno=HA_ERR_CRASHED;
902
my_errno=HA_ERR_CRASHED;
908
903
return(0); /* Wrong key */
910
905
/* Key is packed against prev key, take prefix from prev key. */
985
980
if (from_end != page_end)
987
982
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
988
errno=HA_ERR_CRASHED;
983
my_errno=HA_ERR_CRASHED;
989
984
return(0); /* Error */
991
986
/* Copy data pointer and, if appropriate, key block pointer. */
1007
1002
nod_flag=mi_test_if_nod(page);
1008
1003
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1010
memmove(key,keypos,keyinfo->keylength+nod_flag);
1005
memcpy(key,keypos,keyinfo->keylength+nod_flag);
1011
1006
return(keypos+keyinfo->keylength+nod_flag);
1042
1037
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1044
1039
*return_key_length=keyinfo->keylength;
1045
memmove(key, keypos - *return_key_length-nod_flag, *return_key_length);
1040
memcpy(key, keypos - *return_key_length-nod_flag, *return_key_length);
1080
1075
lastpos=endpos-keyinfo->keylength-nod_flag;
1081
1076
*return_key_length=keyinfo->keylength;
1082
1077
if (lastpos > page)
1083
memmove(lastkey,lastpos,keyinfo->keylength+nod_flag);
1078
memcpy(lastkey,lastpos,keyinfo->keylength+nod_flag);
1176
1171
/* This can't be used when database is touched after last read */
1178
1173
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1179
unsigned char *key, uint32_t key_length, uint32_t nextflag, internal::my_off_t pos)
1174
unsigned char *key, uint32_t key_length, uint32_t nextflag, my_off_t pos)
1182
1177
uint32_t nod_flag;
1210
1205
if (nextflag & SEARCH_BIGGER) /* Next key */
1212
internal::my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1207
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1213
1208
if (tmp_pos != HA_OFFSET_ERROR)
1215
1210
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1252
1247
/* This is stored in info->lastpos */
1254
1249
int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1255
register internal::my_off_t pos)
1250
register my_off_t pos)
1257
1252
uint32_t nod_flag;
1258
1253
unsigned char *page;
1260
1255
if (pos == HA_OFFSET_ERROR)
1262
errno=HA_ERR_KEY_NOT_FOUND;
1257
my_errno=HA_ERR_KEY_NOT_FOUND;
1263
1258
info->lastpos= HA_OFFSET_ERROR;
1294
1289
/* This is stored in info->lastpos */
1296
1291
int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1297
register internal::my_off_t pos)
1292
register my_off_t pos)
1299
1294
uint32_t nod_flag;
1300
1295
unsigned char *buff,*page;
1302
1297
if (pos == HA_OFFSET_ERROR)
1304
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
1299
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
1305
1300
info->lastpos= HA_OFFSET_ERROR;
1352
1347
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1353
unsigned char *next_pos,
1354
unsigned char *org_key,
1355
unsigned char *prev_key,
1348
unsigned char *next_pos __attribute__((unused)),
1349
unsigned char *org_key __attribute__((unused)),
1350
unsigned char *prev_key __attribute__((unused)),
1356
1351
unsigned char *key, MI_KEY_PARAM *s_temp)
1361
1353
s_temp->key=key;
1362
1354
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
1368
1360
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1369
unsigned char *next_pos,
1370
unsigned char *org_key,
1371
unsigned char *prev_key,
1361
unsigned char *next_pos __attribute__((unused)),
1362
unsigned char *org_key __attribute__((unused)),
1363
unsigned char *prev_key __attribute__((unused)),
1372
1364
unsigned char *key, MI_KEY_PARAM *s_temp)
1377
1366
s_temp->key=key;
1378
1367
return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
1401
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1402
unsigned char *next_key,
1403
unsigned char *org_key,
1404
unsigned char *prev_key,
1390
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *next_key,
1391
unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
1406
1392
MI_KEY_PARAM *s_temp)
1408
1394
register HA_KEYSEG *keyseg;
1680
1666
uint32_t length,key_length,ref_length;
1682
1668
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
1683
#ifdef HAVE_VALGRIND
1684
1670
s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */
1686
1672
s_temp->key=key;
1755
1741
/* store key without compression */
1757
void _mi_store_static_key(MI_KEYDEF *keyinfo,
1743
void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1758
1744
register unsigned char *key_pos,
1759
1745
register MI_KEY_PARAM *s_temp)
1762
1747
memcpy(key_pos, s_temp->key, s_temp->totlength);
1770
1755
{ *((pos)++) = (unsigned char) ((length) >> 8); *((pos)++) = (unsigned char) (length); } }
1773
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo,
1758
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1774
1759
register unsigned char *key_pos,
1775
1760
register MI_KEY_PARAM *s_temp)
1778
1762
uint32_t length;
1779
1763
unsigned char *start;
1796
1780
assert(key_pos >= start);
1797
1781
length= s_temp->totlength - (key_pos - start);
1798
memmove(key_pos, s_temp->key, length);
1782
memcpy(key_pos, s_temp->key, length);
1800
1784
if (!s_temp->next_key_pos) /* No following key */
1836
1820
/* variable length key with prefix compression */
1838
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo,
1822
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1839
1823
register unsigned char *key_pos,
1840
1824
register MI_KEY_PARAM *s_temp)
1843
1826
assert(s_temp->totlength >= s_temp->ref_length);
1844
1827
store_key_length_inc(key_pos,s_temp->ref_length);
1845
1828
memcpy(key_pos,s_temp->key+s_temp->ref_length,