~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-08-17 01:44:23 UTC
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090817014423-jxi2qonsumm8mndf
Remove SQL level reference for DELAY (just now done correctly by default in
engine).

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,
 
106
                                uint32_t packlength_arg,
93
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);
 
147
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
113
148
}
114
149
 
115
150
 
116
151
uint32_t Field_blob::get_length(uint32_t row_offset)
117
152
{
118
 
  return get_length(ptr+row_offset,
119
 
                    getTable()->getShare()->db_low_byte_first);
 
153
  return get_length(ptr+row_offset, this->packlength,
 
154
                    table->s->db_low_byte_first);
120
155
}
121
156
 
122
157
 
123
158
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
124
159
{
125
 
  return get_length(ptr_arg, getTable()->getShare()->db_low_byte_first);
 
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))
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);
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
316
  uint32_t length=get_length(ptr);
263
324
 
264
325
  ASSERT_COLUMN_MARKED_FOR_READ;
265
326
 
266
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
327
  memcpy(&blob,ptr+packlength,sizeof(char*));
267
328
  if (!blob)
268
329
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
269
330
  else
272
333
}
273
334
 
274
335
 
275
 
type::Decimal *Field_blob::val_decimal(type::Decimal *decimal_value)
 
336
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
276
337
{
277
338
  const char *blob;
278
339
  size_t length;
279
340
 
280
341
  ASSERT_COLUMN_MARKED_FOR_READ;
281
342
 
282
 
  memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
 
343
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
283
344
  if (!blob)
284
345
  {
285
346
    blob= "";
286
347
    length= 0;
287
348
  }
288
349
  else
289
 
  {
290
350
    length= get_length(ptr);
291
 
  }
292
 
 
293
 
  decimal_value->store(E_DEC_FATAL_ERROR, blob, length, charset());
294
 
 
 
351
 
 
352
  str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
 
353
                 decimal_value);
295
354
  return decimal_value;
296
355
}
297
356
 
309
368
                        uint32_t max_length)
310
369
{
311
370
  unsigned char *blob1,*blob2;
312
 
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
313
 
  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*));
314
373
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
315
374
  set_if_smaller(a_len, max_length);
316
375
  set_if_smaller(b_len, max_length);
324
383
  char *a,*b;
325
384
  uint32_t diff;
326
385
  uint32_t a_length,b_length;
327
 
  memcpy(&a,a_ptr+sizeof(uint32_t),sizeof(char*));
328
 
  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*));
329
388
 
330
389
  a_length= get_length(a_ptr);
331
390
 
339
398
 
340
399
  diff= memcmp(a,b,min(a_length,b_length));
341
400
 
342
 
  return diff ? diff : (unsigned int) (a_length - b_length);
 
401
  return diff ? diff : (int) (a_length - b_length);
343
402
}
344
403
 
345
404
/* The following is used only when comparing a key */
357
416
  if ((uint32_t) length > blob_length)
358
417
  {
359
418
    /*
360
 
      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
361
420
      identical keys
362
421
    */
363
422
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
388
447
  if (length > blob_length)
389
448
  {
390
449
    /*
391
 
      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
392
451
      identical keys
393
452
    */
394
453
 
407
466
{
408
467
  unsigned char *blob1;
409
468
  uint32_t blob_length=get_length(ptr);
410
 
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
 
469
  memcpy(&blob1,ptr+packlength,sizeof(char*));
411
470
  const CHARSET_INFO * const cs= charset();
412
471
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
413
472
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
424
483
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
425
484
}
426
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
 
427
502
uint32_t Field_blob::sort_length() const
428
503
{
429
 
  return (uint32_t) (getTable()->getSession()->variables.max_sort_length +
430
 
                     (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));
431
506
}
432
507
 
433
508
void Field_blob::sort_string(unsigned char *to,uint32_t length)
446
521
      /*
447
522
        Store length of blob last in blob to shorter blobs before longer blobs
448
523
      */
449
 
      length-= sizeof(uint32_t); // size of stored blob length
 
524
      length-= packlength;
450
525
      pos= to+length;
451
526
 
452
 
      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
      }
453
541
    }
454
 
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
542
    memcpy(&blob,ptr+packlength,sizeof(char*));
455
543
 
456
544
    blob_length=my_strnxfrm(field_charset,
457
545
                            to, length, blob, blob_length);
461
549
 
462
550
uint32_t Field_blob::pack_length() const
463
551
{
464
 
  return (uint32_t) (sizeof(uint32_t) + portable_sizeof_char_ptr);
 
552
  return (uint32_t) (packlength+table->s->blob_ptr_size);
465
553
}
466
554
 
467
555
void Field_blob::sql_type(String &res) const
484
572
    length given is smaller than the actual length of the blob, we
485
573
    just store the initial bytes of the blob.
486
574
  */
487
 
  store_length(to, min(length, max_length), low_byte_first);
 
575
  store_length(to, packlength, min(length, max_length), low_byte_first);
488
576
 
489
577
  /*
490
578
    Store the actual blob data, which will occupy 'length' bytes.
492
580
  if (length > 0)
493
581
  {
494
582
    get_ptr((unsigned char**) &from);
495
 
    memcpy(to+sizeof(uint32_t), from,length);
 
583
    memcpy(to+packlength, from,length);
496
584
  }
497
585
 
498
586
  ptr= save;                                    // Restore org row pointer
499
 
  return(to+sizeof(uint32_t)+length);
 
587
  return(to+packlength+length);
500
588
}
501
589
 
502
590
/**
517
605
   @return  New pointer into memory based on from + length of the data
518
606
*/
519
607
const unsigned char *Field_blob::unpack(unsigned char *,
520
 
                                        const unsigned char *from,
521
 
                                        uint32_t,
522
 
                                        bool low_byte_first)
 
608
                                const unsigned char *from,
 
609
                                uint32_t param_data,
 
610
                                bool low_byte_first)
523
611
{
524
 
  uint32_t const length= get_length(from, low_byte_first);
525
 
  getTable()->setWriteSet(position());
526
 
  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,
527
617
        length, field_charset);
528
 
  return(from + sizeof(uint32_t) + length);
 
618
  return(from + master_packlength + length);
529
619
}
530
620
 
531
621
/** Create a packed key that will be used for storage from a MySQL row. */
554
644
}
555
645
 
556
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
 
557
659
/**
558
660
  maximum possible display length for blob.
559
661
 
563
665
 
564
666
uint32_t Field_blob::max_display_length()
565
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:
566
677
    return (uint32_t) 4294967295U;
 
678
  default:
 
679
    assert(0); // we should never go here
 
680
    return 0;
 
681
  }
567
682
}
568
 
 
569
 
} /* namespace drizzled */