~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_key.c

  • Committer: Monty Taylor
  • Date: 2009-03-18 18:45:23 UTC
  • mto: (950.1.1 mordred)
  • mto: This revision was merged to the branch mainline in revision 943.
  • Revision ID: mordred@inaugust.com-20090318184523-mfbjyj5wkipv4n3b
Moved big tests to big suite. Added make target "make test-big" to allow for easy running of the big tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
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 */
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
}
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: