~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_key.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* Functions to handle keys */
17
17
 
18
 
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
 
18
#include "myisam_priv.h"
 
19
#include "drizzled/charset_info.h"
20
20
#ifdef HAVE_IEEEFP_H
21
21
#include <ieeefp.h>
22
22
#endif
 
23
#include <math.h>
 
24
#include <cassert>
23
25
 
24
26
#define CHECK_KEYS                              /* Enable safety checks */
25
27
 
27
29
            do {                                                            \
28
30
              if (length > char_length)                                     \
29
31
                char_length= my_charpos(cs, pos, pos+length, char_length);  \
30
 
              set_if_smaller(char_length,length);                           \
 
32
              drizzled::set_if_smaller(char_length,length);                           \
31
33
            } while(0)
32
34
 
33
 
static int _mi_put_key_in_record(MI_INFO *info,uint keynr,uchar *record);
 
35
static int _mi_put_key_in_record(MI_INFO *info,uint32_t keynr,unsigned char *record);
34
36
 
35
37
/*
36
38
  Make a intern key from a record
47
49
    Length of key
48
50
*/
49
51
 
50
 
uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
51
 
                  const uchar *record, my_off_t filepos)
 
52
uint32_t _mi_make_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
 
53
                      const unsigned char *record, drizzled::internal::my_off_t filepos)
52
54
{
53
 
  uchar *pos;
54
 
  uchar *start;
 
55
  unsigned char *pos;
 
56
  unsigned char *start;
55
57
  register HA_KEYSEG *keyseg;
56
58
 
57
59
  start=key;
58
60
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
59
61
  {
60
 
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
61
 
    uint length=keyseg->length;
62
 
    uint char_length;
63
 
    const CHARSET_INFO * const cs=keyseg->charset;
 
62
    enum drizzled::ha_base_keytype type=(enum drizzled::ha_base_keytype) keyseg->type;
 
63
    uint32_t length=keyseg->length;
 
64
    uint32_t char_length;
 
65
    const drizzled::CHARSET_INFO * const cs=keyseg->charset;
64
66
 
65
67
    if (keyseg->null_bit)
66
68
    {
75
77
    char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
76
78
                  length);
77
79
 
78
 
    pos= (uchar*) record+keyseg->start;
79
 
    if (type == HA_KEYTYPE_BIT)
80
 
    {
81
 
      if (keyseg->bit_length)
82
 
      {
83
 
        uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
 
                                 keyseg->bit_start, keyseg->bit_length);
85
 
        *key++= bits;
86
 
        length--;
87
 
      }
88
 
      memcpy(key, pos, length);
89
 
      key+= length;
90
 
      continue;
91
 
    }
 
80
    pos= (unsigned char*) record+keyseg->start;
 
81
 
92
82
    if (keyseg->flag & HA_SPACE_PACK)
93
83
    {
94
 
      if (type != HA_KEYTYPE_NUM)
95
 
      {
96
 
        length= cs->cset->lengthsp(cs, (char*) pos, length);
97
 
      }
98
 
      else
99
 
      {
100
 
        uchar *end= pos + length;
101
 
        while (pos < end && pos[0] == ' ')
102
 
          pos++;
103
 
        length=(uint) (end-pos);
104
 
      }
 
84
      length= cs->cset->lengthsp(cs, (char*) pos, length);
 
85
 
105
86
      FIX_LENGTH(cs, pos, length, char_length);
106
87
      store_key_length_inc(key,char_length);
107
88
      memcpy(key, pos, char_length);
110
91
    }
111
92
    if (keyseg->flag & HA_VAR_LENGTH_PART)
112
93
    {
113
 
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
 
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
 
94
      uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
 
95
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
115
96
                        uint2korr(pos));
116
97
      pos+= pack_length;                        /* Skip VARCHAR length */
117
 
      set_if_smaller(length,tmp_length);
 
98
      drizzled::set_if_smaller(length,tmp_length);
118
99
      FIX_LENGTH(cs, pos, length, char_length);
119
100
      store_key_length_inc(key,char_length);
120
101
      memcpy(key, pos, char_length);
123
104
    }
124
105
    else if (keyseg->flag & HA_BLOB_PART)
125
106
    {
126
 
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
 
107
      uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
127
108
      memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
128
 
      set_if_smaller(length,tmp_length);
 
109
      drizzled::set_if_smaller(length,tmp_length);
129
110
      FIX_LENGTH(cs, pos, length, char_length);
130
111
      store_key_length_inc(key,char_length);
131
112
      memcpy(key, pos, char_length);
134
115
    }
135
116
    else if (keyseg->flag & HA_SWAP_KEY)
136
117
    {                                           /* Numerical column */
137
 
#ifdef HAVE_ISNAN
138
 
      if (type == HA_KEYTYPE_FLOAT)
139
 
      {
140
 
        float nr;
141
 
        float4get(nr,pos);
142
 
        if (isnan(nr))
143
 
        {
144
 
          /* Replace NAN with zero */
145
 
          memset(key, 0, length);
146
 
          key+=length;
147
 
          continue;
148
 
        }
149
 
      }
150
 
      else if (type == HA_KEYTYPE_DOUBLE)
 
118
      if (type == drizzled::HA_KEYTYPE_DOUBLE)
151
119
      {
152
120
        double nr;
153
121
        float8get(nr,pos);
158
126
          continue;
159
127
        }
160
128
      }
161
 
#endif
162
129
      pos+=length;
163
130
      while (length--)
164
131
      {
183
150
  SYNOPSIS
184
151
    _mi_pack_key()
185
152
    info                MyISAM handler
186
 
    uint keynr          key number
 
153
    uint32_t keynr              key number
187
154
    key                 Store packed key here
188
155
    old                 Not packed key
189
156
    keypart_map         bitmap of used keyparts
195
162
     last_use_keyseg    Store pointer to the keyseg after the last used one
196
163
*/
197
164
 
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)
 
165
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
 
166
                      drizzled::key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
200
167
{
201
 
  uchar *start_key=key;
 
168
  unsigned char *start_key=key;
202
169
  HA_KEYSEG *keyseg;
203
170
 
204
171
  /* only key prefixes are supported */
207
174
  for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
208
175
       old+= keyseg->length, keyseg++)
209
176
  {
210
 
    enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
211
 
    uint length= keyseg->length;
212
 
    uint char_length;
213
 
    uchar *pos;
214
 
    const CHARSET_INFO * const cs=keyseg->charset;
 
177
    enum drizzled::ha_base_keytype type= (enum drizzled::ha_base_keytype) keyseg->type;
 
178
    uint32_t length= keyseg->length;
 
179
    uint32_t char_length;
 
180
    unsigned char *pos;
 
181
    const drizzled::CHARSET_INFO * const cs=keyseg->charset;
215
182
    keypart_map>>= 1;
216
183
    if (keyseg->null_bit)
217
184
    {
226
193
    pos=old;
227
194
    if (keyseg->flag & HA_SPACE_PACK)
228
195
    {
229
 
      uchar *end=pos+length;
230
 
      if (type == HA_KEYTYPE_NUM)
231
 
      {
232
 
        while (pos < end && pos[0] == ' ')
233
 
          pos++;
234
 
      }
235
 
      else if (type != HA_KEYTYPE_BINARY)
 
196
      unsigned char *end=pos+length;
 
197
 
 
198
      if (type != drizzled::HA_KEYTYPE_BINARY)
236
199
      {
237
200
        while (end > pos && end[-1] == ' ')
238
201
          end--;
247
210
    else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
248
211
    {
249
212
      /* Length of key-part used with mi_rkey() always 2 */
250
 
      uint tmp_length=uint2korr(pos);
 
213
      uint32_t tmp_length=uint2korr(pos);
251
214
      pos+=2;
252
 
      set_if_smaller(length,tmp_length);        /* Safety */
 
215
      drizzled::set_if_smaller(length,tmp_length);      /* Safety */
253
216
      FIX_LENGTH(cs, pos, length, char_length);
254
217
      store_key_length_inc(key,char_length);
255
218
      old+=2;                                   /* Skip length */
297
260
   1   error
298
261
*/
299
262
 
300
 
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
301
 
                                 uchar *record)
 
263
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
 
264
                                 unsigned char *record)
302
265
{
303
 
  register uchar *key;
304
 
  uchar *pos,*key_end;
 
266
  register unsigned char *key;
 
267
  unsigned char *pos,*key_end;
305
268
  register HA_KEYSEG *keyseg;
306
 
  uchar *blob_ptr;
 
269
  unsigned char *blob_ptr;
307
270
 
308
 
  blob_ptr= (uchar*) info->lastkey2;             /* Place to put blob parts */
309
 
  key=(uchar*) info->lastkey;                    /* KEy that was read */
 
271
  blob_ptr= (unsigned char*) info->lastkey2;             /* Place to put blob parts */
 
272
  key=(unsigned char*) info->lastkey;                    /* KEy that was read */
310
273
  key_end=key+info->lastkey_length;
311
274
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
312
275
  {
319
282
      }
320
283
      record[keyseg->null_pos]&= ~keyseg->null_bit;
321
284
    }
322
 
    if (keyseg->type == HA_KEYTYPE_BIT)
323
 
    {
324
 
      uint length= keyseg->length;
325
285
 
326
 
      if (keyseg->bit_length)
327
 
      {
328
 
        uchar bits= *key++;
329
 
        set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
330
 
                     keyseg->bit_length);
331
 
        length--;
332
 
      }
333
 
      else
334
 
      {
335
 
        clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
336
 
                     keyseg->bit_length);
337
 
      }
338
 
      memcpy(record + keyseg->start, key, length);
339
 
      key+= length;
340
 
      continue;
341
 
    }
342
286
    if (keyseg->flag & HA_SPACE_PACK)
343
287
    {
344
 
      uint length;
 
288
      uint32_t length;
345
289
      get_key_length(length,key);
346
290
#ifdef CHECK_KEYS
347
291
      if (length > keyseg->length || key+length > key_end)
348
292
        goto err;
349
293
#endif
350
294
      pos= record+keyseg->start;
351
 
      if (keyseg->type != (int) HA_KEYTYPE_NUM)
352
 
      {
353
 
        memcpy(pos, key, length);
354
 
        keyseg->charset->cset->fill(keyseg->charset,
355
 
                                    (char*) pos + length,
356
 
                                    keyseg->length - length,
357
 
                                    ' ');
358
 
      }
359
 
      else
360
 
      {
361
 
        memset(pos, ' ', keyseg->length-length);
362
 
        memcpy(pos+keyseg->length-length, key, length);
363
 
      }
 
295
 
 
296
      memcpy(pos, key, length);
 
297
      keyseg->charset->cset->fill(keyseg->charset,
 
298
                                  (char*) pos + length,
 
299
                                  keyseg->length - length,
 
300
                                  ' ');
364
301
      key+=length;
365
302
      continue;
366
303
    }
367
304
 
368
305
    if (keyseg->flag & HA_VAR_LENGTH_PART)
369
306
    {
370
 
      uint length;
 
307
      uint32_t length;
371
308
      get_key_length(length,key);
372
309
#ifdef CHECK_KEYS
373
310
      if (length > keyseg->length || key+length > key_end)
375
312
#endif
376
313
      /* Store key length */
377
314
      if (keyseg->bit_start == 1)
378
 
        *(uchar*) (record+keyseg->start)= (uchar) length;
 
315
        *(unsigned char*) (record+keyseg->start)= (unsigned char) length;
379
316
      else
380
317
        int2store(record+keyseg->start, length);
381
318
      /* And key data */
384
321
    }
385
322
    else if (keyseg->flag & HA_BLOB_PART)
386
323
    {
387
 
      uint length;
 
324
      uint32_t length;
388
325
      get_key_length(length,key);
389
326
#ifdef CHECK_KEYS
390
327
      if (length > keyseg->length || key+length > key_end)
404
341
    }
405
342
    else if (keyseg->flag & HA_SWAP_KEY)
406
343
    {
407
 
      uchar *to=  record+keyseg->start+keyseg->length;
408
 
      uchar *end= key+keyseg->length;
 
344
      unsigned char *to=  record+keyseg->start+keyseg->length;
 
345
      unsigned char *end= key+keyseg->length;
409
346
#ifdef CHECK_KEYS
410
347
      if (end > key_end)
411
348
        goto err;
435
372
 
436
373
        /* Here when key reads are used */
437
374
 
438
 
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
 
375
int _mi_read_key_record(MI_INFO *info, drizzled::internal::my_off_t filepos, unsigned char *buf)
439
376
{
440
377
  fast_mi_writeinfo(info);
441
378
  if (filepos != HA_OFFSET_ERROR)
445
382
      if (_mi_put_key_in_record(info,(uint) info->lastinx,buf))
446
383
      {
447
384
        mi_print_error(info->s, HA_ERR_CRASHED);
448
 
        my_errno=HA_ERR_CRASHED;
 
385
        errno=HA_ERR_CRASHED;
449
386
        return -1;
450
387
      }
451
388
      info->update|= HA_STATE_AKTIV; /* We should find a record */
452
389
      return 0;
453
390
    }
454
 
    my_errno=HA_ERR_WRONG_INDEX;
 
391
    errno=HA_ERR_WRONG_INDEX;
455
392
  }
456
393
  return(-1);                           /* Wrong data to read */
457
394
}
464
401
    mi_check_index_cond()
465
402
      info    MyISAM handler
466
403
      keynr   Index we're running a scan on
467
 
      record  Record buffer to use (it is assumed that index check function 
 
404
      record  Record buffer to use (it is assumed that index check function
468
405
              will look for column values there)
469
406
 
470
407
  RETURN
471
 
    -1  Error 
 
408
    -1  Error
472
409
    0   Index condition is not satisfied, continue scanning
473
410
    1   Index condition is satisfied
474
 
    2   Index condition is not satisfied, end the scan. 
 
411
    2   Index condition is not satisfied, end the scan.
475
412
*/
476
413
 
477
 
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
 
414
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
478
415
{
479
416
  if (_mi_put_key_in_record(info, keynr, record))
480
417
  {
481
418
    mi_print_error(info->s, HA_ERR_CRASHED);
482
 
    my_errno=HA_ERR_CRASHED;
 
419
    errno=HA_ERR_CRASHED;
483
420
    return -1;
484
421
  }
485
422
  return info->index_cond_func(info->index_cond_func_arg);
499
436
    less than zero.
500
437
*/
501
438
 
502
 
uint64_t retrieve_auto_increment(MI_INFO *info,const uchar *record)
 
439
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
503
440
{
504
441
  uint64_t value= 0;                    /* Store unsigned values here */
505
442
  int64_t s_value= 0;                   /* Store signed values here */
506
443
  HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
507
 
  const uchar *key= (uchar*) record + keyseg->start;
 
444
  const unsigned char *key= (unsigned char*) record + keyseg->start;
508
445
 
509
446
  switch (keyseg->type) {
510
 
  case HA_KEYTYPE_INT8:
511
 
    s_value= (int64_t) *(char*)key;
512
 
    break;
513
 
  case HA_KEYTYPE_BINARY:
514
 
    value=(uint64_t)  *(uchar*) key;
515
 
    break;
516
 
  case HA_KEYTYPE_SHORT_INT:
517
 
    s_value= (int64_t) sint2korr(key);
518
 
    break;
519
 
  case HA_KEYTYPE_USHORT_INT:
520
 
    value=(uint64_t) uint2korr(key);
521
 
    break;
522
 
  case HA_KEYTYPE_LONG_INT:
 
447
  case drizzled::HA_KEYTYPE_BINARY:
 
448
    value=(uint64_t)  *(unsigned char*) key;
 
449
    break;
 
450
  case drizzled::HA_KEYTYPE_LONG_INT:
523
451
    s_value= (int64_t) sint4korr(key);
524
452
    break;
525
 
  case HA_KEYTYPE_ULONG_INT:
 
453
  case drizzled::HA_KEYTYPE_ULONG_INT:
526
454
    value=(uint64_t) uint4korr(key);
527
455
    break;
528
 
  case HA_KEYTYPE_INT24:
529
 
    s_value= (int64_t) sint3korr(key);
530
 
    break;
531
 
  case HA_KEYTYPE_UINT24:
 
456
  case drizzled::HA_KEYTYPE_UINT24:
532
457
    value=(uint64_t) uint3korr(key);
533
458
    break;
534
 
  case HA_KEYTYPE_FLOAT:                        /* This shouldn't be used */
535
 
  {
536
 
    float f_1;
537
 
    float4get(f_1,key);
538
 
    /* Ignore negative values */
539
 
    value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
540
 
    break;
541
 
  }
542
 
  case HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
 
459
  case drizzled::HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
543
460
  {
544
461
    double f_1;
545
462
    float8get(f_1,key);
547
464
    value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
548
465
    break;
549
466
  }
550
 
  case HA_KEYTYPE_LONGLONG:
 
467
  case drizzled::HA_KEYTYPE_LONGLONG:
551
468
    s_value= sint8korr(key);
552
469
    break;
553
 
  case HA_KEYTYPE_ULONGLONG:
 
470
  case drizzled::HA_KEYTYPE_ULONGLONG:
554
471
    value= uint8korr(key);
555
472
    break;
556
473
  default: