18 #include "myisam_priv.h"
19 #include <drizzled/charset.h>
26 using namespace drizzled;
31 #define FIX_LENGTH(cs, pos, length, char_length) \
33 if (length > char_length) \
34 char_length= my_charpos(cs, pos, pos+length, char_length); \
35 drizzled::set_if_smaller(char_length,length); \
38 static int _mi_put_key_in_record(
MI_INFO *info,uint32_t keynr,
unsigned char *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)
63 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;
72 if (record[keyseg->null_pos] & keyseg->null_bit)
80 char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
83 pos= (
unsigned char*) record+keyseg->start;
85 if (keyseg->flag & HA_SPACE_PACK)
87 length= cs->cset->lengthsp(cs, (
char*) pos, length);
89 FIX_LENGTH(cs, pos, length, char_length);
90 store_key_length_inc(key,char_length);
91 memcpy(key, pos, char_length);
95 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 :
101 drizzled::set_if_smaller(length,tmp_length);
102 FIX_LENGTH(cs, pos, length, char_length);
103 store_key_length_inc(key,char_length);
104 memcpy(key, pos, char_length);
108 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);
113 FIX_LENGTH(cs, pos, length, char_length);
114 store_key_length_inc(key,char_length);
115 memcpy(key, pos, char_length);
119 else if (keyseg->flag & HA_SWAP_KEY)
121 if (type == drizzled::HA_KEYTYPE_DOUBLE)
127 memset(key, 0, length);
139 FIX_LENGTH(cs, pos, length, char_length);
140 memcpy(key, pos, char_length);
141 if (length > char_length)
142 cs->cset->fill(cs, (
char*) key+char_length, length-char_length,
' ');
145 _mi_dpointer(info,key,filepos);
146 return((uint) (key-start));
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)
171 unsigned char *start_key=key;
175 assert(((keypart_map+1) & keypart_map) == 0);
177 for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
178 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;
186 if (keyseg->null_bit)
188 if (!(*key++= (
char) 1-*old++))
190 if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
195 char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
197 if (keyseg->flag & HA_SPACE_PACK)
199 unsigned char *end=pos+length;
201 if (type != drizzled::HA_KEYTYPE_BINARY)
203 while (end > pos && end[-1] ==
' ')
206 length=(uint) (end-pos);
207 FIX_LENGTH(cs, pos, length, char_length);
208 store_key_length_inc(key,char_length);
209 memcpy(key, pos, char_length);
213 else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
216 uint32_t tmp_length=uint2korr(pos);
218 drizzled::set_if_smaller(length,tmp_length);
219 FIX_LENGTH(cs, pos, length, char_length);
220 store_key_length_inc(key,char_length);
222 memcpy(key, pos, char_length);
226 else if (keyseg->flag & HA_SWAP_KEY)
233 FIX_LENGTH(cs, pos, length, char_length);
234 memcpy(key, pos, char_length);
235 if (length > char_length)
236 cs->cset->fill(cs, (
char*) key+char_length, length-char_length,
' ');
239 if (last_used_keyseg)
240 *last_used_keyseg= keyseg;
242 return((uint) (key-start_key));
266 static int _mi_put_key_in_record(
register MI_INFO *info, uint32_t keynr,
267 unsigned char *record)
269 register unsigned char *key;
270 unsigned char *pos,*key_end;
272 unsigned char *blob_ptr;
274 blob_ptr= (
unsigned char*) info->lastkey2;
275 key=(
unsigned char*) info->lastkey;
276 key_end=key+info->lastkey_length;
277 for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
279 if (keyseg->null_bit)
283 record[keyseg->null_pos]|= keyseg->null_bit;
286 record[keyseg->null_pos]&= ~keyseg->null_bit;
289 if (keyseg->flag & HA_SPACE_PACK)
292 get_key_length(length,key);
294 if (length > keyseg->length || key+length > key_end)
297 pos= record+keyseg->start;
299 memcpy(pos, key, length);
300 keyseg->charset->cset->fill(keyseg->charset,
301 (
char*) pos + length,
302 keyseg->length - length,
308 if (keyseg->flag & HA_VAR_LENGTH_PART)
311 get_key_length(length,key);
313 if (length > keyseg->length || key+length > key_end)
317 if (keyseg->bit_start == 1)
318 *(
unsigned char*) (record+keyseg->start)= (
unsigned char) length;
320 int2store(record+keyseg->start, length);
322 memcpy(record+keyseg->start + keyseg->bit_start, key, length);
325 else if (keyseg->flag & HA_BLOB_PART)
328 get_key_length(length,key);
330 if (length > keyseg->length || key+length > key_end)
333 memcpy(record+keyseg->start+keyseg->bit_start,
334 &blob_ptr,
sizeof(
char*));
335 memcpy(blob_ptr,key,length);
339 info->update&= ~HA_STATE_RNEXT_SAME;
341 _my_store_blob_length(record+keyseg->start,
342 (uint) keyseg->bit_start,length);
345 else if (keyseg->flag & HA_SWAP_KEY)
347 unsigned char *to= record+keyseg->start+keyseg->length;
348 unsigned char *end= key+keyseg->length;
356 }
while (key != end);
362 if (key+keyseg->length > key_end)
365 memcpy(record+keyseg->start, key, keyseg->length);
366 key+= keyseg->length;
378 int _mi_read_key_record(
MI_INFO *info, drizzled::internal::my_off_t filepos,
unsigned char *buf)
380 fast_mi_writeinfo(info);
381 if (filepos != HA_OFFSET_ERROR)
383 if (info->lastinx >= 0)
385 if (_mi_put_key_in_record(info,(uint) info->lastinx,buf))
387 mi_print_error(info->s, HA_ERR_CRASHED);
388 errno=HA_ERR_CRASHED;
391 info->update|= HA_STATE_AKTIV;
394 errno=HA_ERR_WRONG_INDEX;
417 int mi_check_index_cond(
register MI_INFO *info, uint32_t keynr,
unsigned char *record)
419 if (_mi_put_key_in_record(info, keynr, record))
421 mi_print_error(info->s, HA_ERR_CRASHED);
422 errno=HA_ERR_CRASHED;
425 return info->index_cond_func(info->index_cond_func_arg);
442 uint64_t retrieve_auto_increment(
MI_INFO *info,
const unsigned char *record)
446 HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
447 const unsigned char *key= (
unsigned char*) record + keyseg->start;
449 switch (keyseg->type) {
450 case drizzled::HA_KEYTYPE_BINARY:
451 value=(uint64_t) *(
unsigned char*) key;
453 case drizzled::HA_KEYTYPE_LONG_INT:
454 s_value= (int64_t) sint4korr(key);
456 case drizzled::HA_KEYTYPE_ULONG_INT:
457 value=(uint64_t) uint4korr(key);
459 case drizzled::HA_KEYTYPE_DOUBLE:
464 value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
467 case drizzled::HA_KEYTYPE_LONGLONG:
468 s_value= sint8korr(key);
470 case drizzled::HA_KEYTYPE_ULONGLONG:
471 value= uint8korr(key);
484 return (s_value > 0) ? (uint64_t) s_value : value;