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
/* Functions to handle keys */
18
#include "myisam_priv.h"
19
#include <drizzled/charset_info.h>
18
#include "myisamdef.h"
20
20
#ifdef HAVE_IEEEFP_H
21
21
#include <ieeefp.h>
26
using namespace drizzled;
29
24
#define CHECK_KEYS /* Enable safety checks */
33
28
if (length > char_length) \
34
29
char_length= my_charpos(cs, pos, pos+length, char_length); \
35
drizzled::set_if_smaller(char_length,length); \
30
set_if_smaller(char_length,length); \
38
static int _mi_put_key_in_record(MI_INFO *info,uint32_t keynr,unsigned char *record);
33
static int _mi_put_key_in_record(MI_INFO *info,uint keynr,uchar *record);
41
36
Make a intern key from a record
55
uint32_t _mi_make_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
56
const unsigned char *record, drizzled::internal::my_off_t filepos)
50
uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
51
const uchar *record, my_off_t filepos)
60
55
register HA_KEYSEG *keyseg;
56
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
63
59
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
65
enum drizzled::ha_base_keytype type=(enum drizzled::ha_base_keytype) keyseg->type;
66
uint32_t length=keyseg->length;
68
const drizzled::CHARSET_INFO * const cs=keyseg->charset;
61
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
62
uint length=keyseg->length;
64
CHARSET_INFO *cs=keyseg->charset;
70
66
if (keyseg->null_bit)
77
73
*key++=1; /* Not NULL */
80
char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
76
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
83
pos= (unsigned char*) record+keyseg->start;
79
pos= (uchar*) record+keyseg->start;
80
if (type == HA_KEYTYPE_BIT)
82
if (keyseg->bit_length)
84
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
85
keyseg->bit_start, keyseg->bit_length);
89
memcpy((uchar*) key, pos, length);
85
93
if (keyseg->flag & HA_SPACE_PACK)
87
length= cs->cset->lengthsp(cs, (char*) pos, length);
95
if (type != HA_KEYTYPE_NUM)
97
length= cs->cset->lengthsp(cs, (char*) pos, length);
101
uchar *end= pos + length;
102
while (pos < end && pos[0] == ' ')
104
length=(uint) (end-pos);
89
106
FIX_LENGTH(cs, pos, length, char_length);
90
107
store_key_length_inc(key,char_length);
91
memcpy(key, pos, char_length);
108
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
95
112
if (keyseg->flag & HA_VAR_LENGTH_PART)
97
uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
98
uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
114
uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
115
uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
100
117
pos+= pack_length; /* Skip VARCHAR length */
101
drizzled::set_if_smaller(length,tmp_length);
118
set_if_smaller(length,tmp_length);
102
119
FIX_LENGTH(cs, pos, length, char_length);
103
120
store_key_length_inc(key,char_length);
104
memcpy(key, pos, char_length);
121
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
105
122
key+= char_length;
108
125
else if (keyseg->flag & HA_BLOB_PART)
110
uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
111
memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
112
drizzled::set_if_smaller(length,tmp_length);
127
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
128
memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
129
set_if_smaller(length,tmp_length);
113
130
FIX_LENGTH(cs, pos, length, char_length);
114
131
store_key_length_inc(key,char_length);
115
memcpy(key, pos, char_length);
132
memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
116
133
key+= char_length;
119
136
else if (keyseg->flag & HA_SWAP_KEY)
120
137
{ /* Numerical column */
121
if (type == drizzled::HA_KEYTYPE_DOUBLE)
139
if (type == HA_KEYTYPE_FLOAT)
145
/* Replace NAN with zero */
151
else if (type == HA_KEYTYPE_DOUBLE)
124
154
float8get(nr,pos);
127
memset(key, 0, length);
165
196
last_use_keyseg Store pointer to the keyseg after the last used one
168
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
169
drizzled::key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
199
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
200
key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
171
unsigned char *start_key=key;
202
uchar *start_key=key;
172
203
HA_KEYSEG *keyseg;
204
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
174
206
/* only key prefixes are supported */
175
207
assert(((keypart_map+1) & keypart_map) == 0);
192
224
continue; /* Found NULL */
195
char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
227
char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
197
229
if (keyseg->flag & HA_SPACE_PACK)
199
unsigned char *end=pos+length;
201
if (type != drizzled::HA_KEYTYPE_BINARY)
231
uchar *end=pos+length;
232
if (type == HA_KEYTYPE_NUM)
234
while (pos < end && pos[0] == ' ')
237
else if (type != HA_KEYTYPE_BINARY)
203
239
while (end > pos && end[-1] == ' ')
206
242
length=(uint) (end-pos);
207
243
FIX_LENGTH(cs, pos, length, char_length);
208
244
store_key_length_inc(key,char_length);
209
memcpy(key, pos, char_length);
245
memcpy((uchar*) key,pos,(size_t) char_length);
210
246
key+= char_length;
213
249
else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
215
251
/* Length of key-part used with mi_rkey() always 2 */
216
uint32_t tmp_length=uint2korr(pos);
252
uint tmp_length=uint2korr(pos);
218
drizzled::set_if_smaller(length,tmp_length); /* Safety */
254
set_if_smaller(length,tmp_length); /* Safety */
219
255
FIX_LENGTH(cs, pos, length, char_length);
220
256
store_key_length_inc(key,char_length);
221
257
old+=2; /* Skip length */
222
memcpy(key, pos, char_length);
258
memcpy((uchar*) key, pos,(size_t) char_length);
223
259
key+= char_length;
266
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
267
unsigned char *record)
302
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
269
register unsigned char *key;
270
unsigned char *pos,*key_end;
271
307
register HA_KEYSEG *keyseg;
272
unsigned char *blob_ptr;
274
blob_ptr= (unsigned char*) info->lastkey2; /* Place to put blob parts */
275
key=(unsigned char*) info->lastkey; /* KEy that was read */
310
blob_ptr= (uchar*) info->lastkey2; /* Place to put blob parts */
311
key=(uchar*) info->lastkey; /* KEy that was read */
276
312
key_end=key+info->lastkey_length;
277
313
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
286
322
record[keyseg->null_pos]&= ~keyseg->null_bit;
324
if (keyseg->type == HA_KEYTYPE_BIT)
326
uint length= keyseg->length;
328
if (keyseg->bit_length)
331
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
337
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
340
memcpy(record + keyseg->start, (uchar*) key, length);
289
344
if (keyseg->flag & HA_SPACE_PACK)
292
347
get_key_length(length,key);
293
348
#ifdef CHECK_KEYS
294
349
if (length > keyseg->length || key+length > key_end)
297
352
pos= record+keyseg->start;
299
memcpy(pos, key, length);
300
keyseg->charset->cset->fill(keyseg->charset,
301
(char*) pos + length,
302
keyseg->length - length,
353
if (keyseg->type != (int) HA_KEYTYPE_NUM)
355
memcpy(pos,key,(size_t) length);
356
keyseg->charset->cset->fill(keyseg->charset,
357
(char*) pos + length,
358
keyseg->length - length,
363
bfill(pos,keyseg->length-length,' ');
364
memcpy(pos+keyseg->length-length,key,(size_t) length);
308
370
if (keyseg->flag & HA_VAR_LENGTH_PART)
311
373
get_key_length(length,key);
312
374
#ifdef CHECK_KEYS
313
375
if (length > keyseg->length || key+length > key_end)
316
378
/* Store key length */
317
379
if (keyseg->bit_start == 1)
318
*(unsigned char*) (record+keyseg->start)= (unsigned char) length;
380
*(uchar*) (record+keyseg->start)= (uchar) length;
320
382
int2store(record+keyseg->start, length);
321
383
/* And key data */
322
memcpy(record+keyseg->start + keyseg->bit_start, key, length);
384
memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
325
387
else if (keyseg->flag & HA_BLOB_PART)
328
390
get_key_length(length,key);
329
391
#ifdef CHECK_KEYS
330
392
if (length > keyseg->length || key+length > key_end)
333
395
memcpy(record+keyseg->start+keyseg->bit_start,
334
&blob_ptr,sizeof(char*));
396
(char*) &blob_ptr,sizeof(char*));
335
397
memcpy(blob_ptr,key,length);
336
398
blob_ptr+=length;
404
467
mi_check_index_cond()
405
468
info MyISAM handler
406
469
keynr Index we're running a scan on
407
record Record buffer to use (it is assumed that index check function
470
record Record buffer to use (it is assumed that index check function
408
471
will look for column values there)
412
475
0 Index condition is not satisfied, continue scanning
413
476
1 Index condition is satisfied
414
2 Index condition is not satisfied, end the scan.
477
2 Index condition is not satisfied, end the scan.
417
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
480
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
419
482
if (_mi_put_key_in_record(info, keynr, record))
421
484
mi_print_error(info->s, HA_ERR_CRASHED);
422
errno=HA_ERR_CRASHED;
485
my_errno=HA_ERR_CRASHED;
425
488
return info->index_cond_func(info->index_cond_func_arg);
442
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
505
uint64_t retrieve_auto_increment(MI_INFO *info,const uchar *record)
444
507
uint64_t value= 0; /* Store unsigned values here */
445
508
int64_t s_value= 0; /* Store signed values here */
446
509
HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
447
const unsigned char *key= (unsigned char*) record + keyseg->start;
510
const uchar *key= (uchar*) record + keyseg->start;
449
512
switch (keyseg->type) {
450
case drizzled::HA_KEYTYPE_BINARY:
451
value=(uint64_t) *(unsigned char*) key;
453
case drizzled::HA_KEYTYPE_LONG_INT:
513
case HA_KEYTYPE_INT8:
514
s_value= (int64_t) *(char*)key;
516
case HA_KEYTYPE_BINARY:
517
value=(uint64_t) *(uchar*) key;
519
case HA_KEYTYPE_SHORT_INT:
520
s_value= (int64_t) sint2korr(key);
522
case HA_KEYTYPE_USHORT_INT:
523
value=(uint64_t) uint2korr(key);
525
case HA_KEYTYPE_LONG_INT:
454
526
s_value= (int64_t) sint4korr(key);
456
case drizzled::HA_KEYTYPE_ULONG_INT:
528
case HA_KEYTYPE_ULONG_INT:
457
529
value=(uint64_t) uint4korr(key);
459
case drizzled::HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
531
case HA_KEYTYPE_INT24:
532
s_value= (int64_t) sint3korr(key);
534
case HA_KEYTYPE_UINT24:
535
value=(uint64_t) uint3korr(key);
537
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
541
/* Ignore negative values */
542
value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
545
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
462
548
float8get(f_1,key);