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"
19
#include <mystrings/m_ctype.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;
63
58
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;
60
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
61
uint length=keyseg->length;
63
const CHARSET_INFO * const cs=keyseg->charset;
70
65
if (keyseg->null_bit)
80
75
char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
83
pos= (unsigned char*) record+keyseg->start;
78
pos= (uchar*) record+keyseg->start;
79
if (type == HA_KEYTYPE_BIT)
81
if (keyseg->bit_length)
83
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
keyseg->bit_start, keyseg->bit_length);
88
memcpy(key, pos, length);
85
92
if (keyseg->flag & HA_SPACE_PACK)
87
length= cs->cset->lengthsp(cs, (char*) pos, length);
94
if (type != HA_KEYTYPE_NUM)
96
length= cs->cset->lengthsp(cs, (char*) pos, length);
100
uchar *end= pos + length;
101
while (pos < end && pos[0] == ' ')
103
length=(uint) (end-pos);
89
105
FIX_LENGTH(cs, pos, length, char_length);
90
106
store_key_length_inc(key,char_length);
91
107
memcpy(key, pos, char_length);
95
111
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 :
113
uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
100
116
pos+= pack_length; /* Skip VARCHAR length */
101
drizzled::set_if_smaller(length,tmp_length);
117
set_if_smaller(length,tmp_length);
102
118
FIX_LENGTH(cs, pos, length, char_length);
103
119
store_key_length_inc(key,char_length);
104
120
memcpy(key, pos, char_length);
108
124
else if (keyseg->flag & HA_BLOB_PART)
110
uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
126
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
111
127
memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
112
drizzled::set_if_smaller(length,tmp_length);
128
set_if_smaller(length,tmp_length);
113
129
FIX_LENGTH(cs, pos, length, char_length);
114
130
store_key_length_inc(key,char_length);
115
131
memcpy(key, pos, char_length);
119
135
else if (keyseg->flag & HA_SWAP_KEY)
120
136
{ /* Numerical column */
121
if (type == drizzled::HA_KEYTYPE_DOUBLE)
138
if (type == HA_KEYTYPE_FLOAT)
144
/* Replace NAN with zero */
145
memset(key, 0, length);
150
else if (type == HA_KEYTYPE_DOUBLE)
124
153
float8get(nr,pos);
165
195
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)
198
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
199
key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
171
unsigned char *start_key=key;
201
uchar *start_key=key;
172
202
HA_KEYSEG *keyseg;
174
204
/* only key prefixes are supported */
177
207
for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
178
208
old+= keyseg->length, keyseg++)
180
enum drizzled::ha_base_keytype type= (enum drizzled::ha_base_keytype) keyseg->type;
181
uint32_t length= keyseg->length;
182
uint32_t char_length;
184
const drizzled::CHARSET_INFO * const cs=keyseg->charset;
210
enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
211
uint length= keyseg->length;
214
const CHARSET_INFO * const cs=keyseg->charset;
185
215
keypart_map>>= 1;
186
216
if (keyseg->null_bit)
197
227
if (keyseg->flag & HA_SPACE_PACK)
199
unsigned char *end=pos+length;
201
if (type != drizzled::HA_KEYTYPE_BINARY)
229
uchar *end=pos+length;
230
if (type == HA_KEYTYPE_NUM)
232
while (pos < end && pos[0] == ' ')
235
else if (type != HA_KEYTYPE_BINARY)
203
237
while (end > pos && end[-1] == ' ')
213
247
else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
215
249
/* Length of key-part used with mi_rkey() always 2 */
216
uint32_t tmp_length=uint2korr(pos);
250
uint tmp_length=uint2korr(pos);
218
drizzled::set_if_smaller(length,tmp_length); /* Safety */
252
set_if_smaller(length,tmp_length); /* Safety */
219
253
FIX_LENGTH(cs, pos, length, char_length);
220
254
store_key_length_inc(key,char_length);
221
255
old+=2; /* Skip length */
266
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
267
unsigned char *record)
300
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
305
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 */
308
blob_ptr= (uchar*) info->lastkey2; /* Place to put blob parts */
309
key=(uchar*) info->lastkey; /* KEy that was read */
276
310
key_end=key+info->lastkey_length;
277
311
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
286
320
record[keyseg->null_pos]&= ~keyseg->null_bit;
322
if (keyseg->type == HA_KEYTYPE_BIT)
324
uint length= keyseg->length;
326
if (keyseg->bit_length)
329
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
335
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
338
memcpy(record + keyseg->start, key, length);
289
342
if (keyseg->flag & HA_SPACE_PACK)
292
345
get_key_length(length,key);
293
346
#ifdef CHECK_KEYS
294
347
if (length > keyseg->length || key+length > key_end)
297
350
pos= record+keyseg->start;
299
memcpy(pos, key, length);
300
keyseg->charset->cset->fill(keyseg->charset,
301
(char*) pos + length,
302
keyseg->length - length,
351
if (keyseg->type != (int) HA_KEYTYPE_NUM)
353
memcpy(pos, key, length);
354
keyseg->charset->cset->fill(keyseg->charset,
355
(char*) pos + length,
356
keyseg->length - length,
361
memset(pos, ' ', keyseg->length-length);
362
memcpy(pos+keyseg->length-length, key, length);
308
368
if (keyseg->flag & HA_VAR_LENGTH_PART)
311
371
get_key_length(length,key);
312
372
#ifdef CHECK_KEYS
313
373
if (length > keyseg->length || key+length > key_end)
316
376
/* Store key length */
317
377
if (keyseg->bit_start == 1)
318
*(unsigned char*) (record+keyseg->start)= (unsigned char) length;
378
*(uchar*) (record+keyseg->start)= (uchar) length;
320
380
int2store(record+keyseg->start, length);
321
381
/* And key data */
345
405
else if (keyseg->flag & HA_SWAP_KEY)
347
unsigned char *to= record+keyseg->start+keyseg->length;
348
unsigned char *end= key+keyseg->length;
407
uchar *to= record+keyseg->start+keyseg->length;
408
uchar *end= key+keyseg->length;
349
409
#ifdef CHECK_KEYS
350
410
if (end > key_end)
376
436
/* Here when key reads are used */
378
int _mi_read_key_record(MI_INFO *info, drizzled::internal::my_off_t filepos, unsigned char *buf)
438
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
380
440
fast_mi_writeinfo(info);
381
441
if (filepos != HA_OFFSET_ERROR)
385
445
if (_mi_put_key_in_record(info,(uint) info->lastinx,buf))
387
447
mi_print_error(info->s, HA_ERR_CRASHED);
388
errno=HA_ERR_CRASHED;
448
my_errno=HA_ERR_CRASHED;
391
451
info->update|= HA_STATE_AKTIV; /* We should find a record */
394
errno=HA_ERR_WRONG_INDEX;
454
my_errno=HA_ERR_WRONG_INDEX;
396
456
return(-1); /* Wrong data to read */
404
464
mi_check_index_cond()
405
465
info MyISAM handler
406
466
keynr Index we're running a scan on
407
record Record buffer to use (it is assumed that index check function
467
record Record buffer to use (it is assumed that index check function
408
468
will look for column values there)
412
472
0 Index condition is not satisfied, continue scanning
413
473
1 Index condition is satisfied
414
2 Index condition is not satisfied, end the scan.
474
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)
477
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
419
479
if (_mi_put_key_in_record(info, keynr, record))
421
481
mi_print_error(info->s, HA_ERR_CRASHED);
422
errno=HA_ERR_CRASHED;
482
my_errno=HA_ERR_CRASHED;
425
485
return info->index_cond_func(info->index_cond_func_arg);
442
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
502
uint64_t retrieve_auto_increment(MI_INFO *info,const uchar *record)
444
504
uint64_t value= 0; /* Store unsigned values here */
445
505
int64_t s_value= 0; /* Store signed values here */
446
506
HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
447
const unsigned char *key= (unsigned char*) record + keyseg->start;
507
const uchar *key= (uchar*) record + keyseg->start;
449
509
switch (keyseg->type) {
450
case drizzled::HA_KEYTYPE_BINARY:
451
value=(uint64_t) *(unsigned char*) key;
453
case drizzled::HA_KEYTYPE_LONG_INT:
510
case HA_KEYTYPE_INT8:
511
s_value= (int64_t) *(char*)key;
513
case HA_KEYTYPE_BINARY:
514
value=(uint64_t) *(uchar*) key;
516
case HA_KEYTYPE_SHORT_INT:
517
s_value= (int64_t) sint2korr(key);
519
case HA_KEYTYPE_USHORT_INT:
520
value=(uint64_t) uint2korr(key);
522
case HA_KEYTYPE_LONG_INT:
454
523
s_value= (int64_t) sint4korr(key);
456
case drizzled::HA_KEYTYPE_ULONG_INT:
525
case HA_KEYTYPE_ULONG_INT:
457
526
value=(uint64_t) uint4korr(key);
459
case drizzled::HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
528
case HA_KEYTYPE_INT24:
529
s_value= (int64_t) sint3korr(key);
531
case HA_KEYTYPE_UINT24:
532
value=(uint64_t) uint3korr(key);
534
case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
538
/* Ignore negative values */
539
value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
542
case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
462
545
float8get(f_1,key);
464
547
value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
467
case drizzled::HA_KEYTYPE_LONGLONG:
550
case HA_KEYTYPE_LONGLONG:
468
551
s_value= sint8korr(key);
470
case drizzled::HA_KEYTYPE_ULONGLONG:
553
case HA_KEYTYPE_ULONGLONG:
471
554
value= uint8korr(key);