~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_key.c

  • Committer: Monty Taylor
  • Date: 2008-10-10 23:04:21 UTC
  • mto: (509.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 511.
  • Revision ID: monty@inaugust.com-20081010230421-zohe1eppxievpw8d
RemovedĀ O_NOFOLLOW

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* Functions to handle keys */
17
17
 
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>
22
22
#endif
23
 
#include <math.h>
24
 
#include <cassert>
25
 
 
26
 
using namespace drizzled;
27
 
using namespace std;
28
23
 
29
24
#define CHECK_KEYS                              /* Enable safety checks */
30
25
 
32
27
            do {                                                            \
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);                           \
36
31
            } while(0)
37
32
 
38
33
static int _mi_put_key_in_record(MI_INFO *info,uint32_t keynr,unsigned char *record);
53
48
*/
54
49
 
55
50
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)
 
51
                  const unsigned char *record, my_off_t filepos)
57
52
{
58
53
  unsigned char *pos;
59
54
  unsigned char *start;
62
57
  start=key;
63
58
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
64
59
  {
65
 
    enum drizzled::ha_base_keytype type=(enum drizzled::ha_base_keytype) keyseg->type;
 
60
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
66
61
    uint32_t length=keyseg->length;
67
62
    uint32_t char_length;
68
 
    const drizzled::CHARSET_INFO * const cs=keyseg->charset;
 
63
    const CHARSET_INFO * const cs=keyseg->charset;
69
64
 
70
65
    if (keyseg->null_bit)
71
66
    {
81
76
                  length);
82
77
 
83
78
    pos= (unsigned char*) record+keyseg->start;
84
 
 
 
79
    if (type == HA_KEYTYPE_BIT)
 
80
    {
 
81
      if (keyseg->bit_length)
 
82
      {
 
83
        unsigned char bits= get_rec_bits((unsigned char*) 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
    }
85
92
    if (keyseg->flag & HA_SPACE_PACK)
86
93
    {
87
 
      length= cs->cset->lengthsp(cs, (char*) pos, length);
88
 
 
 
94
      if (type != HA_KEYTYPE_NUM)
 
95
      {
 
96
        length= cs->cset->lengthsp(cs, (char*) pos, length);
 
97
      }
 
98
      else
 
99
      {
 
100
        unsigned char *end= pos + length;
 
101
        while (pos < end && pos[0] == ' ')
 
102
          pos++;
 
103
        length=(uint) (end-pos);
 
104
      }
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);
98
114
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
99
115
                        uint2korr(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);
109
125
    {
110
126
      uint32_t 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);
118
134
    }
119
135
    else if (keyseg->flag & HA_SWAP_KEY)
120
136
    {                                           /* Numerical column */
121
 
      if (type == drizzled::HA_KEYTYPE_DOUBLE)
 
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)
122
151
      {
123
152
        double nr;
124
153
        float8get(nr,pos);
129
158
          continue;
130
159
        }
131
160
      }
 
161
#endif
132
162
      pos+=length;
133
163
      while (length--)
134
164
      {
166
196
*/
167
197
 
168
198
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
                  key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
170
200
{
171
201
  unsigned char *start_key=key;
172
202
  HA_KEYSEG *keyseg;
177
207
  for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
178
208
       old+= keyseg->length, keyseg++)
179
209
  {
180
 
    enum drizzled::ha_base_keytype type= (enum drizzled::ha_base_keytype) keyseg->type;
 
210
    enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
181
211
    uint32_t length= keyseg->length;
182
212
    uint32_t char_length;
183
213
    unsigned char *pos;
184
 
    const drizzled::CHARSET_INFO * const cs=keyseg->charset;
 
214
    const CHARSET_INFO * const cs=keyseg->charset;
185
215
    keypart_map>>= 1;
186
216
    if (keyseg->null_bit)
187
217
    {
197
227
    if (keyseg->flag & HA_SPACE_PACK)
198
228
    {
199
229
      unsigned char *end=pos+length;
200
 
 
201
 
      if (type != drizzled::HA_KEYTYPE_BINARY)
 
230
      if (type == HA_KEYTYPE_NUM)
 
231
      {
 
232
        while (pos < end && pos[0] == ' ')
 
233
          pos++;
 
234
      }
 
235
      else if (type != HA_KEYTYPE_BINARY)
202
236
      {
203
237
        while (end > pos && end[-1] == ' ')
204
238
          end--;
215
249
      /* Length of key-part used with mi_rkey() always 2 */
216
250
      uint32_t tmp_length=uint2korr(pos);
217
251
      pos+=2;
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 */
285
319
      }
286
320
      record[keyseg->null_pos]&= ~keyseg->null_bit;
287
321
    }
 
322
    if (keyseg->type == HA_KEYTYPE_BIT)
 
323
    {
 
324
      uint32_t length= keyseg->length;
288
325
 
 
326
      if (keyseg->bit_length)
 
327
      {
 
328
        unsigned char 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
    }
289
342
    if (keyseg->flag & HA_SPACE_PACK)
290
343
    {
291
344
      uint32_t length;
295
348
        goto err;
296
349
#endif
297
350
      pos= record+keyseg->start;
298
 
 
299
 
      memcpy(pos, key, length);
300
 
      keyseg->charset->cset->fill(keyseg->charset,
301
 
                                  (char*) pos + length,
302
 
                                  keyseg->length - length,
303
 
                                  ' ');
 
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
      }
304
364
      key+=length;
305
365
      continue;
306
366
    }
375
435
 
376
436
        /* Here when key reads are used */
377
437
 
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, unsigned char *buf)
379
439
{
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))
386
446
      {
387
447
        mi_print_error(info->s, HA_ERR_CRASHED);
388
 
        errno=HA_ERR_CRASHED;
 
448
        my_errno=HA_ERR_CRASHED;
389
449
        return -1;
390
450
      }
391
451
      info->update|= HA_STATE_AKTIV; /* We should find a record */
392
452
      return 0;
393
453
    }
394
 
    errno=HA_ERR_WRONG_INDEX;
 
454
    my_errno=HA_ERR_WRONG_INDEX;
395
455
  }
396
456
  return(-1);                           /* Wrong data to read */
397
457
}
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)
409
469
 
410
470
  RETURN
411
 
    -1  Error
 
471
    -1  Error 
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. 
415
475
*/
416
476
 
417
477
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
419
479
  if (_mi_put_key_in_record(info, keynr, record))
420
480
  {
421
481
    mi_print_error(info->s, HA_ERR_CRASHED);
422
 
    errno=HA_ERR_CRASHED;
 
482
    my_errno=HA_ERR_CRASHED;
423
483
    return -1;
424
484
  }
425
485
  return info->index_cond_func(info->index_cond_func_arg);
447
507
  const unsigned char *key= (unsigned char*) record + keyseg->start;
448
508
 
449
509
  switch (keyseg->type) {
450
 
  case drizzled::HA_KEYTYPE_BINARY:
 
510
  case HA_KEYTYPE_INT8:
 
511
    s_value= (int64_t) *(char*)key;
 
512
    break;
 
513
  case HA_KEYTYPE_BINARY:
451
514
    value=(uint64_t)  *(unsigned char*) key;
452
515
    break;
453
 
  case drizzled::HA_KEYTYPE_LONG_INT:
 
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:
454
523
    s_value= (int64_t) sint4korr(key);
455
524
    break;
456
 
  case drizzled::HA_KEYTYPE_ULONG_INT:
 
525
  case HA_KEYTYPE_ULONG_INT:
457
526
    value=(uint64_t) uint4korr(key);
458
527
    break;
459
 
  case drizzled::HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
 
528
  case HA_KEYTYPE_INT24:
 
529
    s_value= (int64_t) sint3korr(key);
 
530
    break;
 
531
  case HA_KEYTYPE_UINT24:
 
532
    value=(uint64_t) uint3korr(key);
 
533
    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 */
460
543
  {
461
544
    double f_1;
462
545
    float8get(f_1,key);
464
547
    value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
465
548
    break;
466
549
  }
467
 
  case drizzled::HA_KEYTYPE_LONGLONG:
 
550
  case HA_KEYTYPE_LONGLONG:
468
551
    s_value= sint8korr(key);
469
552
    break;
470
 
  case drizzled::HA_KEYTYPE_ULONGLONG:
 
553
  case HA_KEYTYPE_ULONGLONG:
471
554
    value= uint8korr(key);
472
555
    break;
473
556
  default: