30
31
set_if_smaller(char_length,length); \
33
static int _mi_put_key_in_record(MI_INFO *info,uint32_t keynr,unsigned char *record);
34
static int _mi_put_key_in_record(MI_INFO *info,uint keynr,uchar *record);
36
37
Make a intern key from a record
50
uint32_t _mi_make_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
51
const unsigned char *record, my_off_t filepos)
51
uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
52
const uchar *record, my_off_t filepos)
55
56
register HA_KEYSEG *keyseg;
57
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
58
DBUG_ENTER("_mi_make_key");
60
if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
63
TODO: nulls processing
66
DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos));
68
DBUG_ASSERT(0); /* mi_open should check that this never happens*/
58
73
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
60
75
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
61
uint32_t length=keyseg->length;
63
const CHARSET_INFO * const cs=keyseg->charset;
76
uint length=keyseg->length;
78
CHARSET_INFO *cs=keyseg->charset;
65
80
if (keyseg->null_bit)
72
87
*key++=1; /* Not NULL */
75
char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
90
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
78
pos= (unsigned char*) record+keyseg->start;
93
pos= (uchar*) record+keyseg->start;
79
94
if (type == HA_KEYTYPE_BIT)
81
96
if (keyseg->bit_length)
83
unsigned char bits= get_rec_bits((unsigned char*) record + keyseg->bit_pos,
98
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
99
keyseg->bit_start, keyseg->bit_length);
88
memcpy(key, pos, length);
103
memcpy((uchar*) key, pos, length);
100
unsigned char *end= pos + length;
115
uchar *end= pos + length;
101
116
while (pos < end && pos[0] == ' ')
103
118
length=(uint) (end-pos);
105
120
FIX_LENGTH(cs, pos, length, char_length);
106
121
store_key_length_inc(key,char_length);
107
memcpy(key, pos, char_length);
122
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
108
123
key+=char_length;
111
126
if (keyseg->flag & HA_VAR_LENGTH_PART)
113
uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
128
uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
129
uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
116
131
pos+= pack_length; /* Skip VARCHAR length */
117
132
set_if_smaller(length,tmp_length);
118
133
FIX_LENGTH(cs, pos, length, char_length);
119
134
store_key_length_inc(key,char_length);
120
memcpy(key, pos, char_length);
135
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
121
136
key+= char_length;
124
139
else if (keyseg->flag & HA_BLOB_PART)
126
uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
127
memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
141
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
142
memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
128
143
set_if_smaller(length,tmp_length);
129
144
FIX_LENGTH(cs, pos, length, char_length);
130
145
store_key_length_inc(key,char_length);
131
memcpy(key, pos, char_length);
146
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
132
147
key+= char_length;
169
184
FIX_LENGTH(cs, pos, length, char_length);
170
memcpy(key, pos, char_length);
185
memcpy((uchar*) key, pos, char_length);
171
186
if (length > char_length)
172
187
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
175
190
_mi_dpointer(info,key,filepos);
176
return((uint) (key-start)); /* Return keylength */
191
DBUG_PRINT("exit",("keynr: %d",keynr));
192
DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length);
194
_mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
195
(uint) (key-start)););
196
DBUG_RETURN((uint) (key-start)); /* Return keylength */
177
197
} /* _mi_make_key */
195
215
last_use_keyseg Store pointer to the keyseg after the last used one
198
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
218
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
199
219
key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
201
unsigned char *start_key=key;
221
uchar *start_key=key;
202
222
HA_KEYSEG *keyseg;
223
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
224
DBUG_ENTER("_mi_pack_key");
226
/* "one part" rtree key is 2*SPDIMS part key in MyISAM */
227
if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
228
keypart_map= (((key_part_map)1) << (2*SPDIMS)) - 1;
204
230
/* only key prefixes are supported */
205
assert(((keypart_map+1) & keypart_map) == 0);
231
DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
207
233
for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
208
234
old+= keyseg->length, keyseg++)
210
236
enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
211
uint32_t length= keyseg->length;
212
uint32_t char_length;
214
const CHARSET_INFO * const cs=keyseg->charset;
237
uint length= keyseg->length;
240
CHARSET_INFO *cs=keyseg->charset;
215
241
keypart_map>>= 1;
216
242
if (keyseg->null_bit)
222
248
continue; /* Found NULL */
225
char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
251
char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
227
253
if (keyseg->flag & HA_SPACE_PACK)
229
unsigned char *end=pos+length;
255
uchar *end=pos+length;
230
256
if (type == HA_KEYTYPE_NUM)
232
258
while (pos < end && pos[0] == ' ')
240
266
length=(uint) (end-pos);
241
267
FIX_LENGTH(cs, pos, length, char_length);
242
268
store_key_length_inc(key,char_length);
243
memcpy(key, pos, char_length);
269
memcpy((uchar*) key,pos,(size_t) char_length);
244
270
key+= char_length;
247
273
else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
249
275
/* Length of key-part used with mi_rkey() always 2 */
250
uint32_t tmp_length=uint2korr(pos);
276
uint tmp_length=uint2korr(pos);
252
278
set_if_smaller(length,tmp_length); /* Safety */
253
279
FIX_LENGTH(cs, pos, length, char_length);
254
280
store_key_length_inc(key,char_length);
255
281
old+=2; /* Skip length */
256
memcpy(key, pos, char_length);
282
memcpy((uchar*) key, pos,(size_t) char_length);
257
283
key+= char_length;
267
293
FIX_LENGTH(cs, pos, length, char_length);
268
memcpy(key, pos, char_length);
294
memcpy((uchar*) key, pos, char_length);
269
295
if (length > char_length)
270
296
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
300
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
301
unsigned char *record)
326
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
303
register unsigned char *key;
304
unsigned char *pos,*key_end;
305
331
register HA_KEYSEG *keyseg;
306
unsigned char *blob_ptr;
333
DBUG_ENTER("_mi_put_key_in_record");
308
blob_ptr= (unsigned char*) info->lastkey2; /* Place to put blob parts */
309
key=(unsigned char*) info->lastkey; /* KEy that was read */
335
blob_ptr= (uchar*) info->lastkey2; /* Place to put blob parts */
336
key=(uchar*) info->lastkey; /* KEy that was read */
310
337
key_end=key+info->lastkey_length;
311
338
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
322
349
if (keyseg->type == HA_KEYTYPE_BIT)
324
uint32_t length= keyseg->length;
351
uint length= keyseg->length;
326
353
if (keyseg->bit_length)
328
unsigned char bits= *key++;
329
356
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
330
357
keyseg->bit_length);
335
362
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
336
363
keyseg->bit_length);
338
memcpy(record + keyseg->start, key, length);
365
memcpy(record + keyseg->start, (uchar*) key, length);
342
369
if (keyseg->flag & HA_SPACE_PACK)
345
372
get_key_length(length,key);
346
373
#ifdef CHECK_KEYS
347
374
if (length > keyseg->length || key+length > key_end)
350
377
pos= record+keyseg->start;
351
378
if (keyseg->type != (int) HA_KEYTYPE_NUM)
353
memcpy(pos, key, length);
380
memcpy(pos,key,(size_t) length);
354
381
keyseg->charset->cset->fill(keyseg->charset,
355
382
(char*) pos + length,
356
383
keyseg->length - length,
361
memset(pos, ' ', keyseg->length-length);
362
memcpy(pos+keyseg->length-length, key, length);
388
bfill(pos,keyseg->length-length,' ');
389
memcpy(pos+keyseg->length-length,key,(size_t) length);
376
403
/* Store key length */
377
404
if (keyseg->bit_start == 1)
378
*(unsigned char*) (record+keyseg->start)= (unsigned char) length;
405
*(uchar*) (record+keyseg->start)= (uchar) length;
380
407
int2store(record+keyseg->start, length);
381
408
/* And key data */
382
memcpy(record+keyseg->start + keyseg->bit_start, key, length);
409
memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
385
412
else if (keyseg->flag & HA_BLOB_PART)
388
415
get_key_length(length,key);
389
416
#ifdef CHECK_KEYS
390
417
if (length > keyseg->length || key+length > key_end)
393
420
memcpy(record+keyseg->start+keyseg->bit_start,
394
&blob_ptr,sizeof(char*));
421
(char*) &blob_ptr,sizeof(char*));
395
422
memcpy(blob_ptr,key,length);
396
423
blob_ptr+=length;
422
449
if (key+keyseg->length > key_end)
425
memcpy(record+keyseg->start, key, keyseg->length);
452
memcpy(record+keyseg->start,(uchar*) key,
453
(size_t) keyseg->length);
426
454
key+= keyseg->length;
432
return(1); /* Crashed row */
460
DBUG_RETURN(1); /* Crashed row */
433
461
} /* _mi_put_key_in_record */
436
464
/* Here when key reads are used */
438
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
466
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
440
468
fast_mi_writeinfo(info);
441
469
if (filepos != HA_OFFSET_ERROR)
474
502
2 Index condition is not satisfied, end the scan.
477
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
505
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
479
507
if (_mi_put_key_in_record(info, keynr, record))
502
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
530
ulonglong retrieve_auto_increment(MI_INFO *info,const uchar *record)
504
uint64_t value= 0; /* Store unsigned values here */
505
int64_t s_value= 0; /* Store signed values here */
532
ulonglong value= 0; /* Store unsigned values here */
533
longlong s_value= 0; /* Store signed values here */
506
534
HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
507
const unsigned char *key= (unsigned char*) record + keyseg->start;
535
const uchar *key= (uchar*) record + keyseg->start;
509
537
switch (keyseg->type) {
510
538
case HA_KEYTYPE_INT8:
511
s_value= (int64_t) *(char*)key;
539
s_value= (longlong) *(char*)key;
513
541
case HA_KEYTYPE_BINARY:
514
value=(uint64_t) *(unsigned char*) key;
542
value=(ulonglong) *(uchar*) key;
516
544
case HA_KEYTYPE_SHORT_INT:
517
s_value= (int64_t) sint2korr(key);
545
s_value= (longlong) sint2korr(key);
519
547
case HA_KEYTYPE_USHORT_INT:
520
value=(uint64_t) uint2korr(key);
548
value=(ulonglong) uint2korr(key);
522
550
case HA_KEYTYPE_LONG_INT:
523
s_value= (int64_t) sint4korr(key);
551
s_value= (longlong) sint4korr(key);
525
553
case HA_KEYTYPE_ULONG_INT:
526
value=(uint64_t) uint4korr(key);
554
value=(ulonglong) uint4korr(key);
528
556
case HA_KEYTYPE_INT24:
529
s_value= (int64_t) sint3korr(key);
557
s_value= (longlong) sint3korr(key);
531
559
case HA_KEYTYPE_UINT24:
532
value=(uint64_t) uint3korr(key);
560
value=(ulonglong) uint3korr(key);
534
562
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
537
565
float4get(f_1,key);
538
566
/* Ignore negative values */
539
value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
567
value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
542
570
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */