~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2010-11-08 19:24:42 UTC
  • mfrom: (1267.1.8 blob-packlength)
  • Revision ID: brian@tangent.org-20101108192442-lzgg9wf818yl6oyn
Merge in Stewart's change to blob field size.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
/****************************************************************************
44
44
** blob type
45
45
** A blob is saved as a length and a pointer. The length is stored in the
46
 
** packlength slot and may be from 1-4.
 
46
** packlength slot and is sizeof(uint32_t) (4 bytes)
47
47
****************************************************************************/
48
48
 
49
49
Field_blob::Field_blob(unsigned char *ptr_arg,
51
51
                       unsigned char null_bit_arg,
52
52
                                   const char *field_name_arg,
53
53
                       TableShare *share,
54
 
                       uint32_t blob_pack_length,
55
54
                       const CHARSET_INFO * const cs)
56
55
  :Field_str(ptr_arg,
57
 
             blob_pack_length_to_max_length(blob_pack_length),
 
56
             blob_pack_length_to_max_length(sizeof(uint32_t)),
58
57
             null_ptr_arg,
59
58
             null_bit_arg,
60
59
             field_name_arg,
61
 
             cs),
62
 
   packlength(blob_pack_length)
 
60
             cs)
63
61
{
64
62
  flags|= BLOB_FLAG;
65
63
  share->blob_fields++;
67
65
}
68
66
 
69
67
void Field_blob::store_length(unsigned char *i_ptr,
70
 
                              uint32_t i_packlength,
71
68
                              uint32_t i_number,
72
69
                              bool low_byte_first)
73
70
{
74
71
#ifndef WORDS_BIGENDIAN
75
72
  (void)low_byte_first;
76
73
#endif
77
 
  switch (i_packlength) {
78
 
  case 1:
79
 
    i_ptr[0]= (unsigned char) i_number;
80
 
    break;
81
 
  case 2:
82
 
#ifdef WORDS_BIGENDIAN
83
 
    if (low_byte_first)
84
 
    {
85
 
      int2store(i_ptr,(unsigned short) i_number);
86
 
    }
87
 
    else
88
 
#endif
89
 
      shortstore(i_ptr,(unsigned short) i_number);
90
 
    break;
91
 
  case 3:
92
 
    int3store(i_ptr,i_number);
93
 
    break;
94
 
  case 4:
95
 
#ifdef WORDS_BIGENDIAN
96
 
    if (low_byte_first)
97
 
    {
98
 
      int4store(i_ptr,i_number);
99
 
    }
100
 
    else
101
 
#endif
102
 
      longstore(i_ptr,i_number);
 
74
 
 
75
#ifdef WORDS_BIGENDIAN
 
76
  if (low_byte_first)
 
77
  {
 
78
    int4store(i_ptr,i_number);
103
79
  }
 
80
  else
 
81
#endif
 
82
    longstore(i_ptr,i_number);
104
83
}
105
84
 
106
85
 
107
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
108
 
                  uint32_t i_number)
 
86
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_number)
109
87
{
110
 
  store_length(i_ptr, i_packlength, i_number, getTable()->getShare()->db_low_byte_first);
 
88
  store_length(i_ptr, i_number, getTable()->getShare()->db_low_byte_first);
111
89
}
112
90
 
113
91
 
114
92
uint32_t Field_blob::get_length(const unsigned char *pos,
115
 
                                uint32_t packlength_arg,
116
93
                                bool low_byte_first)
117
94
{
118
95
#ifndef WORDS_BIGENDIAN
119
96
  (void)low_byte_first;
120
97
#endif
121
 
  switch (packlength_arg) {
122
 
  case 1:
123
 
    return (uint32_t) pos[0];
124
 
  case 2:
125
 
    {
126
 
      uint16_t tmp;
127
 
#ifdef WORDS_BIGENDIAN
128
 
      if (low_byte_first)
129
 
        tmp=sint2korr(pos);
130
 
      else
131
 
#endif
132
 
        shortget(tmp,pos);
133
 
      return (uint32_t) tmp;
134
 
    }
135
 
  case 3:
136
 
    return (uint32_t) uint3korr(pos);
137
 
  case 4:
138
 
    {
139
 
      uint32_t tmp;
140
 
#ifdef WORDS_BIGENDIAN
141
 
      if (low_byte_first)
142
 
        tmp=uint4korr(pos);
143
 
      else
144
 
#endif
145
 
        longget(tmp,pos);
146
 
      return (uint32_t) tmp;
147
 
    }
148
 
  }
149
 
  return 0;                                     // Impossible
 
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;
150
106
}
151
107
 
152
108
 
153
109
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
154
110
                                bool low_byte_first)
155
111
{
156
 
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
 
112
  return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
157
113
}
158
114
 
159
115
 
160
116
uint32_t Field_blob::get_length(uint32_t row_offset)
161
117
{
162
 
  return get_length(ptr+row_offset, this->packlength,
 
118
  return get_length(ptr+row_offset,
163
119
                    getTable()->getShare()->db_low_byte_first);
164
120
}
165
121
 
166
122
 
167
123
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
168
124
{
169
 
  return get_length(ptr_arg, this->packlength, getTable()->getShare()->db_low_byte_first);
 
125
  return get_length(ptr_arg, getTable()->getShare()->db_low_byte_first);
170
126
}
171
127
 
172
128
 
173
129
/**
174
130
  Put a blob length field into a record buffer.
175
131
 
176
 
  Depending on the maximum length of a blob, its length field is
177
 
  put into 1 to 4 bytes. This is a property of the blob object,
178
 
  described by 'packlength'.
 
132
  Blob length is always stored in sizeof(uint32_t) (4 bytes)
179
133
 
180
134
  @param pos                 Pointer into the record buffer.
181
135
  @param length              The length value to put.
183
137
 
184
138
void Field_blob::put_length(unsigned char *pos, uint32_t length)
185
139
{
186
 
  switch (packlength) {
187
 
  case 1:
188
 
    *pos= (char) length;
189
 
    break;
190
 
  case 2:
191
 
    int2store(pos, length);
192
 
    break;
193
 
  case 3:
194
 
    int3store(pos, length);
195
 
    break;
196
 
  case 4:
197
140
    int4store(pos, length);
198
 
    break;
199
 
  }
200
141
}
201
142
 
202
143
 
223
164
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
224
165
    {
225
166
      Field_blob::store_length(length);
226
 
      memmove(ptr+packlength, &from, sizeof(char*));
 
167
      memmove(ptr+sizeof(uint32_t), &from, sizeof(char*));
227
168
      return 0;
228
169
    }
229
170
    if (tmpstr.copy(from, length, cs))
250
191
 
251
192
  Field_blob::store_length(copy_length);
252
193
  tmp= value.ptr();
253
 
  memmove(ptr+packlength, &tmp, sizeof(char*));
 
194
  memmove(ptr+sizeof(uint32_t), &tmp, sizeof(char*));
254
195
 
255
196
  if (check_string_copy_error(this, well_formed_error_pos,
256
197
                              cannot_convert_error_pos, from + length, cs))
292
233
 
293
234
  ASSERT_COLUMN_MARKED_FOR_READ;
294
235
 
295
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
236
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
296
237
  if (!blob)
297
238
    return 0.0;
298
239
  length= get_length(ptr);
308
249
 
309
250
  ASSERT_COLUMN_MARKED_FOR_READ;
310
251
 
311
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
252
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
312
253
  if (!blob)
313
254
    return 0;
314
255
  uint32_t length=get_length(ptr);
322
263
 
323
264
  ASSERT_COLUMN_MARKED_FOR_READ;
324
265
 
325
 
  memcpy(&blob,ptr+packlength,sizeof(char*));
 
266
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
326
267
  if (!blob)
327
268
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
328
269
  else
338
279
 
339
280
  ASSERT_COLUMN_MARKED_FOR_READ;
340
281
 
341
 
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
 
282
  memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
342
283
  if (!blob)
343
284
  {
344
285
    blob= "";
366
307
                        uint32_t max_length)
367
308
{
368
309
  unsigned char *blob1,*blob2;
369
 
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
370
 
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
 
310
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
 
311
  memcpy(&blob2,b_ptr+sizeof(uint32_t),sizeof(char*));
371
312
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
372
313
  set_if_smaller(a_len, max_length);
373
314
  set_if_smaller(b_len, max_length);
381
322
  char *a,*b;
382
323
  uint32_t diff;
383
324
  uint32_t a_length,b_length;
384
 
  memcpy(&a,a_ptr+packlength,sizeof(char*));
385
 
  memcpy(&b,b_ptr+packlength,sizeof(char*));
 
325
  memcpy(&a,a_ptr+sizeof(uint32_t),sizeof(char*));
 
326
  memcpy(&b,b_ptr+sizeof(uint32_t),sizeof(char*));
386
327
 
387
328
  a_length= get_length(a_ptr);
388
329
 
464
405
{
465
406
  unsigned char *blob1;
466
407
  uint32_t blob_length=get_length(ptr);
467
 
  memcpy(&blob1,ptr+packlength,sizeof(char*));
 
408
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
468
409
  const CHARSET_INFO * const cs= charset();
469
410
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
470
411
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
484
425
uint32_t Field_blob::sort_length() const
485
426
{
486
427
  return (uint32_t) (current_session->variables.max_sort_length +
487
 
                   (field_charset == &my_charset_bin ? 0 : packlength));
 
428
                     (field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
488
429
}
489
430
 
490
431
void Field_blob::sort_string(unsigned char *to,uint32_t length)
503
444
      /*
504
445
        Store length of blob last in blob to shorter blobs before longer blobs
505
446
      */
506
 
      length-= packlength;
 
447
      length-= sizeof(uint32_t); // size of stored blob length
507
448
      pos= to+length;
508
449
 
509
 
      switch (packlength) {
510
 
      case 1:
511
 
        *pos= (char) blob_length;
512
 
        break;
513
 
      case 2:
514
 
        mi_int2store(pos, blob_length);
515
 
        break;
516
 
      case 3:
517
 
        mi_int3store(pos, blob_length);
518
 
        break;
519
 
      case 4:
520
 
        mi_int4store(pos, blob_length);
521
 
        break;
522
 
      }
 
450
      mi_int4store(pos, blob_length);
523
451
    }
524
 
    memcpy(&blob,ptr+packlength,sizeof(char*));
 
452
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
525
453
 
526
454
    blob_length=my_strnxfrm(field_charset,
527
455
                            to, length, blob, blob_length);
531
459
 
532
460
uint32_t Field_blob::pack_length() const
533
461
{
534
 
  return (uint32_t) (packlength + portable_sizeof_char_ptr);
 
462
  return (uint32_t) (sizeof(uint32_t) + portable_sizeof_char_ptr);
535
463
}
536
464
 
537
465
void Field_blob::sql_type(String &res) const
554
482
    length given is smaller than the actual length of the blob, we
555
483
    just store the initial bytes of the blob.
556
484
  */
557
 
  store_length(to, packlength, min(length, max_length), low_byte_first);
 
485
  store_length(to, min(length, max_length), low_byte_first);
558
486
 
559
487
  /*
560
488
    Store the actual blob data, which will occupy 'length' bytes.
562
490
  if (length > 0)
563
491
  {
564
492
    get_ptr((unsigned char**) &from);
565
 
    memcpy(to+packlength, from,length);
 
493
    memcpy(to+sizeof(uint32_t), from,length);
566
494
  }
567
495
 
568
496
  ptr= save;                                    // Restore org row pointer
569
 
  return(to+packlength+length);
 
497
  return(to+sizeof(uint32_t)+length);
570
498
}
571
499
 
572
500
/**
588
516
*/
589
517
const unsigned char *Field_blob::unpack(unsigned char *,
590
518
                                        const unsigned char *from,
591
 
                                        uint32_t param_data,
 
519
                                        uint32_t,
592
520
                                        bool low_byte_first)
593
521
{
594
 
  uint32_t const master_packlength=
595
 
    param_data > 0 ? param_data & 0xFF : packlength;
596
 
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
 
522
  uint32_t const length= get_length(from, low_byte_first);
597
523
  getTable()->setWriteSet(field_index);
598
 
  store(reinterpret_cast<const char*>(from) + master_packlength,
 
524
  store(reinterpret_cast<const char*>(from) + sizeof(uint32_t),
599
525
        length, field_charset);
600
 
  return(from + master_packlength + length);
 
526
  return(from + sizeof(uint32_t) + length);
601
527
}
602
528
 
603
529
/** Create a packed key that will be used for storage from a MySQL row. */
635
561
 
636
562
uint32_t Field_blob::max_display_length()
637
563
{
638
 
  switch (packlength)
639
 
  {
640
 
  case 1:
641
 
    return 255 * field_charset->mbmaxlen;
642
 
  case 2:
643
 
    return 65535 * field_charset->mbmaxlen;
644
 
  case 3:
645
 
    return 16777215 * field_charset->mbmaxlen;
646
 
  case 4:
647
564
    return (uint32_t) 4294967295U;
648
 
  default:
649
 
    assert(0); // we should never go here
650
 
    return 0;
651
 
  }
652
565
}
653
566
 
654
567
} /* namespace drizzled */