~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_key.c

  • Committer: Brian Aker
  • Date: 2008-07-14 22:40:46 UTC
  • Revision ID: brian@tangent.org-20080714224046-x183907w9wp1txwv
Removed sql_manager. Ever heard of just setting up the OS to sync when you
want it to?

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;
 
57
  DBUG_ENTER("_mi_make_key");
56
58
 
57
59
  start=key;
58
60
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
59
61
  {
60
62
    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;
 
63
    uint length=keyseg->length;
 
64
    uint char_length;
 
65
    CHARSET_INFO *cs=keyseg->charset;
64
66
 
65
67
    if (keyseg->null_bit)
66
68
    {
72
74
      *key++=1;                                 /* Not NULL */
73
75
    }
74
76
 
75
 
    char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
 
77
    char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
76
78
                  length);
77
79
 
78
 
    pos= (unsigned char*) record+keyseg->start;
 
80
    pos= (uchar*) record+keyseg->start;
79
81
    if (type == HA_KEYTYPE_BIT)
80
82
    {
81
83
      if (keyseg->bit_length)
82
84
      {
83
 
        unsigned char bits= get_rec_bits((unsigned char*) record + keyseg->bit_pos,
 
85
        uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
86
                                 keyseg->bit_start, keyseg->bit_length);
85
87
        *key++= bits;
86
88
        length--;
87
89
      }
88
 
      memcpy(key, pos, length);
 
90
      memcpy((uchar*) key, pos, length);
89
91
      key+= length;
90
92
      continue;
91
93
    }
97
99
      }
98
100
      else
99
101
      {
100
 
        unsigned char *end= pos + length;
 
102
        uchar *end= pos + length;
101
103
        while (pos < end && pos[0] == ' ')
102
104
          pos++;
103
105
        length=(uint) (end-pos);
104
106
      }
105
107
      FIX_LENGTH(cs, pos, length, char_length);
106
108
      store_key_length_inc(key,char_length);
107
 
      memcpy(key, pos, char_length);
 
109
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
108
110
      key+=char_length;
109
111
      continue;
110
112
    }
111
113
    if (keyseg->flag & HA_VAR_LENGTH_PART)
112
114
    {
113
 
      uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
 
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
115
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
 
116
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
115
117
                        uint2korr(pos));
116
118
      pos+= pack_length;                        /* Skip VARCHAR length */
117
119
      set_if_smaller(length,tmp_length);
118
120
      FIX_LENGTH(cs, pos, length, char_length);
119
121
      store_key_length_inc(key,char_length);
120
 
      memcpy(key, pos, char_length);
 
122
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
121
123
      key+= char_length;
122
124
      continue;
123
125
    }
124
126
    else if (keyseg->flag & HA_BLOB_PART)
125
127
    {
126
 
      uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
127
 
      memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
 
128
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
 
129
      memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
128
130
      set_if_smaller(length,tmp_length);
129
131
      FIX_LENGTH(cs, pos, length, char_length);
130
132
      store_key_length_inc(key,char_length);
131
 
      memcpy(key, pos, char_length);
 
133
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
132
134
      key+= char_length;
133
135
      continue;
134
136
    }
142
144
        if (isnan(nr))
143
145
        {
144
146
          /* Replace NAN with zero */
145
 
          memset(key, 0, length);
 
147
          bzero(key,length);
146
148
          key+=length;
147
149
          continue;
148
150
        }
153
155
        float8get(nr,pos);
154
156
        if (isnan(nr))
155
157
        {
156
 
          memset(key, 0, length);
 
158
          bzero(key,length);
157
159
          key+=length;
158
160
          continue;
159
161
        }
167
169
      continue;
168
170
    }
169
171
    FIX_LENGTH(cs, pos, length, char_length);
170
 
    memcpy(key, pos, char_length);
 
172
    memcpy((uchar*) key, pos, char_length);
171
173
    if (length > char_length)
172
174
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
173
175
    key+= length;
174
176
  }
175
177
  _mi_dpointer(info,key,filepos);
176
 
  return((uint) (key-start));           /* Return keylength */
 
178
  DBUG_PRINT("exit",("keynr: %d",keynr));
 
179
  DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length);
 
180
  DBUG_EXECUTE("key",
 
181
               _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
 
182
                             (uint) (key-start)););
 
183
  DBUG_RETURN((uint) (key-start));              /* Return keylength */
177
184
} /* _mi_make_key */
178
185
 
179
186
 
183
190
  SYNOPSIS
184
191
    _mi_pack_key()
185
192
    info                MyISAM handler
186
 
    uint32_t keynr              key number
 
193
    uint keynr          key number
187
194
    key                 Store packed key here
188
195
    old                 Not packed key
189
196
    keypart_map         bitmap of used keyparts
195
202
     last_use_keyseg    Store pointer to the keyseg after the last used one
196
203
*/
197
204
 
198
 
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
 
205
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
199
206
                  key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
200
207
{
201
 
  unsigned char *start_key=key;
 
208
  uchar *start_key=key;
202
209
  HA_KEYSEG *keyseg;
 
210
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
 
211
  DBUG_ENTER("_mi_pack_key");
203
212
 
204
213
  /* only key prefixes are supported */
205
 
  assert(((keypart_map+1) & keypart_map) == 0);
 
214
  DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
206
215
 
207
216
  for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
208
217
       old+= keyseg->length, keyseg++)
209
218
  {
210
219
    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;
 
220
    uint length= keyseg->length;
 
221
    uint char_length;
 
222
    uchar *pos;
 
223
    CHARSET_INFO *cs=keyseg->charset;
215
224
    keypart_map>>= 1;
216
225
    if (keyseg->null_bit)
217
226
    {
222
231
        continue;                                       /* Found NULL */
223
232
      }
224
233
    }
225
 
    char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
 
234
    char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
226
235
    pos=old;
227
236
    if (keyseg->flag & HA_SPACE_PACK)
228
237
    {
229
 
      unsigned char *end=pos+length;
 
238
      uchar *end=pos+length;
230
239
      if (type == HA_KEYTYPE_NUM)
231
240
      {
232
241
        while (pos < end && pos[0] == ' ')
240
249
      length=(uint) (end-pos);
241
250
      FIX_LENGTH(cs, pos, length, char_length);
242
251
      store_key_length_inc(key,char_length);
243
 
      memcpy(key, pos, char_length);
 
252
      memcpy((uchar*) key,pos,(size_t) char_length);
244
253
      key+= char_length;
245
254
      continue;
246
255
    }
247
256
    else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
248
257
    {
249
258
      /* Length of key-part used with mi_rkey() always 2 */
250
 
      uint32_t tmp_length=uint2korr(pos);
 
259
      uint tmp_length=uint2korr(pos);
251
260
      pos+=2;
252
261
      set_if_smaller(length,tmp_length);        /* Safety */
253
262
      FIX_LENGTH(cs, pos, length, char_length);
254
263
      store_key_length_inc(key,char_length);
255
264
      old+=2;                                   /* Skip length */
256
 
      memcpy(key, pos, char_length);
 
265
      memcpy((uchar*) key, pos,(size_t) char_length);
257
266
      key+= char_length;
258
267
      continue;
259
268
    }
265
274
      continue;
266
275
    }
267
276
    FIX_LENGTH(cs, pos, length, char_length);
268
 
    memcpy(key, pos, char_length);
 
277
    memcpy((uchar*) key, pos, char_length);
269
278
    if (length > char_length)
270
279
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
271
280
    key+= length;
273
282
  if (last_used_keyseg)
274
283
    *last_used_keyseg= keyseg;
275
284
 
276
 
  return((uint) (key-start_key));
 
285
  DBUG_RETURN((uint) (key-start_key));
277
286
} /* _mi_pack_key */
278
287
 
279
288
 
297
306
   1   error
298
307
*/
299
308
 
300
 
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
301
 
                                 unsigned char *record)
 
309
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
 
310
                                 uchar *record)
302
311
{
303
 
  register unsigned char *key;
304
 
  unsigned char *pos,*key_end;
 
312
  register uchar *key;
 
313
  uchar *pos,*key_end;
305
314
  register HA_KEYSEG *keyseg;
306
 
  unsigned char *blob_ptr;
 
315
  uchar *blob_ptr;
 
316
  DBUG_ENTER("_mi_put_key_in_record");
307
317
 
308
 
  blob_ptr= (unsigned char*) info->lastkey2;             /* Place to put blob parts */
309
 
  key=(unsigned char*) info->lastkey;                    /* KEy that was read */
 
318
  blob_ptr= (uchar*) info->lastkey2;             /* Place to put blob parts */
 
319
  key=(uchar*) info->lastkey;                    /* KEy that was read */
310
320
  key_end=key+info->lastkey_length;
311
321
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
312
322
  {
321
331
    }
322
332
    if (keyseg->type == HA_KEYTYPE_BIT)
323
333
    {
324
 
      uint32_t length= keyseg->length;
 
334
      uint length= keyseg->length;
325
335
 
326
336
      if (keyseg->bit_length)
327
337
      {
328
 
        unsigned char bits= *key++;
 
338
        uchar bits= *key++;
329
339
        set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
330
340
                     keyseg->bit_length);
331
341
        length--;
335
345
        clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
336
346
                     keyseg->bit_length);
337
347
      }
338
 
      memcpy(record + keyseg->start, key, length);
 
348
      memcpy(record + keyseg->start, (uchar*) key, length);
339
349
      key+= length;
340
350
      continue;
341
351
    }
342
352
    if (keyseg->flag & HA_SPACE_PACK)
343
353
    {
344
 
      uint32_t length;
 
354
      uint length;
345
355
      get_key_length(length,key);
346
356
#ifdef CHECK_KEYS
347
357
      if (length > keyseg->length || key+length > key_end)
350
360
      pos= record+keyseg->start;
351
361
      if (keyseg->type != (int) HA_KEYTYPE_NUM)
352
362
      {
353
 
        memcpy(pos, key, length);
 
363
        memcpy(pos,key,(size_t) length);
354
364
        keyseg->charset->cset->fill(keyseg->charset,
355
365
                                    (char*) pos + length,
356
366
                                    keyseg->length - length,
358
368
      }
359
369
      else
360
370
      {
361
 
        memset(pos, ' ', keyseg->length-length);
362
 
        memcpy(pos+keyseg->length-length, key, length);
 
371
        bfill(pos,keyseg->length-length,' ');
 
372
        memcpy(pos+keyseg->length-length,key,(size_t) length);
363
373
      }
364
374
      key+=length;
365
375
      continue;
367
377
 
368
378
    if (keyseg->flag & HA_VAR_LENGTH_PART)
369
379
    {
370
 
      uint32_t length;
 
380
      uint length;
371
381
      get_key_length(length,key);
372
382
#ifdef CHECK_KEYS
373
383
      if (length > keyseg->length || key+length > key_end)
375
385
#endif
376
386
      /* Store key length */
377
387
      if (keyseg->bit_start == 1)
378
 
        *(unsigned char*) (record+keyseg->start)= (unsigned char) length;
 
388
        *(uchar*) (record+keyseg->start)= (uchar) length;
379
389
      else
380
390
        int2store(record+keyseg->start, length);
381
391
      /* And key data */
382
 
      memcpy(record+keyseg->start + keyseg->bit_start, key, length);
 
392
      memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
383
393
      key+= length;
384
394
    }
385
395
    else if (keyseg->flag & HA_BLOB_PART)
386
396
    {
387
 
      uint32_t length;
 
397
      uint length;
388
398
      get_key_length(length,key);
389
399
#ifdef CHECK_KEYS
390
400
      if (length > keyseg->length || key+length > key_end)
391
401
        goto err;
392
402
#endif
393
403
      memcpy(record+keyseg->start+keyseg->bit_start,
394
 
             &blob_ptr,sizeof(char*));
 
404
             (char*) &blob_ptr,sizeof(char*));
395
405
      memcpy(blob_ptr,key,length);
396
406
      blob_ptr+=length;
397
407
 
404
414
    }
405
415
    else if (keyseg->flag & HA_SWAP_KEY)
406
416
    {
407
 
      unsigned char *to=  record+keyseg->start+keyseg->length;
408
 
      unsigned char *end= key+keyseg->length;
 
417
      uchar *to=  record+keyseg->start+keyseg->length;
 
418
      uchar *end= key+keyseg->length;
409
419
#ifdef CHECK_KEYS
410
420
      if (end > key_end)
411
421
        goto err;
422
432
      if (key+keyseg->length > key_end)
423
433
        goto err;
424
434
#endif
425
 
      memcpy(record+keyseg->start, key, keyseg->length);
 
435
      memcpy(record+keyseg->start,(uchar*) key,
 
436
             (size_t) keyseg->length);
426
437
      key+= keyseg->length;
427
438
    }
428
439
  }
429
 
  return(0);
 
440
  DBUG_RETURN(0);
430
441
 
431
442
err:
432
 
  return(1);                            /* Crashed row */
 
443
  DBUG_RETURN(1);                               /* Crashed row */
433
444
} /* _mi_put_key_in_record */
434
445
 
435
446
 
436
447
        /* Here when key reads are used */
437
448
 
438
 
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
 
449
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
439
450
{
440
451
  fast_mi_writeinfo(info);
441
452
  if (filepos != HA_OFFSET_ERROR)
474
485
    2   Index condition is not satisfied, end the scan. 
475
486
*/
476
487
 
477
 
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
 
488
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
478
489
{
479
490
  if (_mi_put_key_in_record(info, keynr, record))
480
491
  {
499
510
    less than zero.
500
511
*/
501
512
 
502
 
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
 
513
uint64_t retrieve_auto_increment(MI_INFO *info,const uchar *record)
503
514
{
504
515
  uint64_t value= 0;                    /* Store unsigned values here */
505
516
  int64_t s_value= 0;                   /* Store signed values here */
506
517
  HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
507
 
  const unsigned char *key= (unsigned char*) record + keyseg->start;
 
518
  const uchar *key= (uchar*) record + keyseg->start;
508
519
 
509
520
  switch (keyseg->type) {
510
521
  case HA_KEYTYPE_INT8:
511
522
    s_value= (int64_t) *(char*)key;
512
523
    break;
513
524
  case HA_KEYTYPE_BINARY:
514
 
    value=(uint64_t)  *(unsigned char*) key;
 
525
    value=(uint64_t)  *(uchar*) key;
515
526
    break;
516
527
  case HA_KEYTYPE_SHORT_INT:
517
528
    s_value= (int64_t) sint2korr(key);
554
565
    value= uint8korr(key);
555
566
    break;
556
567
  default:
557
 
    assert(0);
 
568
    DBUG_ASSERT(0);
558
569
    value=0;                                    /* Error */
559
570
    break;
560
571
  }