~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/varstring.cc

  • Committer: Brian Aker
  • Date: 2009-11-12 16:13:04 UTC
  • mfrom: (1211.1.7 staging)
  • Revision ID: brian@gaz-20091112161304-opamiauv36fg0n6u
Rollup of Brian, Padraig, and Stewart patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include "config.h"
 
22
#include <drizzled/server_includes.h>
23
23
#include <drizzled/field/varstring.h>
24
24
#include <drizzled/table.h>
25
25
#include <drizzled/session.h>
26
 
#include "plugin/myisam/myisam.h"
27
26
 
28
27
#include <string>
29
28
 
30
29
using namespace std;
31
30
 
32
 
namespace drizzled
33
 
{
34
 
 
35
31
/****************************************************************************
36
32
  VARCHAR type
37
33
  Data in field->ptr is stored as:
56
52
                                 unsigned char *null_ptr_arg,
57
53
                                 unsigned char null_bit_arg,
58
54
                                 const char *field_name_arg,
59
 
                                 const CHARSET_INFO * const cs) :
60
 
  Field_str(ptr_arg,
61
 
            len_arg,
62
 
            null_ptr_arg,
63
 
            null_bit_arg,
64
 
            field_name_arg, cs),
65
 
length_bytes(length_bytes_arg)
 
55
                                 TableShare *share,
 
56
                                 const CHARSET_INFO * const cs)
 
57
  :Field_str(ptr_arg,
 
58
             len_arg,
 
59
             null_ptr_arg,
 
60
             null_bit_arg,
 
61
             field_name_arg, cs),
 
62
   length_bytes(length_bytes_arg)
66
63
{
 
64
  share->varchar_fields++;
67
65
}
68
66
 
69
67
Field_varstring::Field_varstring(uint32_t len_arg,
70
68
                                 bool maybe_null_arg,
71
69
                                 const char *field_name_arg,
72
 
                                 const CHARSET_INFO * const cs) :
73
 
  Field_str((unsigned char*) 0,
74
 
            len_arg,
75
 
            maybe_null_arg ? (unsigned char*) "": 0,
76
 
            0,
77
 
            field_name_arg,
78
 
            cs),
79
 
  length_bytes(len_arg < 256 ? 1 :2)
80
 
{
 
70
                                 TableShare *share,
 
71
                                 const CHARSET_INFO * const cs)
 
72
  :Field_str((unsigned char*) 0,
 
73
             len_arg,
 
74
             maybe_null_arg ? (unsigned char*) "": 0,
 
75
             0,
 
76
             field_name_arg,
 
77
             cs),
 
78
   length_bytes(len_arg < 256 ? 1 :2)
 
79
{
 
80
  share->varchar_fields++;
 
81
}
 
82
 
 
83
/**
 
84
   Save the field metadata for varstring fields.
 
85
 
 
86
   Saves the field length in the first byte. Note: may consume
 
87
   2 bytes. Caller must ensure second byte is contiguous with
 
88
   first byte (e.g. array index 0,1).
 
89
 
 
90
   @param   metadata_ptr   First byte of field metadata
 
91
 
 
92
   @returns number of bytes written to metadata_ptr
 
93
*/
 
94
int Field_varstring::do_save_field_metadata(unsigned char *metadata_ptr)
 
95
{
 
96
  assert(field_length <= 65535);
 
97
  int2store(metadata_ptr, field_length);
 
98
  return 2;
81
99
}
82
100
 
83
101
int Field_varstring::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
116
134
  char buff[64];
117
135
  uint32_t  length;
118
136
  length= (uint32_t) (field_charset->cset->int64_t10_to_str)(field_charset,
119
 
                                                             buff,
120
 
                                                             sizeof(buff),
121
 
                                                             (unsigned_val ? 10: -10),
122
 
                                                             nr);
 
137
                                                          buff,
 
138
                                                          sizeof(buff),
 
139
                                                          (unsigned_val ? 10:
 
140
                                                           -10),
 
141
                                                           nr);
123
142
  return Field_varstring::store(buff, length, field_charset);
124
143
}
125
144
 
165
184
}
166
185
 
167
186
 
168
 
type::Decimal *Field_varstring::val_decimal(type::Decimal *decimal_value)
 
187
my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
169
188
{
170
189
  uint32_t length;
171
190
 
173
192
 
174
193
  length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
175
194
 
176
 
  decimal_value->store(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length, charset());
177
 
 
 
195
  str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
 
196
                 charset(), decimal_value);
178
197
  return decimal_value;
179
198
}
180
199
 
219
238
  uint32_t local_char_length= max_key_length / field_charset->mbmaxlen;
220
239
 
221
240
  local_char_length= my_charpos(field_charset, ptr + length_bytes,
222
 
                                ptr + length_bytes + length, local_char_length);
 
241
                          ptr + length_bytes + length, local_char_length);
223
242
  set_if_smaller(length, local_char_length);
224
243
  return field_charset->coll->strnncollsp(field_charset,
225
244
                                          ptr + length_bytes,
264
283
  }
265
284
 
266
285
  tot_length= my_strnxfrm(field_charset,
267
 
                          to, length, ptr + length_bytes,
268
 
                          tot_length);
 
286
                          to, length, ptr + length_bytes,
 
287
                          tot_length);
269
288
  assert(tot_length == length);
270
289
}
271
290
 
295
314
}
296
315
 
297
316
 
 
317
uint32_t Field_varstring::data_length()
 
318
{
 
319
  return length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
 
320
}
 
321
 
298
322
uint32_t Field_varstring::used_length()
299
323
{
300
324
  return length_bytes == 1 ? 1 + (uint32_t) (unsigned char) *ptr : 2 + uint2korr(ptr);
326
350
}
327
351
 
328
352
 
 
353
unsigned char *
 
354
Field_varstring::pack_key(unsigned char *to, const unsigned char *key, uint32_t max_length,
 
355
                          bool )
 
356
{
 
357
  uint32_t length=  length_bytes == 1 ? (uint32_t) *key : uint2korr(key);
 
358
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
 
359
                     max_length/field_charset->mbmaxlen : max_length);
 
360
  key+= length_bytes;
 
361
  if (length > local_char_length)
 
362
  {
 
363
    local_char_length= my_charpos(field_charset, key, key+length,
 
364
                                  local_char_length);
 
365
    set_if_smaller(length, local_char_length);
 
366
  }
 
367
  *to++= (char) (length & 255);
 
368
  if (max_length > 255)
 
369
    *to++= (char) (length >> 8);
 
370
  if (length)
 
371
    memcpy(to, key, length);
 
372
  return to+length;
 
373
}
 
374
 
 
375
 
 
376
/**
 
377
  Unpack a key into a record buffer.
 
378
 
 
379
  A VARCHAR key has a maximum size of 64K-1.
 
380
  In its packed form, the length field is one or two bytes long,
 
381
  depending on 'max_length'.
 
382
 
 
383
  @param to                          Pointer into the record buffer.
 
384
  @param key                         Pointer to the packed key.
 
385
  @param max_length                  Key length limit from key description.
 
386
 
 
387
  @return
 
388
    Pointer to end of 'key' (To the next key part if multi-segment key)
 
389
*/
 
390
 
 
391
const unsigned char *
 
392
Field_varstring::unpack_key(unsigned char *,
 
393
                            const unsigned char *key, uint32_t max_length,
 
394
                            bool )
 
395
{
 
396
  /* get length of the blob key */
 
397
  uint32_t length= *key++;
 
398
  if (max_length > 255)
 
399
    length+= (*key++) << 8;
 
400
 
 
401
  /* put the length into the record buffer */
 
402
  if (length_bytes == 1)
 
403
    *ptr= (unsigned char) length;
 
404
  else
 
405
    int2store(ptr, length);
 
406
  memcpy(ptr + length_bytes, key, length);
 
407
  return key + length;
 
408
}
 
409
 
 
410
/**
 
411
  Create a packed key that will be used for storage in the index tree.
 
412
 
 
413
  @param to             Store packed key segment here
 
414
  @param from           Key segment (as given to index_read())
 
415
  @param max_length     Max length of key
 
416
 
 
417
  @return
 
418
    end of key storage
 
419
*/
 
420
 
 
421
unsigned char *
 
422
Field_varstring::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
423
                                         bool )
 
424
{
 
425
  /* Key length is always stored as 2 bytes */
 
426
  uint32_t length= uint2korr(from);
 
427
  if (length > max_length)
 
428
    length= max_length;
 
429
  *to++= (char) (length & 255);
 
430
  if (max_length > 255)
 
431
    *to++= (char) (length >> 8);
 
432
  if (length)
 
433
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
 
434
  return to+length;
 
435
}
 
436
 
 
437
 
329
438
/**
330
439
   Unpack a varstring field from row data.
331
440
 
368
477
}
369
478
 
370
479
 
 
480
int Field_varstring::pack_cmp(const unsigned char *a, const unsigned char *b,
 
481
                              uint32_t key_length_arg,
 
482
                              bool insert_or_update)
 
483
{
 
484
  uint32_t a_length, b_length;
 
485
  if (key_length_arg > 255)
 
486
  {
 
487
    a_length=uint2korr(a); a+= 2;
 
488
    b_length=uint2korr(b); b+= 2;
 
489
  }
 
490
  else
 
491
  {
 
492
    a_length= (uint32_t) *a++;
 
493
    b_length= (uint32_t) *b++;
 
494
  }
 
495
  return field_charset->coll->strnncollsp(field_charset,
 
496
                                          a, a_length,
 
497
                                          b, b_length,
 
498
                                          insert_or_update);
 
499
}
 
500
 
 
501
 
 
502
int Field_varstring::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
 
503
                              bool insert_or_update)
 
504
{
 
505
  unsigned char *a= ptr+ length_bytes;
 
506
  uint32_t a_length=  length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
 
507
  uint32_t b_length;
 
508
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
 
509
                           key_length_arg / field_charset->mbmaxlen :
 
510
                           key_length_arg);
 
511
 
 
512
  if (key_length_arg > 255)
 
513
  {
 
514
    b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
 
515
  }
 
516
  else
 
517
    b_length= (uint32_t) *b++;
 
518
 
 
519
  if (a_length > local_char_length)
 
520
  {
 
521
    local_char_length= my_charpos(field_charset, a, a+a_length,
 
522
                                  local_char_length);
 
523
    set_if_smaller(a_length, local_char_length);
 
524
  }
 
525
 
 
526
  return field_charset->coll->strnncollsp(field_charset,
 
527
                                          a, a_length,
 
528
                                          b, b_length,
 
529
                                          insert_or_update);
 
530
}
 
531
 
 
532
 
 
533
uint32_t Field_varstring::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
534
{
 
535
  if (length > 255)
 
536
    return uint2korr(data_ptr)+2;
 
537
  return (uint32_t) *data_ptr + 1;
 
538
}
 
539
 
 
540
 
371
541
uint32_t Field_varstring::max_packed_col_length(uint32_t max_length)
372
542
{
373
543
  return (max_length > 255 ? 2 : 1)+max_length;
390
560
  if (f_length < length)
391
561
  {
392
562
    /*
393
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
563
      Must clear this as we do a memcmp in opt_range.cc to detect
394
564
      identical keys
395
565
    */
396
566
    buff.append(length-f_length, 0);
413
583
  if (f_length < length)
414
584
  {
415
585
    /*
416
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
586
      Must clear this as we do a memcmp in opt_range.cc to detect
417
587
      identical keys
418
588
    */
419
589
    memset(buff+HA_KEY_BLOB_LENGTH+f_length, 0, (length-f_length));
451
621
}
452
622
 
453
623
 
454
 
Field *Field_varstring::new_field(memory::Root *root, Table *new_table, bool keep_type)
 
624
Field *Field_varstring::new_field(MEM_ROOT *root, Table *new_table, bool keep_type)
455
625
{
456
626
  Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
457
627
                                                            keep_type);
461
631
}
462
632
 
463
633
 
464
 
Field *Field_varstring::new_key_field(memory::Root *root,
 
634
Field *Field_varstring::new_key_field(MEM_ROOT *root,
465
635
                                      Table *new_table,
466
636
                                      unsigned char *new_ptr, unsigned char *new_null_ptr,
467
637
                                      uint32_t new_null_bit)
479
649
  return res;
480
650
}
481
651
 
482
 
} /* namespace drizzled */
 
652
 
 
653
uint32_t Field_varstring::is_equal(CreateField *new_field_ptr)
 
654
{
 
655
  if (new_field_ptr->sql_type == real_type() &&
 
656
      new_field_ptr->charset == field_charset)
 
657
  {
 
658
    if (new_field_ptr->length == max_display_length())
 
659
      return IS_EQUAL_YES;
 
660
    if (new_field_ptr->length > max_display_length() &&
 
661
        ((new_field_ptr->length <= 255 && max_display_length() <= 255) ||
 
662
         (new_field_ptr->length > 255 && max_display_length() > 255)))
 
663
      return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length
 
664
  }
 
665
  return IS_EQUAL_NO;
 
666
}
 
667
 
 
668
 
 
669
void Field_varstring::hash(uint32_t *nr, uint32_t *nr2)
 
670
{
 
671
  if (is_null())
 
672
  {
 
673
    *nr^= (*nr << 1) | 1;
 
674
  }
 
675
  else
 
676
  {
 
677
    uint32_t len=  length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
 
678
    const CHARSET_INFO * const cs= charset();
 
679
    cs->coll->hash_sort(cs, ptr + length_bytes, len, nr, nr2);
 
680
  }
 
681
}
 
682
 
 
683