~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-07-10 01:49:29 UTC
  • mto: (1090.1.1 staging)
  • mto: This revision was merged to the branch mainline in revision 1091.
  • Revision ID: brian@gaz-20090710014929-v8pmvf7woqkld9iv
Cleanup of user_var

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/blob.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
#include <algorithm>
30
29
 
31
30
using namespace std;
32
31
 
33
 
namespace drizzled
34
 
{
35
 
 
36
 
static uint32_t blob_pack_length_to_max_length(uint32_t arg)
 
32
uint32_t
 
33
blob_pack_length_to_max_length(uint32_t arg)
37
34
{
38
35
  return max(UINT32_MAX,
39
36
             (uint32_t)((INT64_C(1) << min(arg, 4U) * 8) - INT64_C(1)));
43
40
/****************************************************************************
44
41
** blob type
45
42
** A blob is saved as a length and a pointer. The length is stored in the
46
 
** packlength slot and is sizeof(uint32_t) (4 bytes)
 
43
** packlength slot and may be from 1-4.
47
44
****************************************************************************/
48
45
 
49
 
Field_blob::Field_blob(unsigned char *ptr_arg,
50
 
                       unsigned char *null_ptr_arg,
51
 
                       unsigned char null_bit_arg,
52
 
                                   const char *field_name_arg,
53
 
                       TableShare *share,
54
 
                       const CHARSET_INFO * const cs)
55
 
  :Field_str(ptr_arg,
56
 
             blob_pack_length_to_max_length(sizeof(uint32_t)),
57
 
             null_ptr_arg,
58
 
             null_bit_arg,
59
 
             field_name_arg,
60
 
             cs)
 
46
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
47
                       enum utype unireg_check_arg, const char *field_name_arg,
 
48
                       TableShare *share, uint32_t blob_pack_length,
 
49
                       const CHARSET_INFO * const cs)
 
50
  :Field_str(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
51
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
 
52
                 cs),
 
53
   packlength(blob_pack_length)
61
54
{
62
55
  flags|= BLOB_FLAG;
63
56
  share->blob_fields++;
64
 
  /* TODO: why do not fill table->getShare()->blob_field array here? */
 
57
  /* TODO: why do not fill table->s->blob_field array here? */
65
58
}
66
59
 
 
60
 
67
61
void Field_blob::store_length(unsigned char *i_ptr,
 
62
                              uint32_t i_packlength,
68
63
                              uint32_t i_number,
69
64
                              bool low_byte_first)
70
65
{
71
66
#ifndef WORDS_BIGENDIAN
72
67
  (void)low_byte_first;
73
68
#endif
74
 
 
75
 
#ifdef WORDS_BIGENDIAN
76
 
  if (low_byte_first)
77
 
  {
78
 
    int4store(i_ptr,i_number);
 
69
  switch (i_packlength) {
 
70
  case 1:
 
71
    i_ptr[0]= (unsigned char) i_number;
 
72
    break;
 
73
  case 2:
 
74
#ifdef WORDS_BIGENDIAN
 
75
    if (low_byte_first)
 
76
    {
 
77
      int2store(i_ptr,(unsigned short) i_number);
 
78
    }
 
79
    else
 
80
#endif
 
81
      shortstore(i_ptr,(unsigned short) i_number);
 
82
    break;
 
83
  case 3:
 
84
    int3store(i_ptr,i_number);
 
85
    break;
 
86
  case 4:
 
87
#ifdef WORDS_BIGENDIAN
 
88
    if (low_byte_first)
 
89
    {
 
90
      int4store(i_ptr,i_number);
 
91
    }
 
92
    else
 
93
#endif
 
94
      longstore(i_ptr,i_number);
79
95
  }
80
 
  else
81
 
#endif
82
 
    longstore(i_ptr,i_number);
83
96
}
84
97
 
85
98
 
86
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_number)
 
99
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
 
100
                  uint32_t i_number)
87
101
{
88
 
  store_length(i_ptr, i_number, getTable()->getShare()->db_low_byte_first);
 
102
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
89
103
}
90
104
 
91
105
 
92
106
uint32_t Field_blob::get_length(const unsigned char *pos,
 
107
                                uint32_t packlength_arg,
93
108
                                bool low_byte_first)
94
109
{
95
110
#ifndef WORDS_BIGENDIAN
96
111
  (void)low_byte_first;
97
112
#endif
98
 
  uint32_t tmp;
99
 
#ifdef WORDS_BIGENDIAN
100
 
  if (low_byte_first)
101
 
    tmp=uint4korr(pos);
102
 
  else
103
 
#endif
104
 
    longget(tmp,pos);
105
 
  return (uint32_t) tmp;
 
113
  switch (packlength_arg) {
 
114
  case 1:
 
115
    return (uint32_t) pos[0];
 
116
  case 2:
 
117
    {
 
118
      uint16_t tmp;
 
119
#ifdef WORDS_BIGENDIAN
 
120
      if (low_byte_first)
 
121
        tmp=sint2korr(pos);
 
122
      else
 
123
#endif
 
124
        shortget(tmp,pos);
 
125
      return (uint32_t) tmp;
 
126
    }
 
127
  case 3:
 
128
    return (uint32_t) uint3korr(pos);
 
129
  case 4:
 
130
    {
 
131
      uint32_t tmp;
 
132
#ifdef WORDS_BIGENDIAN
 
133
      if (low_byte_first)
 
134
        tmp=uint4korr(pos);
 
135
      else
 
136
#endif
 
137
        longget(tmp,pos);
 
138
      return (uint32_t) tmp;
 
139
    }
 
140
  }
 
141
  return 0;                                     // Impossible
106
142
}
107
143
 
108
144
 
109
145
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
110
146
                                bool low_byte_first)
111
147
{
112
 
  return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
 
148
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
113
149
}
114
150
 
115
151
 
116
152
uint32_t Field_blob::get_length(uint32_t row_offset)
117
153
{
118
 
  return get_length(ptr+row_offset,
119
 
                    getTable()->getShare()->db_low_byte_first);
 
154
  return get_length(ptr+row_offset, this->packlength,
 
155
                    table->s->db_low_byte_first);
120
156
}
121
157
 
122
158
 
123
159
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
124
160
{
125
 
  return get_length(ptr_arg, getTable()->getShare()->db_low_byte_first);
 
161
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
126
162
}
127
163
 
128
164
 
129
165
/**
130
166
  Put a blob length field into a record buffer.
131
167
 
132
 
  Blob length is always stored in sizeof(uint32_t) (4 bytes)
 
168
  Depending on the maximum length of a blob, its length field is
 
169
  put into 1 to 4 bytes. This is a property of the blob object,
 
170
  described by 'packlength'.
133
171
 
134
172
  @param pos                 Pointer into the record buffer.
135
173
  @param length              The length value to put.
137
175
 
138
176
void Field_blob::put_length(unsigned char *pos, uint32_t length)
139
177
{
 
178
  switch (packlength) {
 
179
  case 1:
 
180
    *pos= (char) length;
 
181
    break;
 
182
  case 2:
 
183
    int2store(pos, length);
 
184
    break;
 
185
  case 3:
 
186
    int3store(pos, length);
 
187
    break;
 
188
  case 4:
140
189
    int4store(pos, length);
 
190
    break;
 
191
  }
141
192
}
142
193
 
143
194
 
160
211
 
161
212
  if (from == value.ptr())
162
213
  {
163
 
    size_t dummy_offset;
 
214
    uint32_t dummy_offset;
164
215
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
165
216
    {
166
217
      Field_blob::store_length(length);
167
 
      memmove(ptr+sizeof(uint32_t), &from, sizeof(char*));
 
218
      memmove(ptr+packlength, &from, sizeof(char*));
168
219
      return 0;
169
220
    }
170
221
    if (tmpstr.copy(from, length, cs))
176
227
  if (value.alloc(new_length))
177
228
    goto oom_error;
178
229
 
 
230
 
 
231
  if (f_is_hex_escape(flags))
 
232
  {
 
233
    copy_length= my_copy_with_hex_escaping(field_charset,
 
234
                                           (char*) value.ptr(), new_length,
 
235
                                            from, length);
 
236
    Field_blob::store_length(copy_length);
 
237
    tmp= value.ptr();
 
238
    memmove(ptr + packlength, &tmp, sizeof(char*));
 
239
    return 0;
 
240
  }
179
241
  /*
180
242
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
181
243
    is never used to limit the length of the data. The cut of long data
191
253
 
192
254
  Field_blob::store_length(copy_length);
193
255
  tmp= value.ptr();
194
 
  memmove(ptr+sizeof(uint32_t), &tmp, sizeof(char*));
 
256
  memmove(ptr+packlength, &tmp, sizeof(char*));
195
257
 
196
258
  if (check_string_copy_error(this, well_formed_error_pos,
197
259
                              cannot_convert_error_pos, from + length, cs))
233
295
 
234
296
  ASSERT_COLUMN_MARKED_FOR_READ;
235
297
 
236
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
298
  memcpy(&blob,ptr+packlength,sizeof(char*));
237
299
  if (!blob)
238
300
    return 0.0;
239
301
  length= get_length(ptr);
249
311
 
250
312
  ASSERT_COLUMN_MARKED_FOR_READ;
251
313
 
252
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
314
  memcpy(&blob,ptr+packlength,sizeof(char*));
253
315
  if (!blob)
254
316
    return 0;
255
317
  uint32_t length=get_length(ptr);
263
325
 
264
326
  ASSERT_COLUMN_MARKED_FOR_READ;
265
327
 
266
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
328
  memcpy(&blob,ptr+packlength,sizeof(char*));
267
329
  if (!blob)
268
330
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
269
331
  else
279
341
 
280
342
  ASSERT_COLUMN_MARKED_FOR_READ;
281
343
 
282
 
  memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
 
344
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
283
345
  if (!blob)
284
346
  {
285
347
    blob= "";
307
369
                        uint32_t max_length)
308
370
{
309
371
  unsigned char *blob1,*blob2;
310
 
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
311
 
  memcpy(&blob2,b_ptr+sizeof(uint32_t),sizeof(char*));
 
372
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
 
373
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
312
374
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
313
375
  set_if_smaller(a_len, max_length);
314
376
  set_if_smaller(b_len, max_length);
322
384
  char *a,*b;
323
385
  uint32_t diff;
324
386
  uint32_t a_length,b_length;
325
 
  memcpy(&a,a_ptr+sizeof(uint32_t),sizeof(char*));
326
 
  memcpy(&b,b_ptr+sizeof(uint32_t),sizeof(char*));
 
387
  memcpy(&a,a_ptr+packlength,sizeof(char*));
 
388
  memcpy(&b,b_ptr+packlength,sizeof(char*));
327
389
 
328
390
  a_length= get_length(a_ptr);
329
391
 
337
399
 
338
400
  diff= memcmp(a,b,min(a_length,b_length));
339
401
 
340
 
  return diff ? diff : (unsigned int) (a_length - b_length);
 
402
  return diff ? diff : (int) (a_length - b_length);
341
403
}
342
404
 
343
405
/* The following is used only when comparing a key */
355
417
  if ((uint32_t) length > blob_length)
356
418
  {
357
419
    /*
358
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
420
      Must clear this as we do a memcmp in opt_range.cc to detect
359
421
      identical keys
360
422
    */
361
423
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
386
448
  if (length > blob_length)
387
449
  {
388
450
    /*
389
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
451
      Must clear this as we do a memcmp in opt_range.cc to detect
390
452
      identical keys
391
453
    */
392
454
 
405
467
{
406
468
  unsigned char *blob1;
407
469
  uint32_t blob_length=get_length(ptr);
408
 
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
 
470
  memcpy(&blob1,ptr+packlength,sizeof(char*));
409
471
  const CHARSET_INFO * const cs= charset();
410
472
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
411
473
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
422
484
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
423
485
}
424
486
 
 
487
/**
 
488
   Save the field metadata for blob fields.
 
489
 
 
490
   Saves the pack length in the first byte of the field metadata array
 
491
   at index of *metadata_ptr.
 
492
 
 
493
   @param   metadata_ptr   First byte of field metadata
 
494
 
 
495
   @returns number of bytes written to metadata_ptr
 
496
*/
 
497
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
498
{
 
499
  *metadata_ptr= pack_length_no_ptr();
 
500
  return 1;
 
501
}
 
502
 
425
503
uint32_t Field_blob::sort_length() const
426
504
{
427
505
  return (uint32_t) (current_session->variables.max_sort_length +
428
 
                     (field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
 
506
                   (field_charset == &my_charset_bin ? 0 : packlength));
429
507
}
430
508
 
431
509
void Field_blob::sort_string(unsigned char *to,uint32_t length)
444
522
      /*
445
523
        Store length of blob last in blob to shorter blobs before longer blobs
446
524
      */
447
 
      length-= sizeof(uint32_t); // size of stored blob length
 
525
      length-= packlength;
448
526
      pos= to+length;
449
527
 
450
 
      mi_int4store(pos, blob_length);
 
528
      switch (packlength) {
 
529
      case 1:
 
530
        *pos= (char) blob_length;
 
531
        break;
 
532
      case 2:
 
533
        mi_int2store(pos, blob_length);
 
534
        break;
 
535
      case 3:
 
536
        mi_int3store(pos, blob_length);
 
537
        break;
 
538
      case 4:
 
539
        mi_int4store(pos, blob_length);
 
540
        break;
 
541
      }
451
542
    }
452
 
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
543
    memcpy(&blob,ptr+packlength,sizeof(char*));
453
544
 
454
545
    blob_length=my_strnxfrm(field_charset,
455
546
                            to, length, blob, blob_length);
459
550
 
460
551
uint32_t Field_blob::pack_length() const
461
552
{
462
 
  return (uint32_t) (sizeof(uint32_t) + portable_sizeof_char_ptr);
 
553
  return (uint32_t) (packlength+table->s->blob_ptr_size);
463
554
}
464
555
 
465
556
void Field_blob::sql_type(String &res) const
482
573
    length given is smaller than the actual length of the blob, we
483
574
    just store the initial bytes of the blob.
484
575
  */
485
 
  store_length(to, min(length, max_length), low_byte_first);
 
576
  store_length(to, packlength, min(length, max_length), low_byte_first);
486
577
 
487
578
  /*
488
579
    Store the actual blob data, which will occupy 'length' bytes.
490
581
  if (length > 0)
491
582
  {
492
583
    get_ptr((unsigned char**) &from);
493
 
    memcpy(to+sizeof(uint32_t), from,length);
 
584
    memcpy(to+packlength, from,length);
494
585
  }
495
586
 
496
587
  ptr= save;                                    // Restore org row pointer
497
 
  return(to+sizeof(uint32_t)+length);
 
588
  return(to+packlength+length);
498
589
}
499
590
 
500
591
/**
515
606
   @return  New pointer into memory based on from + length of the data
516
607
*/
517
608
const unsigned char *Field_blob::unpack(unsigned char *,
518
 
                                        const unsigned char *from,
519
 
                                        uint32_t,
520
 
                                        bool low_byte_first)
 
609
                                const unsigned char *from,
 
610
                                uint32_t param_data,
 
611
                                bool low_byte_first)
521
612
{
522
 
  uint32_t const length= get_length(from, low_byte_first);
523
 
  getTable()->setWriteSet(position());
524
 
  store(reinterpret_cast<const char*>(from) + sizeof(uint32_t),
 
613
  uint32_t const master_packlength=
 
614
    param_data > 0 ? param_data & 0xFF : packlength;
 
615
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
 
616
  table->setWriteSet(field_index);
 
617
  store(reinterpret_cast<const char*>(from) + master_packlength,
525
618
        length, field_charset);
526
 
  return(from + sizeof(uint32_t) + length);
 
619
  return(from + master_packlength + length);
527
620
}
528
621
 
529
622
/** Create a packed key that will be used for storage from a MySQL row. */
552
645
}
553
646
 
554
647
 
 
648
uint32_t Field_blob::is_equal(CreateField *new_field_ptr)
 
649
{
 
650
  if (compare_str_field_flags(new_field_ptr, flags))
 
651
    return 0;
 
652
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
 
653
 
 
654
  return (new_field_ptr->sql_type == DRIZZLE_TYPE_BLOB
 
655
          && new_field_ptr->charset == field_charset
 
656
          && blob_field_ptr->max_data_length() == max_data_length());
 
657
}
 
658
 
 
659
 
555
660
/**
556
661
  maximum possible display length for blob.
557
662
 
561
666
 
562
667
uint32_t Field_blob::max_display_length()
563
668
{
 
669
  switch (packlength)
 
670
  {
 
671
  case 1:
 
672
    return 255 * field_charset->mbmaxlen;
 
673
  case 2:
 
674
    return 65535 * field_charset->mbmaxlen;
 
675
  case 3:
 
676
    return 16777215 * field_charset->mbmaxlen;
 
677
  case 4:
564
678
    return (uint32_t) 4294967295U;
 
679
  default:
 
680
    assert(0); // we should never go here
 
681
    return 0;
 
682
  }
565
683
}
566
 
 
567
 
} /* namespace drizzled */