~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_key.c

Put errmsg.c in sql-common since it can be built only once and used twice.
Put client.c and net_serv.c in libmysql so that we can only have one
link_sources section. 
Got rid of just about all copying and other weirdness, other than some stuff
in client and client.c/net_serv.c, which need to be reworked.

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
#include "sp_defs.h"
20
21
#ifdef HAVE_IEEEFP_H
21
22
#include <ieeefp.h>
22
23
#endif
30
31
              set_if_smaller(char_length,length);                           \
31
32
            } while(0)
32
33
 
33
 
static int _mi_put_key_in_record(MI_INFO *info,uint32_t keynr,unsigned char *record);
 
34
static int _mi_put_key_in_record(MI_INFO *info,uint keynr,uchar *record);
34
35
 
35
36
/*
36
37
  Make a intern key from a record
47
48
    Length of key
48
49
*/
49
50
 
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)
 
51
uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
 
52
                  const uchar *record, my_off_t filepos)
52
53
{
53
 
  unsigned char *pos;
54
 
  unsigned char *start;
 
54
  uchar *pos;
 
55
  uchar *start;
55
56
  register HA_KEYSEG *keyseg;
 
57
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
 
58
  DBUG_ENTER("_mi_make_key");
 
59
 
 
60
  if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
 
61
  {
 
62
    /*
 
63
      TODO: nulls processing
 
64
    */
 
65
#ifdef HAVE_SPATIAL
 
66
    DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos));
 
67
#else
 
68
    DBUG_ASSERT(0); /* mi_open should check that this never happens*/
 
69
#endif
 
70
  }
56
71
 
57
72
  start=key;
58
73
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
59
74
  {
60
75
    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;
 
76
    uint length=keyseg->length;
 
77
    uint char_length;
 
78
    CHARSET_INFO *cs=keyseg->charset;
64
79
 
65
80
    if (keyseg->null_bit)
66
81
    {
72
87
      *key++=1;                                 /* Not NULL */
73
88
    }
74
89
 
75
 
    char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
 
90
    char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
76
91
                  length);
77
92
 
78
 
    pos= (unsigned char*) record+keyseg->start;
 
93
    pos= (uchar*) record+keyseg->start;
79
94
    if (type == HA_KEYTYPE_BIT)
80
95
    {
81
96
      if (keyseg->bit_length)
82
97
      {
83
 
        unsigned char bits= get_rec_bits((unsigned char*) record + keyseg->bit_pos,
 
98
        uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
84
99
                                 keyseg->bit_start, keyseg->bit_length);
85
100
        *key++= bits;
86
101
        length--;
87
102
      }
88
 
      memcpy(key, pos, length);
 
103
      memcpy((uchar*) key, pos, length);
89
104
      key+= length;
90
105
      continue;
91
106
    }
97
112
      }
98
113
      else
99
114
      {
100
 
        unsigned char *end= pos + length;
 
115
        uchar *end= pos + length;
101
116
        while (pos < end && pos[0] == ' ')
102
117
          pos++;
103
118
        length=(uint) (end-pos);
104
119
      }
105
120
      FIX_LENGTH(cs, pos, length, char_length);
106
121
      store_key_length_inc(key,char_length);
107
 
      memcpy(key, pos, char_length);
 
122
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
108
123
      key+=char_length;
109
124
      continue;
110
125
    }
111
126
    if (keyseg->flag & HA_VAR_LENGTH_PART)
112
127
    {
113
 
      uint32_t pack_length= (keyseg->bit_start == 1 ? 1 : 2);
114
 
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
128
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
 
129
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
115
130
                        uint2korr(pos));
116
131
      pos+= pack_length;                        /* Skip VARCHAR length */
117
132
      set_if_smaller(length,tmp_length);
118
133
      FIX_LENGTH(cs, pos, length, char_length);
119
134
      store_key_length_inc(key,char_length);
120
 
      memcpy(key, pos, char_length);
 
135
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
121
136
      key+= char_length;
122
137
      continue;
123
138
    }
124
139
    else if (keyseg->flag & HA_BLOB_PART)
125
140
    {
126
 
      uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
127
 
      memcpy(&pos, pos+keyseg->bit_start, sizeof(char*));
 
141
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
 
142
      memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
128
143
      set_if_smaller(length,tmp_length);
129
144
      FIX_LENGTH(cs, pos, length, char_length);
130
145
      store_key_length_inc(key,char_length);
131
 
      memcpy(key, pos, char_length);
 
146
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
132
147
      key+= char_length;
133
148
      continue;
134
149
    }
142
157
        if (isnan(nr))
143
158
        {
144
159
          /* Replace NAN with zero */
145
 
          memset(key, 0, length);
 
160
          bzero(key,length);
146
161
          key+=length;
147
162
          continue;
148
163
        }
153
168
        float8get(nr,pos);
154
169
        if (isnan(nr))
155
170
        {
156
 
          memset(key, 0, length);
 
171
          bzero(key,length);
157
172
          key+=length;
158
173
          continue;
159
174
        }
167
182
      continue;
168
183
    }
169
184
    FIX_LENGTH(cs, pos, length, char_length);
170
 
    memcpy(key, pos, char_length);
 
185
    memcpy((uchar*) key, pos, char_length);
171
186
    if (length > char_length)
172
187
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
173
188
    key+= length;
174
189
  }
175
190
  _mi_dpointer(info,key,filepos);
176
 
  return((uint) (key-start));           /* Return keylength */
 
191
  DBUG_PRINT("exit",("keynr: %d",keynr));
 
192
  DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length);
 
193
  DBUG_EXECUTE("key",
 
194
               _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
 
195
                             (uint) (key-start)););
 
196
  DBUG_RETURN((uint) (key-start));              /* Return keylength */
177
197
} /* _mi_make_key */
178
198
 
179
199
 
183
203
  SYNOPSIS
184
204
    _mi_pack_key()
185
205
    info                MyISAM handler
186
 
    uint32_t keynr              key number
 
206
    uint keynr          key number
187
207
    key                 Store packed key here
188
208
    old                 Not packed key
189
209
    keypart_map         bitmap of used keyparts
195
215
     last_use_keyseg    Store pointer to the keyseg after the last used one
196
216
*/
197
217
 
198
 
uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key, unsigned char *old,
 
218
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
199
219
                  key_part_map keypart_map, HA_KEYSEG **last_used_keyseg)
200
220
{
201
 
  unsigned char *start_key=key;
 
221
  uchar *start_key=key;
202
222
  HA_KEYSEG *keyseg;
 
223
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
 
224
  DBUG_ENTER("_mi_pack_key");
 
225
 
 
226
  /* "one part" rtree key is 2*SPDIMS part key in MyISAM */
 
227
  if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
 
228
    keypart_map= (((key_part_map)1) << (2*SPDIMS)) - 1;
203
229
 
204
230
  /* only key prefixes are supported */
205
 
  assert(((keypart_map+1) & keypart_map) == 0);
 
231
  DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
206
232
 
207
233
  for (keyseg= info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
208
234
       old+= keyseg->length, keyseg++)
209
235
  {
210
236
    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;
 
237
    uint length= keyseg->length;
 
238
    uint char_length;
 
239
    uchar *pos;
 
240
    CHARSET_INFO *cs=keyseg->charset;
215
241
    keypart_map>>= 1;
216
242
    if (keyseg->null_bit)
217
243
    {
222
248
        continue;                                       /* Found NULL */
223
249
      }
224
250
    }
225
 
    char_length= (cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
 
251
    char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
226
252
    pos=old;
227
253
    if (keyseg->flag & HA_SPACE_PACK)
228
254
    {
229
 
      unsigned char *end=pos+length;
 
255
      uchar *end=pos+length;
230
256
      if (type == HA_KEYTYPE_NUM)
231
257
      {
232
258
        while (pos < end && pos[0] == ' ')
240
266
      length=(uint) (end-pos);
241
267
      FIX_LENGTH(cs, pos, length, char_length);
242
268
      store_key_length_inc(key,char_length);
243
 
      memcpy(key, pos, char_length);
 
269
      memcpy((uchar*) key,pos,(size_t) char_length);
244
270
      key+= char_length;
245
271
      continue;
246
272
    }
247
273
    else if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
248
274
    {
249
275
      /* Length of key-part used with mi_rkey() always 2 */
250
 
      uint32_t tmp_length=uint2korr(pos);
 
276
      uint tmp_length=uint2korr(pos);
251
277
      pos+=2;
252
278
      set_if_smaller(length,tmp_length);        /* Safety */
253
279
      FIX_LENGTH(cs, pos, length, char_length);
254
280
      store_key_length_inc(key,char_length);
255
281
      old+=2;                                   /* Skip length */
256
 
      memcpy(key, pos, char_length);
 
282
      memcpy((uchar*) key, pos,(size_t) char_length);
257
283
      key+= char_length;
258
284
      continue;
259
285
    }
265
291
      continue;
266
292
    }
267
293
    FIX_LENGTH(cs, pos, length, char_length);
268
 
    memcpy(key, pos, char_length);
 
294
    memcpy((uchar*) key, pos, char_length);
269
295
    if (length > char_length)
270
296
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
271
297
    key+= length;
273
299
  if (last_used_keyseg)
274
300
    *last_used_keyseg= keyseg;
275
301
 
276
 
  return((uint) (key-start_key));
 
302
  DBUG_RETURN((uint) (key-start_key));
277
303
} /* _mi_pack_key */
278
304
 
279
305
 
297
323
   1   error
298
324
*/
299
325
 
300
 
static int _mi_put_key_in_record(register MI_INFO *info, uint32_t keynr,
301
 
                                 unsigned char *record)
 
326
static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
 
327
                                 uchar *record)
302
328
{
303
 
  register unsigned char *key;
304
 
  unsigned char *pos,*key_end;
 
329
  register uchar *key;
 
330
  uchar *pos,*key_end;
305
331
  register HA_KEYSEG *keyseg;
306
 
  unsigned char *blob_ptr;
 
332
  uchar *blob_ptr;
 
333
  DBUG_ENTER("_mi_put_key_in_record");
307
334
 
308
 
  blob_ptr= (unsigned char*) info->lastkey2;             /* Place to put blob parts */
309
 
  key=(unsigned char*) info->lastkey;                    /* KEy that was read */
 
335
  blob_ptr= (uchar*) info->lastkey2;             /* Place to put blob parts */
 
336
  key=(uchar*) info->lastkey;                    /* KEy that was read */
310
337
  key_end=key+info->lastkey_length;
311
338
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
312
339
  {
321
348
    }
322
349
    if (keyseg->type == HA_KEYTYPE_BIT)
323
350
    {
324
 
      uint32_t length= keyseg->length;
 
351
      uint length= keyseg->length;
325
352
 
326
353
      if (keyseg->bit_length)
327
354
      {
328
 
        unsigned char bits= *key++;
 
355
        uchar bits= *key++;
329
356
        set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
330
357
                     keyseg->bit_length);
331
358
        length--;
335
362
        clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
336
363
                     keyseg->bit_length);
337
364
      }
338
 
      memcpy(record + keyseg->start, key, length);
 
365
      memcpy(record + keyseg->start, (uchar*) key, length);
339
366
      key+= length;
340
367
      continue;
341
368
    }
342
369
    if (keyseg->flag & HA_SPACE_PACK)
343
370
    {
344
 
      uint32_t length;
 
371
      uint length;
345
372
      get_key_length(length,key);
346
373
#ifdef CHECK_KEYS
347
374
      if (length > keyseg->length || key+length > key_end)
350
377
      pos= record+keyseg->start;
351
378
      if (keyseg->type != (int) HA_KEYTYPE_NUM)
352
379
      {
353
 
        memcpy(pos, key, length);
 
380
        memcpy(pos,key,(size_t) length);
354
381
        keyseg->charset->cset->fill(keyseg->charset,
355
382
                                    (char*) pos + length,
356
383
                                    keyseg->length - length,
358
385
      }
359
386
      else
360
387
      {
361
 
        memset(pos, ' ', keyseg->length-length);
362
 
        memcpy(pos+keyseg->length-length, key, length);
 
388
        bfill(pos,keyseg->length-length,' ');
 
389
        memcpy(pos+keyseg->length-length,key,(size_t) length);
363
390
      }
364
391
      key+=length;
365
392
      continue;
367
394
 
368
395
    if (keyseg->flag & HA_VAR_LENGTH_PART)
369
396
    {
370
 
      uint32_t length;
 
397
      uint length;
371
398
      get_key_length(length,key);
372
399
#ifdef CHECK_KEYS
373
400
      if (length > keyseg->length || key+length > key_end)
375
402
#endif
376
403
      /* Store key length */
377
404
      if (keyseg->bit_start == 1)
378
 
        *(unsigned char*) (record+keyseg->start)= (unsigned char) length;
 
405
        *(uchar*) (record+keyseg->start)= (uchar) length;
379
406
      else
380
407
        int2store(record+keyseg->start, length);
381
408
      /* And key data */
382
 
      memcpy(record+keyseg->start + keyseg->bit_start, key, length);
 
409
      memcpy(record+keyseg->start + keyseg->bit_start, (uchar*) key, length);
383
410
      key+= length;
384
411
    }
385
412
    else if (keyseg->flag & HA_BLOB_PART)
386
413
    {
387
 
      uint32_t length;
 
414
      uint length;
388
415
      get_key_length(length,key);
389
416
#ifdef CHECK_KEYS
390
417
      if (length > keyseg->length || key+length > key_end)
391
418
        goto err;
392
419
#endif
393
420
      memcpy(record+keyseg->start+keyseg->bit_start,
394
 
             &blob_ptr,sizeof(char*));
 
421
             (char*) &blob_ptr,sizeof(char*));
395
422
      memcpy(blob_ptr,key,length);
396
423
      blob_ptr+=length;
397
424
 
404
431
    }
405
432
    else if (keyseg->flag & HA_SWAP_KEY)
406
433
    {
407
 
      unsigned char *to=  record+keyseg->start+keyseg->length;
408
 
      unsigned char *end= key+keyseg->length;
 
434
      uchar *to=  record+keyseg->start+keyseg->length;
 
435
      uchar *end= key+keyseg->length;
409
436
#ifdef CHECK_KEYS
410
437
      if (end > key_end)
411
438
        goto err;
422
449
      if (key+keyseg->length > key_end)
423
450
        goto err;
424
451
#endif
425
 
      memcpy(record+keyseg->start, key, keyseg->length);
 
452
      memcpy(record+keyseg->start,(uchar*) key,
 
453
             (size_t) keyseg->length);
426
454
      key+= keyseg->length;
427
455
    }
428
456
  }
429
 
  return(0);
 
457
  DBUG_RETURN(0);
430
458
 
431
459
err:
432
 
  return(1);                            /* Crashed row */
 
460
  DBUG_RETURN(1);                               /* Crashed row */
433
461
} /* _mi_put_key_in_record */
434
462
 
435
463
 
436
464
        /* Here when key reads are used */
437
465
 
438
 
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
 
466
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf)
439
467
{
440
468
  fast_mi_writeinfo(info);
441
469
  if (filepos != HA_OFFSET_ERROR)
474
502
    2   Index condition is not satisfied, end the scan. 
475
503
*/
476
504
 
477
 
int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record)
 
505
int mi_check_index_cond(register MI_INFO *info, uint keynr, uchar *record)
478
506
{
479
507
  if (_mi_put_key_in_record(info, keynr, record))
480
508
  {
499
527
    less than zero.
500
528
*/
501
529
 
502
 
uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record)
 
530
ulonglong retrieve_auto_increment(MI_INFO *info,const uchar *record)
503
531
{
504
 
  uint64_t value= 0;                    /* Store unsigned values here */
505
 
  int64_t s_value= 0;                   /* Store signed values here */
 
532
  ulonglong value= 0;                   /* Store unsigned values here */
 
533
  longlong s_value= 0;                  /* Store signed values here */
506
534
  HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
507
 
  const unsigned char *key= (unsigned char*) record + keyseg->start;
 
535
  const uchar *key= (uchar*) record + keyseg->start;
508
536
 
509
537
  switch (keyseg->type) {
510
538
  case HA_KEYTYPE_INT8:
511
 
    s_value= (int64_t) *(char*)key;
 
539
    s_value= (longlong) *(char*)key;
512
540
    break;
513
541
  case HA_KEYTYPE_BINARY:
514
 
    value=(uint64_t)  *(unsigned char*) key;
 
542
    value=(ulonglong)  *(uchar*) key;
515
543
    break;
516
544
  case HA_KEYTYPE_SHORT_INT:
517
 
    s_value= (int64_t) sint2korr(key);
 
545
    s_value= (longlong) sint2korr(key);
518
546
    break;
519
547
  case HA_KEYTYPE_USHORT_INT:
520
 
    value=(uint64_t) uint2korr(key);
 
548
    value=(ulonglong) uint2korr(key);
521
549
    break;
522
550
  case HA_KEYTYPE_LONG_INT:
523
 
    s_value= (int64_t) sint4korr(key);
 
551
    s_value= (longlong) sint4korr(key);
524
552
    break;
525
553
  case HA_KEYTYPE_ULONG_INT:
526
 
    value=(uint64_t) uint4korr(key);
 
554
    value=(ulonglong) uint4korr(key);
527
555
    break;
528
556
  case HA_KEYTYPE_INT24:
529
 
    s_value= (int64_t) sint3korr(key);
 
557
    s_value= (longlong) sint3korr(key);
530
558
    break;
531
559
  case HA_KEYTYPE_UINT24:
532
 
    value=(uint64_t) uint3korr(key);
 
560
    value=(ulonglong) uint3korr(key);
533
561
    break;
534
562
  case HA_KEYTYPE_FLOAT:                        /* This shouldn't be used */
535
563
  {
536
564
    float f_1;
537
565
    float4get(f_1,key);
538
566
    /* Ignore negative values */
539
 
    value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
 
567
    value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
540
568
    break;
541
569
  }
542
570
  case HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
544
572
    double f_1;
545
573
    float8get(f_1,key);
546
574
    /* Ignore negative values */
547
 
    value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
 
575
    value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
548
576
    break;
549
577
  }
550
578
  case HA_KEYTYPE_LONGLONG:
554
582
    value= uint8korr(key);
555
583
    break;
556
584
  default:
557
 
    assert(0);
 
585
    DBUG_ASSERT(0);
558
586
    value=0;                                    /* Error */
559
587
    break;
560
588
  }
564
592
    and if s_value == 0 then value will contain either s_value or the
565
593
    correct value.
566
594
  */
567
 
  return (s_value > 0) ? (uint64_t) s_value : value;
 
595
  return (s_value > 0) ? (ulonglong) s_value : value;
568
596
}