52
uint32_t _mi_make_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
53
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)
57
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*/
60
73
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
62
75
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
63
uint32_t length=keyseg->length;
65
const CHARSET_INFO * const cs=keyseg->charset;
76
uint length=keyseg->length;
78
CHARSET_INFO *cs=keyseg->charset;
67
80
if (keyseg->null_bit)
74
87
*key++=1; /* Not NULL */
77
char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
90
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
80
pos= (unsigned char*) record+keyseg->start;
93
pos= (uchar*) record+keyseg->start;
94
if (type == HA_KEYTYPE_BIT)
96
if (keyseg->bit_length)
98
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
99
keyseg->bit_start, keyseg->bit_length);
103
memcpy((uchar*) key, pos, length);
82
107
if (keyseg->flag & HA_SPACE_PACK)
84
length= cs->cset->lengthsp(cs, (char*) pos, length);
109
if (type != HA_KEYTYPE_NUM)
111
length= cs->cset->lengthsp(cs, (char*) pos, length);
115
uchar *end= pos + length;
116
while (pos < end && pos[0] == ' ')
118
length=(uint) (end-pos);
86
120
FIX_LENGTH(cs, pos, length, char_length);
87
121
store_key_length_inc(key,char_length);
88
memcpy(key, pos, char_length);
122
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
92
126
if (keyseg->flag & HA_VAR_LENGTH_PART)
94
uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
95
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 :
97
131
pos+= pack_length; /* Skip VARCHAR length */
98
132
set_if_smaller(length,tmp_length);
99
133
FIX_LENGTH(cs, pos, length, char_length);
100
134
store_key_length_inc(key,char_length);
101
memcpy(key, pos, char_length);
135
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
102
136
key+= char_length;
105
139
else if (keyseg->flag & HA_BLOB_PART)
107
uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
108
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*));
109
143
set_if_smaller(length,tmp_length);
110
144
FIX_LENGTH(cs, pos, length, char_length);
111
145
store_key_length_inc(key,char_length);
112
memcpy(key, pos, char_length);
146
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
113
147
key+= char_length;
116
150
else if (keyseg->flag & HA_SWAP_KEY)
117
151
{ /* Numerical column */
118
if (type == HA_KEYTYPE_DOUBLE)
153
if (type == HA_KEYTYPE_FLOAT)
159
/* Replace NAN with zero */
165
else if (type == HA_KEYTYPE_DOUBLE)
121
168
float8get(nr,pos);
124
memset(key, 0, length);
136
184
FIX_LENGTH(cs, pos, length, char_length);
137
memcpy(key, pos, char_length);
185
memcpy((uchar*) key, pos, char_length);
138
186
if (length > char_length)
139
187
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
142
190
_mi_dpointer(info,key,filepos);
143
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 */
144
197
} /* _mi_make_key */
162
215
last_use_keyseg Store pointer to the keyseg after the last used one
165
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,
166
219
key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
168
unsigned char *start_key=key;
221
uchar *start_key=key;
169
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;
171
230
/* only key prefixes are supported */
172
assert(((keypart_map+1) & keypart_map) == 0);
231
DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
174
233
for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
175
234
old+= keyseg->length, keyseg++)
177
236
enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
178
uint32_t length= keyseg->length;
179
uint32_t char_length;
181
const CHARSET_INFO * const cs=keyseg->charset;
237
uint length= keyseg->length;
240
CHARSET_INFO *cs=keyseg->charset;
182
241
keypart_map>>= 1;
183
242
if (keyseg->null_bit)
189
248
continue; /* Found NULL */
192
char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
251
char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
194
253
if (keyseg->flag & HA_SPACE_PACK)
196
unsigned char *end=pos+length;
198
if (type != HA_KEYTYPE_BINARY)
255
uchar *end=pos+length;
256
if (type == HA_KEYTYPE_NUM)
258
while (pos < end && pos[0] == ' ')
261
else if (type != HA_KEYTYPE_BINARY)
200
263
while (end > pos && end[-1] == ' ')
203
266
length=(uint) (end-pos);
204
267
FIX_LENGTH(cs, pos, length, char_length);
205
268
store_key_length_inc(key,char_length);
206
memcpy(key, pos, char_length);
269
memcpy((uchar*) key,pos,(size_t) char_length);
207
270
key+= char_length;
210
273
else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
212
275
/* Length of key-part used with mi_rkey() always 2 */
213
uint32_t tmp_length=uint2korr(pos);
276
uint tmp_length=uint2korr(pos);
215
278
set_if_smaller(length,tmp_length); /* Safety */
216
279
FIX_LENGTH(cs, pos, length, char_length);
217
280
store_key_length_inc(key,char_length);
218
281
old+=2; /* Skip length */
219
memcpy(key, pos, char_length);
282
memcpy((uchar*) key, pos,(size_t) char_length);
220
283
key+= char_length;
230
293
FIX_LENGTH(cs, pos, length, char_length);
231
memcpy(key, pos, char_length);
294
memcpy((uchar*) key, pos, char_length);
232
295
if (length > char_length)
233
296
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
263
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
264
unsigned char *record)
326
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
266
register unsigned char *key;
267
unsigned char *pos,*key_end;
268
331
register HA_KEYSEG *keyseg;
269
unsigned char *blob_ptr;
333
DBUG_ENTER("_mi_put_key_in_record");
271
blob_ptr= (unsigned char*) info->lastkey2; /* Place to put blob parts */
272
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 */
273
337
key_end=key+info->lastkey_length;
274
338
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
283
347
record[keyseg->null_pos]&= ~keyseg->null_bit;
349
if (keyseg->type == HA_KEYTYPE_BIT)
351
uint length= keyseg->length;
353
if (keyseg->bit_length)
356
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
362
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
365
memcpy(record + keyseg->start, (uchar*) key, length);
286
369
if (keyseg->flag & HA_SPACE_PACK)
289
372
get_key_length(length,key);
290
373
#ifdef CHECK_KEYS
291
374
if (length > keyseg->length || key+length > key_end)
294
377
pos= record+keyseg->start;
296
memcpy(pos, key, length);
297
keyseg->charset->cset->fill(keyseg->charset,
298
(char*) pos + length,
299
keyseg->length - length,
378
if (keyseg->type != (int) HA_KEYTYPE_NUM)
380
memcpy(pos,key,(size_t) length);
381
keyseg->charset->cset->fill(keyseg->charset,
382
(char*) pos + length,
383
keyseg->length - length,
388
bfill(pos,keyseg->length-length,' ');
389
memcpy(pos+keyseg->length-length,key,(size_t) length);
305
395
if (keyseg->flag & HA_VAR_LENGTH_PART)
308
398
get_key_length(length,key);
309
399
#ifdef CHECK_KEYS
310
400
if (length > keyseg->length || key+length > key_end)
313
403
/* Store key length */
314
404
if (keyseg->bit_start == 1)
315
*(unsigned char*) (record+keyseg->start)= (unsigned char) length;
405
*(uchar*) (record+keyseg->start)= (uchar) length;
317
407
int2store(record+keyseg->start, length);
318
408
/* And key data */
319
memcpy(record+keyseg->start + keyseg->bit_start, key, length);
409
memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
322
412
else if (keyseg->flag & HA_BLOB_PART)
325
415
get_key_length(length,key);
326
416
#ifdef CHECK_KEYS
327
417
if (length > keyseg->length || key+length > key_end)
330
420
memcpy(record+keyseg->start+keyseg->bit_start,
331
&blob_ptr,sizeof(char*));
421
(char*) &blob_ptr,sizeof(char*));
332
422
memcpy(blob_ptr,key,length);
333
423
blob_ptr+=length;
359
449
if (key+keyseg->length > key_end)
362
memcpy(record+keyseg->start, key, keyseg->length);
452
memcpy(record+keyseg->start,(uchar*) key,
453
(size_t) keyseg->length);
363
454
key+= keyseg->length;
369
return(1); /* Crashed row */
460
DBUG_RETURN(1); /* Crashed row */
370
461
} /* _mi_put_key_in_record */
373
464
/* Here when key reads are used */
375
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)
377
468
fast_mi_writeinfo(info);
378
469
if (filepos != HA_OFFSET_ERROR)
401
492
mi_check_index_cond()
402
493
info MyISAM handler
403
494
keynr Index we're running a scan on
404
record Record buffer to use (it is assumed that index check function
495
record Record buffer to use (it is assumed that index check function
405
496
will look for column values there)
409
500
0 Index condition is not satisfied, continue scanning
410
501
1 Index condition is satisfied
411
2 Index condition is not satisfied, end the scan.
502
2 Index condition is not satisfied, end the scan.
414
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)
416
507
if (_mi_put_key_in_record(info, keynr, record))
418
509
mi_print_error(info->s, HA_ERR_CRASHED);
419
errno=HA_ERR_CRASHED;
510
my_errno=HA_ERR_CRASHED;
422
513
return info->index_cond_func(info->index_cond_func_arg);
439
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
530
ulonglong retrieve_auto_increment(MI_INFO *info,const uchar *record)
441
uint64_t value= 0; /* Store unsigned values here */
442
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 */
443
534
HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
444
const unsigned char *key= (unsigned char*) record + keyseg->start;
535
const uchar *key= (uchar*) record + keyseg->start;
446
537
switch (keyseg->type) {
538
case HA_KEYTYPE_INT8:
539
s_value= (longlong) *(char*)key;
447
541
case HA_KEYTYPE_BINARY:
448
value=(uint64_t) *(unsigned char*) key;
542
value=(ulonglong) *(uchar*) key;
544
case HA_KEYTYPE_SHORT_INT:
545
s_value= (longlong) sint2korr(key);
547
case HA_KEYTYPE_USHORT_INT:
548
value=(ulonglong) uint2korr(key);
450
550
case HA_KEYTYPE_LONG_INT:
451
s_value= (int64_t) sint4korr(key);
551
s_value= (longlong) sint4korr(key);
453
553
case HA_KEYTYPE_ULONG_INT:
454
value=(uint64_t) uint4korr(key);
554
value=(ulonglong) uint4korr(key);
556
case HA_KEYTYPE_INT24:
557
s_value= (longlong) sint3korr(key);
456
559
case HA_KEYTYPE_UINT24:
457
value=(uint64_t) uint3korr(key);
560
value=(ulonglong) uint3korr(key);
562
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
566
/* Ignore negative values */
567
value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
459
570
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
462
573
float8get(f_1,key);
463
574
/* Ignore negative values */
464
value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
575
value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
467
578
case HA_KEYTYPE_LONGLONG: