~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_key.c

  • Committer: Jay Pipes
  • Date: 2008-07-17 17:54:00 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717175400-xm2aazihjra8mdzq
Removal of DBUG from libdrizzle/ - Round 2

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* Functions to handle keys */
17
17
 
18
18
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
 
19
#include "m_ctype.h"
20
20
#ifdef HAVE_IEEEFP_H
21
21
#include <ieeefp.h>
22
22
#endif
30
30
              set_if_smaller(char_length,length);                           \
31
31
            } while(0)
32
32
 
33
 
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);
34
34
 
35
35
/*
36
36
  Make a intern key from a record
47
47
    Length of key
48
48
*/
49
49
 
50
 
uint32_t _mi_make_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
51
 
                  const unsigned char *record, 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)
52
52
{
53
 
  unsigned char *pos;
54
 
  unsigned char *start;
 
53
  uchar *pos;
 
54
  uchar *start;
55
55
  register HA_KEYSEG *keyseg;
 
56
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
56
57
 
57
58
  start=key;
58
59
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
59
60
  {
60
61
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
61
 
    uint32_t length=keyseg->length;
62
 
    uint32_t char_length;
63
 
    const CHARSET_INFO * const cs=keyseg->charset;
 
62
    uint length=keyseg->length;
 
63
    uint char_length;
 
64
    CHARSET_INFO *cs=keyseg->charset;
64
65
 
65
66
    if (keyseg->null_bit)
66
67
    {
72
73
      *key++=1;                                 /* Not NULL */
73
74
    }
74
75
 
75
 
    char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
 
76
    char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
76
77
                  length);
77
78
 
78
 
    pos= (unsigned char*) record+keyseg->start;
 
79
    pos= (uchar*) record+keyseg->start;
79
80
    if (type == HA_KEYTYPE_BIT)
80
81
    {
81
82
      if (keyseg->bit_length)
82
83
      {
83
 
        unsigned char bits= get_rec_bits((unsigned char*) record + keyseg->bit_pos,
 
84
        uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
85
                                 keyseg->bit_start, keyseg->bit_length);
85
86
        *key++= bits;
86
87
        length--;
87
88
      }
88
 
      memcpy(key, pos, length);
 
89
      memcpy((uchar*) key, pos, length);
89
90
      key+= length;
90
91
      continue;
91
92
    }
97
98
      }
98
99
      else
99
100
      {
100
 
        unsigned char *end= pos + length;
 
101
        uchar *end= pos + length;
101
102
        while (pos < end && pos[0] == ' ')
102
103
          pos++;
103
104
        length=(uint) (end-pos);
104
105
      }
105
106
      FIX_LENGTH(cs, pos, length, char_length);
106
107
      store_key_length_inc(key,char_length);
107
 
      memcpy(key, pos, char_length);
 
108
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
108
109
      key+=char_length;
109
110
      continue;
110
111
    }
111
112
    if (keyseg->flag & HA_VAR_LENGTH_PART)
112
113
    {
113
 
      uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
 
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
114
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
 
115
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
115
116
                        uint2korr(pos));
116
117
      pos+= pack_length;                        /* Skip VARCHAR length */
117
118
      set_if_smaller(length,tmp_length);
118
119
      FIX_LENGTH(cs, pos, length, char_length);
119
120
      store_key_length_inc(key,char_length);
120
 
      memcpy(key, pos, char_length);
 
121
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
121
122
      key+= char_length;
122
123
      continue;
123
124
    }
124
125
    else if (keyseg->flag & HA_BLOB_PART)
125
126
    {
126
 
      uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
127
 
      memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
 
127
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
 
128
      memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
128
129
      set_if_smaller(length,tmp_length);
129
130
      FIX_LENGTH(cs, pos, length, char_length);
130
131
      store_key_length_inc(key,char_length);
131
 
      memcpy(key, pos, char_length);
 
132
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
132
133
      key+= char_length;
133
134
      continue;
134
135
    }
142
143
        if (isnan(nr))
143
144
        {
144
145
          /* Replace NAN with zero */
145
 
          memset(key, 0, length);
 
146
          bzero(key,length);
146
147
          key+=length;
147
148
          continue;
148
149
        }
153
154
        float8get(nr,pos);
154
155
        if (isnan(nr))
155
156
        {
156
 
          memset(key, 0, length);
 
157
          bzero(key,length);
157
158
          key+=length;
158
159
          continue;
159
160
        }
167
168
      continue;
168
169
    }
169
170
    FIX_LENGTH(cs, pos, length, char_length);
170
 
    memcpy(key, pos, char_length);
 
171
    memcpy((uchar*) key, pos, char_length);
171
172
    if (length > char_length)
172
173
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
173
174
    key+= length;
183
184
  SYNOPSIS
184
185
    _mi_pack_key()
185
186
    info                MyISAM handler
186
 
    uint32_t keynr              key number
 
187
    uint keynr          key number
187
188
    key                 Store packed key here
188
189
    old                 Not packed key
189
190
    keypart_map         bitmap of used keyparts
195
196
     last_use_keyseg    Store pointer to the keyseg after the last used one
196
197
*/
197
198
 
198
 
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
 
199
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
199
200
                  key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
200
201
{
201
 
  unsigned char *start_key=key;
 
202
  uchar *start_key=key;
202
203
  HA_KEYSEG *keyseg;
 
204
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
203
205
 
204
206
  /* only key prefixes are supported */
205
207
  assert(((keypart_map+1) & keypart_map) == 0);
208
210
       old+= keyseg->length, keyseg++)
209
211
  {
210
212
    enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
211
 
    uint32_t length= keyseg->length;
212
 
    uint32_t char_length;
213
 
    unsigned char *pos;
214
 
    const CHARSET_INFO * const cs=keyseg->charset;
 
213
    uint length= keyseg->length;
 
214
    uint char_length;
 
215
    uchar *pos;
 
216
    CHARSET_INFO *cs=keyseg->charset;
215
217
    keypart_map>>= 1;
216
218
    if (keyseg->null_bit)
217
219
    {
222
224
        continue;                                       /* Found NULL */
223
225
      }
224
226
    }
225
 
    char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
 
227
    char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
226
228
    pos=old;
227
229
    if (keyseg->flag & HA_SPACE_PACK)
228
230
    {
229
 
      unsigned char *end=pos+length;
 
231
      uchar *end=pos+length;
230
232
      if (type == HA_KEYTYPE_NUM)
231
233
      {
232
234
        while (pos < end && pos[0] == ' ')
240
242
      length=(uint) (end-pos);
241
243
      FIX_LENGTH(cs, pos, length, char_length);
242
244
      store_key_length_inc(key,char_length);
243
 
      memcpy(key, pos, char_length);
 
245
      memcpy((uchar*) key,pos,(size_t) char_length);
244
246
      key+= char_length;
245
247
      continue;
246
248
    }
247
249
    else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
248
250
    {
249
251
      /* Length of key-part used with mi_rkey() always 2 */
250
 
      uint32_t tmp_length=uint2korr(pos);
 
252
      uint tmp_length=uint2korr(pos);
251
253
      pos+=2;
252
254
      set_if_smaller(length,tmp_length);        /* Safety */
253
255
      FIX_LENGTH(cs, pos, length, char_length);
254
256
      store_key_length_inc(key,char_length);
255
257
      old+=2;                                   /* Skip length */
256
 
      memcpy(key, pos, char_length);
 
258
      memcpy((uchar*) key, pos,(size_t) char_length);
257
259
      key+= char_length;
258
260
      continue;
259
261
    }
265
267
      continue;
266
268
    }
267
269
    FIX_LENGTH(cs, pos, length, char_length);
268
 
    memcpy(key, pos, char_length);
 
270
    memcpy((uchar*) key, pos, char_length);
269
271
    if (length > char_length)
270
272
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
271
273
    key+= length;
297
299
   1   error
298
300
*/
299
301
 
300
 
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
301
 
                                 unsigned char *record)
 
302
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
 
303
                                 uchar *record)
302
304
{
303
 
  register unsigned char *key;
304
 
  unsigned char *pos,*key_end;
 
305
  register uchar *key;
 
306
  uchar *pos,*key_end;
305
307
  register HA_KEYSEG *keyseg;
306
 
  unsigned char *blob_ptr;
 
308
  uchar *blob_ptr;
307
309
 
308
 
  blob_ptr= (unsigned char*) info->lastkey2;             /* Place to put blob parts */
309
 
  key=(unsigned char*) info->lastkey;                    /* KEy that was read */
 
310
  blob_ptr= (uchar*) info->lastkey2;             /* Place to put blob parts */
 
311
  key=(uchar*) info->lastkey;                    /* KEy that was read */
310
312
  key_end=key+info->lastkey_length;
311
313
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
312
314
  {
321
323
    }
322
324
    if (keyseg->type == HA_KEYTYPE_BIT)
323
325
    {
324
 
      uint32_t length= keyseg->length;
 
326
      uint length= keyseg->length;
325
327
 
326
328
      if (keyseg->bit_length)
327
329
      {
328
 
        unsigned char bits= *key++;
 
330
        uchar bits= *key++;
329
331
        set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
330
332
                     keyseg->bit_length);
331
333
        length--;
335
337
        clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
336
338
                     keyseg->bit_length);
337
339
      }
338
 
      memcpy(record + keyseg->start, key, length);
 
340
      memcpy(record + keyseg->start, (uchar*) key, length);
339
341
      key+= length;
340
342
      continue;
341
343
    }
342
344
    if (keyseg->flag & HA_SPACE_PACK)
343
345
    {
344
 
      uint32_t length;
 
346
      uint length;
345
347
      get_key_length(length,key);
346
348
#ifdef CHECK_KEYS
347
349
      if (length > keyseg->length || key+length > key_end)
350
352
      pos= record+keyseg->start;
351
353
      if (keyseg->type != (int) HA_KEYTYPE_NUM)
352
354
      {
353
 
        memcpy(pos, key, length);
 
355
        memcpy(pos,key,(size_t) length);
354
356
        keyseg->charset->cset->fill(keyseg->charset,
355
357
                                    (char*) pos + length,
356
358
                                    keyseg->length - length,
358
360
      }
359
361
      else
360
362
      {
361
 
        memset(pos, ' ', keyseg->length-length);
362
 
        memcpy(pos+keyseg->length-length, key, length);
 
363
        bfill(pos,keyseg->length-length,' ');
 
364
        memcpy(pos+keyseg->length-length,key,(size_t) length);
363
365
      }
364
366
      key+=length;
365
367
      continue;
367
369
 
368
370
    if (keyseg->flag & HA_VAR_LENGTH_PART)
369
371
    {
370
 
      uint32_t length;
 
372
      uint length;
371
373
      get_key_length(length,key);
372
374
#ifdef CHECK_KEYS
373
375
      if (length > keyseg->length || key+length > key_end)
375
377
#endif
376
378
      /* Store key length */
377
379
      if (keyseg->bit_start == 1)
378
 
        *(unsigned char*) (record+keyseg->start)= (unsigned char) length;
 
380
        *(uchar*) (record+keyseg->start)= (uchar) length;
379
381
      else
380
382
        int2store(record+keyseg->start, length);
381
383
      /* And key data */
382
 
      memcpy(record+keyseg->start + keyseg->bit_start, key, length);
 
384
      memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
383
385
      key+= length;
384
386
    }
385
387
    else if (keyseg->flag & HA_BLOB_PART)
386
388
    {
387
 
      uint32_t length;
 
389
      uint length;
388
390
      get_key_length(length,key);
389
391
#ifdef CHECK_KEYS
390
392
      if (length > keyseg->length || key+length > key_end)
391
393
        goto err;
392
394
#endif
393
395
      memcpy(record+keyseg->start+keyseg->bit_start,
394
 
             &blob_ptr,sizeof(char*));
 
396
             (char*) &blob_ptr,sizeof(char*));
395
397
      memcpy(blob_ptr,key,length);
396
398
      blob_ptr+=length;
397
399
 
404
406
    }
405
407
    else if (keyseg->flag & HA_SWAP_KEY)
406
408
    {
407
 
      unsigned char *to=  record+keyseg->start+keyseg->length;
408
 
      unsigned char *end= key+keyseg->length;
 
409
      uchar *to=  record+keyseg->start+keyseg->length;
 
410
      uchar *end= key+keyseg->length;
409
411
#ifdef CHECK_KEYS
410
412
      if (end > key_end)
411
413
        goto err;
422
424
      if (key+keyseg->length > key_end)
423
425
        goto err;
424
426
#endif
425
 
      memcpy(record+keyseg->start, key, keyseg->length);
 
427
      memcpy(record+keyseg->start,(uchar*) key,
 
428
             (size_t) keyseg->length);
426
429
      key+= keyseg->length;
427
430
    }
428
431
  }
435
438
 
436
439
        /* Here when key reads are used */
437
440
 
438
 
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
 
441
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
439
442
{
440
443
  fast_mi_writeinfo(info);
441
444
  if (filepos != HA_OFFSET_ERROR)
474
477
    2   Index condition is not satisfied, end the scan. 
475
478
*/
476
479
 
477
 
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
 
480
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
478
481
{
479
482
  if (_mi_put_key_in_record(info, keynr, record))
480
483
  {
499
502
    less than zero.
500
503
*/
501
504
 
502
 
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
 
505
uint64_t retrieve_auto_increment(MI_INFO *info,const uchar *record)
503
506
{
504
507
  uint64_t value= 0;                    /* Store unsigned values here */
505
508
  int64_t s_value= 0;                   /* Store signed values here */
506
509
  HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
507
 
  const unsigned char *key= (unsigned char*) record + keyseg->start;
 
510
  const uchar *key= (uchar*) record + keyseg->start;
508
511
 
509
512
  switch (keyseg->type) {
510
513
  case HA_KEYTYPE_INT8:
511
514
    s_value= (int64_t) *(char*)key;
512
515
    break;
513
516
  case HA_KEYTYPE_BINARY:
514
 
    value=(uint64_t)  *(unsigned char*) key;
 
517
    value=(uint64_t)  *(uchar*) key;
515
518
    break;
516
519
  case HA_KEYTYPE_SHORT_INT:
517
520
    s_value= (int64_t) sint2korr(key);