~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Monty Taylor
  • Date: 2008-08-16 21:06:22 UTC
  • Revision ID: monty@inaugust.com-20080816210622-zpnn13unyinqzn72
Updated po files.

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
21
24
 
22
25
#include <drizzled/server_includes.h>
23
26
#include <drizzled/field/blob.h>
24
 
#include <drizzled/table.h>
25
 
#include <drizzled/session.h>
26
 
 
27
 
#include <string>
28
 
 
29
 
using namespace std;
30
 
 
31
 
uint32_t
32
 
blob_pack_length_to_max_length(uint32_t arg)
33
 
{
34
 
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
35
 
}
36
 
 
 
27
 
 
28
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
 
29
((uint32_t) ((1LL << min(arg, (uint)4) * 8) - 1LL))
37
30
 
38
31
/****************************************************************************
39
32
** blob type
41
34
** packlength slot and may be from 1-4.
42
35
****************************************************************************/
43
36
 
44
 
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
37
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
45
38
                       enum utype unireg_check_arg, const char *field_name_arg,
46
 
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
39
                       TABLE_SHARE *share, uint blob_pack_length,
47
40
                       const CHARSET_INFO * const cs)
48
 
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
41
  :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
49
42
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
50
43
                 cs),
51
44
   packlength(blob_pack_length)
56
49
}
57
50
 
58
51
 
59
 
void Field_blob::store_length(unsigned char *i_ptr,
60
 
                              uint32_t i_packlength,
 
52
void Field_blob::store_length(uchar *i_ptr,
 
53
                              uint i_packlength,
61
54
                              uint32_t i_number,
62
55
                              bool low_byte_first __attribute__((unused)))
63
56
{
64
57
  switch (i_packlength) {
65
58
  case 1:
66
 
    i_ptr[0]= (unsigned char) i_number;
 
59
    i_ptr[0]= (uchar) i_number;
67
60
    break;
68
61
  case 2:
69
62
#ifdef WORDS_BIGENDIAN
91
84
}
92
85
 
93
86
 
94
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
95
 
                  uint32_t i_number)
96
 
{
97
 
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
98
 
}
99
 
 
100
 
 
101
 
uint32_t Field_blob::get_length(const unsigned char *pos,
102
 
                              uint32_t packlength_arg,
 
87
uint32_t Field_blob::get_length(const uchar *pos,
 
88
                              uint packlength_arg,
103
89
                              bool low_byte_first __attribute__((unused)))
104
90
{
105
91
  switch (packlength_arg) {
134
120
}
135
121
 
136
122
 
137
 
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
138
 
                                bool low_byte_first)
139
 
{
140
 
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
141
 
}
142
 
 
143
 
 
144
 
uint32_t Field_blob::get_length(uint32_t row_offset)
145
 
{
146
 
  return get_length(ptr+row_offset, this->packlength,
147
 
                    table->s->db_low_byte_first);
148
 
}
149
 
 
150
 
 
151
 
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
152
 
{
153
 
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
154
 
}
155
 
 
156
 
 
157
123
/**
158
124
  Put a blob length field into a record buffer.
159
125
 
165
131
  @param length              The length value to put.
166
132
*/
167
133
 
168
 
void Field_blob::put_length(unsigned char *pos, uint32_t length)
 
134
void Field_blob::put_length(uchar *pos, uint32_t length)
169
135
{
170
136
  switch (packlength) {
171
137
  case 1:
184
150
}
185
151
 
186
152
 
187
 
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
 
153
int Field_blob::store(const char *from,uint length, const CHARSET_INFO * const cs)
188
154
{
189
 
  uint32_t copy_length, new_length;
 
155
  uint copy_length, new_length;
190
156
  const char *well_formed_error_pos;
191
157
  const char *cannot_convert_error_pos;
192
158
  const char *from_end_pos, *tmp;
205
171
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
206
172
    {
207
173
      Field_blob::store_length(length);
208
 
      memmove(ptr+packlength, &from, sizeof(char*));
 
174
      memcpy(ptr+packlength, &from, sizeof(char*));
209
175
      return 0;
210
176
    }
211
177
    if (tmpstr.copy(from, length, cs))
213
179
    from= tmpstr.ptr();
214
180
  }
215
181
 
216
 
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
 
182
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
217
183
  if (value.alloc(new_length))
218
184
    goto oom_error;
219
185
 
225
191
                                            from, length);
226
192
    Field_blob::store_length(copy_length);
227
193
    tmp= value.ptr();
228
 
    memmove(ptr + packlength, &tmp, sizeof(char*));
 
194
    memcpy(ptr + packlength, &tmp, sizeof(char*));
229
195
    return 0;
230
196
  }
231
197
  /*
243
209
 
244
210
  Field_blob::store_length(copy_length);
245
211
  tmp= value.ptr();
246
 
  memmove(ptr+packlength, &tmp, sizeof(char*));
 
212
  memcpy(ptr+packlength, &tmp, sizeof(char*));
247
213
 
248
214
  if (check_string_copy_error(this, well_formed_error_pos,
249
215
                              cannot_convert_error_pos, from + length, cs))
254
220
oom_error:
255
221
  /* Fatal OOM error */
256
222
  memset(ptr, 0, Field_blob::pack_length());
257
 
  return -1;
 
223
  return -1; 
258
224
}
259
225
 
260
226
 
318
284
{
319
285
  const char *blob;
320
286
  size_t length;
321
 
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
 
287
  memcpy(&blob, ptr+packlength, sizeof(const uchar*));
322
288
  if (!blob)
323
289
  {
324
290
    blob= "";
333
299
}
334
300
 
335
301
 
336
 
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
 
302
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
337
303
                    uint32_t b_length)
338
304
{
339
 
  return field_charset->coll->strnncollsp(field_charset,
 
305
  return field_charset->coll->strnncollsp(field_charset, 
340
306
                                          a, a_length, b, b_length,
341
307
                                          0);
342
308
}
343
309
 
344
310
 
345
 
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
346
 
                        uint32_t max_length)
 
311
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
 
312
                        uint max_length)
347
313
{
348
 
  unsigned char *blob1,*blob2;
 
314
  uchar *blob1,*blob2;
349
315
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
350
316
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
351
 
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
 
317
  uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
352
318
  set_if_smaller(a_len, max_length);
353
319
  set_if_smaller(b_len, max_length);
354
320
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
355
321
}
356
322
 
357
323
 
358
 
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
324
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
359
325
                           uint32_t max_length)
360
326
{
361
327
  char *a,*b;
362
 
  uint32_t diff;
 
328
  uint diff;
363
329
  uint32_t a_length,b_length;
364
330
  memcpy(&a,a_ptr+packlength,sizeof(char*));
365
331
  memcpy(&b,b_ptr+packlength,sizeof(char*));
369
335
  b_length=get_length(b_ptr);
370
336
  if (b_length > max_length)
371
337
    b_length=max_length;
372
 
  diff=memcmp(a,b,cmin(a_length,b_length));
 
338
  diff=memcmp(a,b,min(a_length,b_length));
373
339
  return diff ? diff : (int) (a_length - b_length);
374
340
}
375
341
 
376
342
 
377
343
/* The following is used only when comparing a key */
378
344
 
379
 
uint32_t Field_blob::get_key_image(unsigned char *buff,
380
 
                                   uint32_t length,
381
 
                                   imagetype)
 
345
uint Field_blob::get_key_image(uchar *buff,
 
346
                               uint length,
 
347
                               imagetype type_arg __attribute__((unused)))
382
348
{
383
349
  uint32_t blob_length= get_length(ptr);
384
 
  unsigned char *blob;
 
350
  uchar *blob;
385
351
 
386
352
  get_ptr(&blob);
387
 
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
353
  uint local_char_length= length / field_charset->mbmaxlen;
388
354
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
389
355
                          local_char_length);
390
356
  set_if_smaller(blob_length, local_char_length);
404
370
}
405
371
 
406
372
 
407
 
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff,
408
 
                                   uint32_t length,
409
 
                                   imagetype)
410
 
{
411
 
  uint32_t blob_length= get_length(ptr);
412
 
  unsigned char *blob;
413
 
 
414
 
  get_ptr(&blob);
415
 
  uint32_t local_char_length= length / field_charset->mbmaxlen;
416
 
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
417
 
                                local_char_length);
418
 
  set_if_smaller(blob_length, local_char_length);
419
 
 
420
 
  unsigned char len_buff[HA_KEY_BLOB_LENGTH];
421
 
  int2store(len_buff,length);
422
 
  buff.append(len_buff);
423
 
  buff.append(blob, blob_length);
424
 
 
425
 
  if (length > blob_length)
426
 
  {
427
 
    /*
428
 
      Must clear this as we do a memcmp in opt_range.cc to detect
429
 
      identical keys
430
 
    */
431
 
 
432
 
    buff.append(length-blob_length, '0');
433
 
  }
434
 
  return HA_KEY_BLOB_LENGTH+length;
435
 
}
436
 
 
437
 
 
438
 
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
 
373
void Field_blob::set_key_image(const uchar *buff,uint length)
439
374
{
440
375
  length= uint2korr(buff);
441
376
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
443
378
}
444
379
 
445
380
 
446
 
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
 
381
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
447
382
{
448
 
  unsigned char *blob1;
449
 
  uint32_t blob_length=get_length(ptr);
 
383
  uchar *blob1;
 
384
  uint blob_length=get_length(ptr);
450
385
  memcpy(&blob1,ptr+packlength,sizeof(char*));
451
386
  const CHARSET_INFO * const cs= charset();
452
 
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
 
387
  uint local_char_length= max_key_length / cs->mbmaxlen;
453
388
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
454
389
                                local_char_length);
455
390
  set_if_smaller(blob_length, local_char_length);
458
393
                         uint2korr(key_ptr));
459
394
}
460
395
 
461
 
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
 
396
int Field_blob::key_cmp(const uchar *a,const uchar *b)
462
397
{
463
398
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
464
399
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
475
410
 
476
411
   @returns number of bytes written to metadata_ptr
477
412
*/
478
 
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
413
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
479
414
{
480
415
  *metadata_ptr= pack_length_no_ptr();
481
416
  return 1;
484
419
 
485
420
uint32_t Field_blob::sort_length() const
486
421
{
487
 
  return (uint32_t) (current_session->variables.max_sort_length +
 
422
  return (uint32_t) (current_thd->variables.max_sort_length + 
488
423
                   (field_charset == &my_charset_bin ? 0 : packlength));
489
424
}
490
425
 
491
426
 
492
 
void Field_blob::sort_string(unsigned char *to,uint32_t length)
 
427
void Field_blob::sort_string(uchar *to,uint length)
493
428
{
494
 
  unsigned char *blob;
495
 
  uint32_t blob_length=get_length();
 
429
  uchar *blob;
 
430
  uint blob_length=get_length();
496
431
 
497
432
  if (!blob_length)
498
433
    memset(to, 0, length);
500
435
  {
501
436
    if (field_charset == &my_charset_bin)
502
437
    {
503
 
      unsigned char *pos;
 
438
      uchar *pos;
504
439
 
505
440
      /*
506
441
        Store length of blob last in blob to shorter blobs before longer blobs
524
459
      }
525
460
    }
526
461
    memcpy(&blob,ptr+packlength,sizeof(char*));
527
 
 
 
462
    
528
463
    blob_length=my_strnxfrm(field_charset,
529
464
                            to, length, blob, blob_length);
530
465
    assert(blob_length == length);
532
467
}
533
468
 
534
469
 
535
 
uint32_t Field_blob::pack_length() const
536
 
{
537
 
  return (uint32_t) (packlength+table->s->blob_ptr_size);
538
 
}
539
 
 
540
 
 
541
470
void Field_blob::sql_type(String &res) const
542
471
{
543
472
  if (charset() == &my_charset_bin)
546
475
    res.set_ascii(STRING_WITH_LEN("text"));
547
476
}
548
477
 
549
 
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
550
 
                        uint32_t max_length, bool low_byte_first)
 
478
uchar *Field_blob::pack(uchar *to, const uchar *from,
 
479
                        uint max_length, bool low_byte_first)
551
480
{
552
 
  unsigned char *save= ptr;
553
 
  ptr= (unsigned char*) from;
 
481
  uchar *save= ptr;
 
482
  ptr= (uchar*) from;
554
483
  uint32_t length=get_length();                 // Length of from string
555
484
 
556
485
  /*
558
487
    length given is smaller than the actual length of the blob, we
559
488
    just store the initial bytes of the blob.
560
489
  */
561
 
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
 
490
  store_length(to, packlength, min(length, max_length), low_byte_first);
562
491
 
563
492
  /*
564
493
    Store the actual blob data, which will occupy 'length' bytes.
565
494
   */
566
495
  if (length > 0)
567
496
  {
568
 
    get_ptr((unsigned char**) &from);
 
497
    get_ptr((uchar**) &from);
569
498
    memcpy(to+packlength, from,length);
570
499
  }
571
500
  ptr=save;                                     // Restore org row pointer
576
505
/**
577
506
   Unpack a blob field from row data.
578
507
 
579
 
   This method is used to unpack a blob field from a master whose size of
 
508
   This method is used to unpack a blob field from a master whose size of 
580
509
   the field is less than that of the slave. Note: This method is included
581
510
   to satisfy inheritance rules, but is not needed for blob fields. It
582
511
   simply is used as a pass-through to the original unpack() method for
590
519
 
591
520
   @return  New pointer into memory based on from + length of the data
592
521
*/
593
 
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
594
 
                                const unsigned char *from,
595
 
                                uint32_t param_data,
 
522
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
 
523
                                const uchar *from,
 
524
                                uint param_data,
596
525
                                bool low_byte_first)
597
526
{
598
 
  uint32_t const master_packlength=
 
527
  uint const master_packlength=
599
528
    param_data > 0 ? param_data & 0xFF : packlength;
600
529
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
601
530
  bitmap_set_bit(table->write_set, field_index);
606
535
 
607
536
/* Keys for blobs are like keys on varchars */
608
537
 
609
 
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
 
538
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
610
539
                         bool insert_or_update)
611
540
{
612
 
  uint32_t a_length, b_length;
 
541
  uint a_length, b_length;
613
542
  if (key_length_arg > 255)
614
543
  {
615
544
    a_length=uint2korr(a); a+=2;
627
556
}
628
557
 
629
558
 
630
 
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
 
559
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
631
560
                         bool insert_or_update)
632
561
{
633
 
  unsigned char *a;
634
 
  uint32_t a_length, b_length;
 
562
  uchar *a;
 
563
  uint a_length, b_length;
635
564
  memcpy(&a,ptr+packlength,sizeof(char*));
636
565
  if (!a)
637
566
    return key_length_arg > 0 ? -1 : 0;
651
580
 
652
581
/** Create a packed key that will be used for storage from a MySQL row. */
653
582
 
654
 
unsigned char *
655
 
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
583
uchar *
 
584
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
656
585
                     bool low_byte_first __attribute__((unused)))
657
586
{
658
 
  unsigned char *save= ptr;
659
 
  ptr= (unsigned char*) from;
 
587
  uchar *save= ptr;
 
588
  ptr= (uchar*) from;
660
589
  uint32_t length=get_length();        // Length of from string
661
 
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
 
590
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
662
591
                           max_length/field_charset->mbmaxlen : max_length);
663
592
  if (length)
664
 
    get_ptr((unsigned char**) &from);
 
593
    get_ptr((uchar**) &from);
665
594
  if (length > local_char_length)
666
595
    local_char_length= my_charpos(field_charset, from, from+length,
667
596
                                  local_char_length);
668
597
  set_if_smaller(length, local_char_length);
669
 
  *to++= (unsigned char) length;
 
598
  *to++= (uchar) length;
670
599
  if (max_length > 255)                         // 2 byte length
671
 
    *to++= (unsigned char) (length >> 8);
 
600
    *to++= (uchar) (length >> 8);
672
601
  memcpy(to, from, length);
673
602
  ptr=save;                                     // Restore org row pointer
674
603
  return to+length;
696
625
    Pointer into 'from' past the last byte copied from packed key.
697
626
*/
698
627
 
699
 
const unsigned char *
700
 
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
628
const uchar *
 
629
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
701
630
                       bool low_byte_first __attribute__((unused)))
702
631
{
703
632
  /* get length of the blob key */
721
650
 
722
651
/** Create a packed key that will be used for storage from a MySQL key. */
723
652
 
724
 
unsigned char *
725
 
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
653
uchar *
 
654
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
726
655
                                    bool low_byte_first __attribute__((unused)))
727
656
{
728
 
  uint32_t length=uint2korr(from);
 
657
  uint length=uint2korr(from);
729
658
  if (length > max_length)
730
659
    length=max_length;
731
660
  *to++= (char) (length & 255);
737
666
}
738
667
 
739
668
 
740
 
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
669
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
741
670
{
742
671
  if (length > 255)
743
672
    return uint2korr(data_ptr)+2;
745
674
}
746
675
 
747
676
 
748
 
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
 
677
uint Field_blob::max_packed_col_length(uint max_length)
749
678
{
750
679
  return (max_length > 255 ? 2 : 1)+max_length;
751
680
}
752
681
 
753
682
 
754
 
uint32_t Field_blob::is_equal(Create_field *new_field)
 
683
uint Field_blob::is_equal(Create_field *new_field)
755
684
{
756
685
  if (compare_str_field_flags(new_field, flags))
757
686
    return 0;
788
717
  }
789
718
}
790
719
 
791
 
bool Field_blob::in_read_set()
792
 
{
793
 
  return bitmap_is_set(table->read_set, field_index);
794
 
}
795
 
 
796
 
 
797
 
bool Field_blob::in_write_set()
798
 
{
799
 
  return bitmap_is_set(table->write_set, field_index);
800
 
}