~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-08-18 07:19:56 UTC
  • mfrom: (1116.1.3 stewart)
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090818071956-nfpoe9rp3i7p50kx
Merge my branch from Stewart into one branch

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