~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2008 MySQL
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#ifdef USE_PRAGMA_IMPLEMENTATION
22
 
#pragma implementation                          // gcc: Class implementation
23
 
#endif
24
21
 
25
22
#include <drizzled/server_includes.h>
26
23
#include <drizzled/field/blob.h>
 
24
#include <drizzled/table.h>
 
25
#include <drizzled/session.h>
 
26
 
 
27
#include <string>
 
28
 
 
29
using namespace std;
27
30
 
28
31
uint32_t
29
32
blob_pack_length_to_max_length(uint32_t arg)
30
33
{
31
 
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
 
34
  return (uint32_t)cmax(UINT32_MAX,
 
35
                        (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1));
32
36
}
33
37
 
34
38
 
40
44
 
41
45
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
42
46
                       enum utype unireg_check_arg, const char *field_name_arg,
43
 
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
47
                       TableShare *share, uint32_t blob_pack_length,
44
48
                       const CHARSET_INFO * const cs)
45
49
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
46
50
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
56
60
void Field_blob::store_length(unsigned char *i_ptr,
57
61
                              uint32_t i_packlength,
58
62
                              uint32_t i_number,
59
 
                              bool low_byte_first __attribute__((unused)))
 
63
                              bool low_byte_first)
60
64
{
 
65
#ifndef WORDS_BIGENDIAN
 
66
  (void)low_byte_first;
 
67
#endif
61
68
  switch (i_packlength) {
62
69
  case 1:
63
70
    i_ptr[0]= (unsigned char) i_number;
88
95
}
89
96
 
90
97
 
 
98
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
 
99
                  uint32_t i_number)
 
100
{
 
101
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
 
102
}
 
103
 
 
104
 
91
105
uint32_t Field_blob::get_length(const unsigned char *pos,
92
 
                              uint32_t packlength_arg,
93
 
                              bool low_byte_first __attribute__((unused)))
 
106
                                uint32_t packlength_arg,
 
107
                                bool low_byte_first)
94
108
{
 
109
#ifndef WORDS_BIGENDIAN
 
110
  (void)low_byte_first;
 
111
#endif
95
112
  switch (packlength_arg) {
96
113
  case 1:
97
114
    return (uint32_t) pos[0];
124
141
}
125
142
 
126
143
 
 
144
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
 
145
                                bool low_byte_first)
 
146
{
 
147
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
 
148
}
 
149
 
 
150
 
 
151
uint32_t Field_blob::get_length(uint32_t row_offset)
 
152
{
 
153
  return get_length(ptr+row_offset, this->packlength,
 
154
                    table->s->db_low_byte_first);
 
155
}
 
156
 
 
157
 
 
158
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
 
159
{
 
160
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
 
161
}
 
162
 
 
163
 
127
164
/**
128
165
  Put a blob length field into a record buffer.
129
166
 
175
212
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
176
213
    {
177
214
      Field_blob::store_length(length);
178
 
      memcpy(ptr+packlength, &from, sizeof(char*));
 
215
      memmove(ptr+packlength, &from, sizeof(char*));
179
216
      return 0;
180
217
    }
181
218
    if (tmpstr.copy(from, length, cs))
195
232
                                            from, length);
196
233
    Field_blob::store_length(copy_length);
197
234
    tmp= value.ptr();
198
 
    memcpy(ptr + packlength, &tmp, sizeof(char*));
 
235
    memmove(ptr + packlength, &tmp, sizeof(char*));
199
236
    return 0;
200
237
  }
201
238
  /*
213
250
 
214
251
  Field_blob::store_length(copy_length);
215
252
  tmp= value.ptr();
216
 
  memcpy(ptr+packlength, &tmp, sizeof(char*));
 
253
  memmove(ptr+packlength, &tmp, sizeof(char*));
217
254
 
218
255
  if (check_string_copy_error(this, well_formed_error_pos,
219
256
                              cannot_convert_error_pos, from + length, cs))
224
261
oom_error:
225
262
  /* Fatal OOM error */
226
263
  memset(ptr, 0, Field_blob::pack_length());
227
 
  return -1; 
 
264
  return -1;
228
265
}
229
266
 
230
267
 
232
269
{
233
270
  const CHARSET_INFO * const cs=charset();
234
271
  value.set_real(nr, NOT_FIXED_DEC, cs);
235
 
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
 
272
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
236
273
}
237
274
 
238
275
 
240
277
{
241
278
  const CHARSET_INFO * const cs=charset();
242
279
  value.set_int(nr, unsigned_val, cs);
243
 
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
 
280
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
244
281
}
245
282
 
246
283
 
271
308
  return my_strntoll(charset(),blob,length,10,NULL,&not_used);
272
309
}
273
310
 
274
 
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
 
311
String *Field_blob::val_str(String *,
275
312
                            String *val_ptr)
276
313
{
277
314
  char *blob;
306
343
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
307
344
                    uint32_t b_length)
308
345
{
309
 
  return field_charset->coll->strnncollsp(field_charset, 
 
346
  return field_charset->coll->strnncollsp(field_charset,
310
347
                                          a, a_length, b, b_length,
311
348
                                          0);
312
349
}
347
384
/* The following is used only when comparing a key */
348
385
 
349
386
uint32_t Field_blob::get_key_image(unsigned char *buff,
350
 
                               uint32_t length,
351
 
                               imagetype type_arg __attribute__((unused)))
 
387
                                   uint32_t length,
 
388
                                   imagetype)
352
389
{
353
390
  uint32_t blob_length= get_length(ptr);
354
391
  unsigned char *blob;
366
403
      identical keys
367
404
    */
368
405
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
369
 
    length=(uint) blob_length;
 
406
    length=(uint32_t) blob_length;
370
407
  }
371
408
  int2store(buff,length);
372
409
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
374
411
}
375
412
 
376
413
 
 
414
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff,
 
415
                                   uint32_t length,
 
416
                                   imagetype)
 
417
{
 
418
  uint32_t blob_length= get_length(ptr);
 
419
  unsigned char *blob;
 
420
 
 
421
  get_ptr(&blob);
 
422
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
423
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
 
424
                                local_char_length);
 
425
  set_if_smaller(blob_length, local_char_length);
 
426
 
 
427
  unsigned char len_buff[HA_KEY_BLOB_LENGTH];
 
428
  int2store(len_buff,length);
 
429
  buff.append(len_buff);
 
430
  buff.append(blob, blob_length);
 
431
 
 
432
  if (length > blob_length)
 
433
  {
 
434
    /*
 
435
      Must clear this as we do a memcmp in opt_range.cc to detect
 
436
      identical keys
 
437
    */
 
438
 
 
439
    buff.append(length-blob_length, '0');
 
440
  }
 
441
  return HA_KEY_BLOB_LENGTH+length;
 
442
}
 
443
 
 
444
 
377
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
378
446
{
379
447
  length= uint2korr(buff);
423
491
 
424
492
uint32_t Field_blob::sort_length() const
425
493
{
426
 
  return (uint32_t) (current_thd->variables.max_sort_length + 
 
494
  return (uint32_t) (current_session->variables.max_sort_length +
427
495
                   (field_charset == &my_charset_bin ? 0 : packlength));
428
496
}
429
497
 
463
531
      }
464
532
    }
465
533
    memcpy(&blob,ptr+packlength,sizeof(char*));
466
 
    
 
534
 
467
535
    blob_length=my_strnxfrm(field_charset,
468
536
                            to, length, blob, blob_length);
469
537
    assert(blob_length == length);
471
539
}
472
540
 
473
541
 
 
542
uint32_t Field_blob::pack_length() const
 
543
{
 
544
  return (uint32_t) (packlength+table->s->blob_ptr_size);
 
545
}
 
546
 
 
547
 
474
548
void Field_blob::sql_type(String &res) const
475
549
{
476
550
  if (charset() == &my_charset_bin)
509
583
/**
510
584
   Unpack a blob field from row data.
511
585
 
512
 
   This method is used to unpack a blob field from a master whose size of 
 
586
   This method is used to unpack a blob field from a master whose size of
513
587
   the field is less than that of the slave. Note: This method is included
514
588
   to satisfy inheritance rules, but is not needed for blob fields. It
515
589
   simply is used as a pass-through to the original unpack() method for
523
597
 
524
598
   @return  New pointer into memory based on from + length of the data
525
599
*/
526
 
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
 
600
const unsigned char *Field_blob::unpack(unsigned char *,
527
601
                                const unsigned char *from,
528
602
                                uint32_t param_data,
529
603
                                bool low_byte_first)
531
605
  uint32_t const master_packlength=
532
606
    param_data > 0 ? param_data & 0xFF : packlength;
533
607
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
 
  bitmap_set_bit(table->write_set, field_index);
 
608
  table->setWriteSet(field_index);
535
609
  store(reinterpret_cast<const char*>(from) + master_packlength,
536
610
        length, field_charset);
537
611
  return(from + master_packlength + length);
538
612
}
539
613
 
540
 
/* Keys for blobs are like keys on varchars */
541
 
 
542
 
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
543
 
                         bool insert_or_update)
544
 
{
545
 
  uint32_t a_length, b_length;
546
 
  if (key_length_arg > 255)
547
 
  {
548
 
    a_length=uint2korr(a); a+=2;
549
 
    b_length=uint2korr(b); b+=2;
550
 
  }
551
 
  else
552
 
  {
553
 
    a_length= (uint) *a++;
554
 
    b_length= (uint) *b++;
555
 
  }
556
 
  return field_charset->coll->strnncollsp(field_charset,
557
 
                                          a, a_length,
558
 
                                          b, b_length,
559
 
                                          insert_or_update);
560
 
}
561
 
 
562
 
 
563
 
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
564
 
                         bool insert_or_update)
565
 
{
566
 
  unsigned char *a;
567
 
  uint32_t a_length, b_length;
568
 
  memcpy(&a,ptr+packlength,sizeof(char*));
569
 
  if (!a)
570
 
    return key_length_arg > 0 ? -1 : 0;
571
 
 
572
 
  a_length= get_length(ptr);
573
 
  if (key_length_arg > 255)
574
 
  {
575
 
    b_length= uint2korr(b); b+=2;
576
 
  }
577
 
  else
578
 
    b_length= (uint) *b++;
579
 
  return field_charset->coll->strnncollsp(field_charset,
580
 
                                          a, a_length,
581
 
                                          b, b_length,
582
 
                                          insert_or_update);
583
 
}
584
 
 
585
614
/** Create a packed key that will be used for storage from a MySQL row. */
586
615
 
587
616
unsigned char *
588
617
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
589
 
                     bool low_byte_first __attribute__((unused)))
 
618
                     bool )
590
619
{
591
620
  unsigned char *save= ptr;
592
621
  ptr= (unsigned char*) from;
608
637
}
609
638
 
610
639
 
611
 
/**
612
 
  Unpack a blob key into a record buffer.
613
 
 
614
 
  A blob key has a maximum size of 64K-1.
615
 
  In its packed form, the length field is one or two bytes long,
616
 
  depending on 'max_length'.
617
 
  Depending on the maximum length of a blob, its length field is
618
 
  put into 1 to 4 bytes. This is a property of the blob object,
619
 
  described by 'packlength'.
620
 
  Blobs are internally stored apart from the record buffer, which
621
 
  contains a pointer to the blob buffer.
622
 
 
623
 
 
624
 
  @param to                          Pointer into the record buffer.
625
 
  @param from                        Pointer to the packed key.
626
 
  @param max_length                  Key length limit from key description.
627
 
 
628
 
  @return
629
 
    Pointer into 'from' past the last byte copied from packed key.
630
 
*/
631
 
 
632
 
const unsigned char *
633
 
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
634
 
                       bool low_byte_first __attribute__((unused)))
635
 
{
636
 
  /* get length of the blob key */
637
 
  uint32_t length= *from++;
638
 
  if (max_length > 255)
639
 
    length+= *from++ << 8;
640
 
 
641
 
  /* put the length into the record buffer */
642
 
  put_length(to, length);
643
 
 
644
 
  /* put the address of the blob buffer or NULL */
645
 
  if (length)
646
 
    memcpy(to + packlength, &from, sizeof(from));
647
 
  else
648
 
    memset(to + packlength, 0, sizeof(from));
649
 
 
650
 
  /* point to first byte of next field in 'from' */
651
 
  return from + length;
652
 
}
653
 
 
654
 
 
655
 
/** Create a packed key that will be used for storage from a MySQL key. */
656
 
 
657
 
unsigned char *
658
 
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
659
 
                                    bool low_byte_first __attribute__((unused)))
660
 
{
661
 
  uint32_t length=uint2korr(from);
662
 
  if (length > max_length)
663
 
    length=max_length;
664
 
  *to++= (char) (length & 255);
665
 
  if (max_length > 255)
666
 
    *to++= (char) (length >> 8);
667
 
  if (length)
668
 
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
669
 
  return to+length;
670
 
}
671
 
 
672
 
 
673
 
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
674
 
{
675
 
  if (length > 255)
676
 
    return uint2korr(data_ptr)+2;
677
 
  return (uint) *data_ptr + 1;
678
 
}
679
 
 
680
 
 
681
 
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
682
 
{
683
 
  return (max_length > 255 ? 2 : 1)+max_length;
684
 
}
685
 
 
686
 
 
687
 
uint32_t Field_blob::is_equal(Create_field *new_field)
688
 
{
689
 
  if (compare_str_field_flags(new_field, flags))
 
640
uint32_t Field_blob::is_equal(Create_field *new_field_ptr)
 
641
{
 
642
  if (compare_str_field_flags(new_field_ptr, flags))
690
643
    return 0;
 
644
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
691
645
 
692
 
  return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
693
 
          && new_field->charset == field_charset &&
694
 
          ((Field_blob *)new_field->field)->max_data_length() ==
695
 
          max_data_length());
 
646
  return ((new_field_ptr->sql_type == 
 
647
             get_blob_type_from_length(max_data_length()))
 
648
          && new_field_ptr->charset == field_charset
 
649
          && blob_field_ptr->max_data_length() == max_data_length());
696
650
}
697
651
 
698
652
 
720
674
    return 0;
721
675
  }
722
676
}
723