~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-03-21 01:02:23 UTC
  • mto: (960.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 961.
  • Revision ID: osullivan.padraig@gmail.com-20090321010223-j8cph7eeyt1u3xol
Fixed function object to ensure it correctly returns a boolean type since
memcmp returns an integer. Added some more comments.

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
 
#include <algorithm>
30
28
 
31
29
using namespace std;
32
30
 
33
 
namespace drizzled
34
 
{
35
 
 
36
 
static uint32_t blob_pack_length_to_max_length(uint32_t arg)
37
 
{
38
 
  return max(UINT32_MAX,
39
 
             (uint32_t)((INT64_C(1) << min(arg, 4U) * 8) - INT64_C(1)));
 
31
uint32_t
 
32
blob_pack_length_to_max_length(uint32_t arg)
 
33
{
 
34
  return (uint32_t)cmax(UINT32_MAX,
 
35
                        (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1));
40
36
}
41
37
 
42
38
 
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
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
48
                       const CHARSET_INFO * const cs)
 
49
  :Field_longstr(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
 
150
200
  char buff[STRING_BUFFER_USUAL_SIZE];
151
201
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
152
202
 
153
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
154
 
 
155
203
  if (!length)
156
204
  {
157
205
    memset(ptr, 0, Field_blob::pack_length());
160
208
 
161
209
  if (from == value.ptr())
162
210
  {
163
 
    size_t dummy_offset;
 
211
    uint32_t dummy_offset;
164
212
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
165
213
    {
166
214
      Field_blob::store_length(length);
167
 
      memmove(ptr+sizeof(uint32_t), &from, sizeof(char*));
 
215
      memmove(ptr+packlength, &from, sizeof(char*));
168
216
      return 0;
169
217
    }
170
218
    if (tmpstr.copy(from, length, cs))
172
220
    from= tmpstr.ptr();
173
221
  }
174
222
 
175
 
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
 
223
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
176
224
  if (value.alloc(new_length))
177
225
    goto oom_error;
178
226
 
 
227
 
 
228
  if (f_is_hex_escape(flags))
 
229
  {
 
230
    copy_length= my_copy_with_hex_escaping(field_charset,
 
231
                                           (char*) value.ptr(), new_length,
 
232
                                            from, length);
 
233
    Field_blob::store_length(copy_length);
 
234
    tmp= value.ptr();
 
235
    memmove(ptr + packlength, &tmp, sizeof(char*));
 
236
    return 0;
 
237
  }
179
238
  /*
180
239
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
181
240
    is never used to limit the length of the data. The cut of long data
191
250
 
192
251
  Field_blob::store_length(copy_length);
193
252
  tmp= value.ptr();
194
 
  memmove(ptr+sizeof(uint32_t), &tmp, sizeof(char*));
 
253
  memmove(ptr+packlength, &tmp, sizeof(char*));
195
254
 
196
255
  if (check_string_copy_error(this, well_formed_error_pos,
197
256
                              cannot_convert_error_pos, from + length, cs))
209
268
int Field_blob::store(double nr)
210
269
{
211
270
  const CHARSET_INFO * const cs=charset();
212
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
213
271
  value.set_real(nr, NOT_FIXED_DEC, cs);
214
272
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
215
273
}
218
276
int Field_blob::store(int64_t nr, bool unsigned_val)
219
277
{
220
278
  const CHARSET_INFO * const cs=charset();
221
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
222
279
  value.set_int(nr, unsigned_val, cs);
223
280
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
224
281
}
231
288
  uint32_t length;
232
289
  const CHARSET_INFO *cs;
233
290
 
234
 
  ASSERT_COLUMN_MARKED_FOR_READ;
235
 
 
236
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
291
  memcpy(&blob,ptr+packlength,sizeof(char*));
237
292
  if (!blob)
238
293
    return 0.0;
239
294
  length= get_length(ptr);
246
301
{
247
302
  int not_used;
248
303
  char *blob;
249
 
 
250
 
  ASSERT_COLUMN_MARKED_FOR_READ;
251
 
 
252
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
304
  memcpy(&blob,ptr+packlength,sizeof(char*));
253
305
  if (!blob)
254
306
    return 0;
255
307
  uint32_t length=get_length(ptr);
260
312
                            String *val_ptr)
261
313
{
262
314
  char *blob;
263
 
 
264
 
  ASSERT_COLUMN_MARKED_FOR_READ;
265
 
 
266
 
  memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
315
  memcpy(&blob,ptr+packlength,sizeof(char*));
267
316
  if (!blob)
268
317
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
269
318
  else
276
325
{
277
326
  const char *blob;
278
327
  size_t length;
279
 
 
280
 
  ASSERT_COLUMN_MARKED_FOR_READ;
281
 
 
282
 
  memcpy(&blob, ptr+sizeof(uint32_t), sizeof(const unsigned char*));
 
328
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
283
329
  if (!blob)
284
330
  {
285
331
    blob= "";
307
353
                        uint32_t max_length)
308
354
{
309
355
  unsigned char *blob1,*blob2;
310
 
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
311
 
  memcpy(&blob2,b_ptr+sizeof(uint32_t),sizeof(char*));
 
356
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
 
357
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
312
358
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
313
359
  set_if_smaller(a_len, max_length);
314
360
  set_if_smaller(b_len, max_length);
317
363
 
318
364
 
319
365
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
320
 
                           uint32_t max_length)
 
366
                           uint32_t max_length)
321
367
{
322
368
  char *a,*b;
323
369
  uint32_t diff;
324
370
  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*));
327
 
 
328
 
  a_length= get_length(a_ptr);
329
 
 
 
371
  memcpy(&a,a_ptr+packlength,sizeof(char*));
 
372
  memcpy(&b,b_ptr+packlength,sizeof(char*));
 
373
  a_length=get_length(a_ptr);
330
374
  if (a_length > max_length)
331
 
    a_length= max_length;
332
 
 
333
 
  b_length= get_length(b_ptr);
334
 
 
 
375
    a_length=max_length;
 
376
  b_length=get_length(b_ptr);
335
377
  if (b_length > max_length)
336
 
    b_length= max_length;
337
 
 
338
 
  diff= memcmp(a,b,min(a_length,b_length));
339
 
 
340
 
  return diff ? diff : (unsigned int) (a_length - b_length);
 
378
    b_length=max_length;
 
379
  diff=memcmp(a,b,cmin(a_length,b_length));
 
380
  return diff ? diff : (int) (a_length - b_length);
341
381
}
342
382
 
 
383
 
343
384
/* The following is used only when comparing a key */
344
 
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
 
385
 
 
386
uint32_t Field_blob::get_key_image(unsigned char *buff,
 
387
                                   uint32_t length,
 
388
                                   imagetype)
345
389
{
346
390
  uint32_t blob_length= get_length(ptr);
347
391
  unsigned char *blob;
355
399
  if ((uint32_t) length > blob_length)
356
400
  {
357
401
    /*
358
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
402
      Must clear this as we do a memcmp in opt_range.cc to detect
359
403
      identical keys
360
404
    */
361
405
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
367
411
}
368
412
 
369
413
 
370
 
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
 
414
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff,
 
415
                                   uint32_t length,
 
416
                                   imagetype)
371
417
{
372
418
  uint32_t blob_length= get_length(ptr);
373
419
  unsigned char *blob;
386
432
  if (length > blob_length)
387
433
  {
388
434
    /*
389
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
435
      Must clear this as we do a memcmp in opt_range.cc to detect
390
436
      identical keys
391
437
    */
392
438
 
395
441
  return HA_KEY_BLOB_LENGTH+length;
396
442
}
397
443
 
 
444
 
398
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
399
446
{
400
447
  length= uint2korr(buff);
401
 
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
 
448
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
 
449
                           field_charset);
402
450
}
403
451
 
 
452
 
404
453
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
405
454
{
406
455
  unsigned char *blob1;
407
456
  uint32_t blob_length=get_length(ptr);
408
 
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
 
457
  memcpy(&blob1,ptr+packlength,sizeof(char*));
409
458
  const CHARSET_INFO * const cs= charset();
410
459
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
411
460
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
422
471
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
423
472
}
424
473
 
 
474
 
 
475
/**
 
476
   Save the field metadata for blob fields.
 
477
 
 
478
   Saves the pack length in the first byte of the field metadata array
 
479
   at index of *metadata_ptr.
 
480
 
 
481
   @param   metadata_ptr   First byte of field metadata
 
482
 
 
483
   @returns number of bytes written to metadata_ptr
 
484
*/
 
485
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
486
{
 
487
  *metadata_ptr= pack_length_no_ptr();
 
488
  return 1;
 
489
}
 
490
 
 
491
 
425
492
uint32_t Field_blob::sort_length() const
426
493
{
427
494
  return (uint32_t) (current_session->variables.max_sort_length +
428
 
                     (field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
 
495
                   (field_charset == &my_charset_bin ? 0 : packlength));
429
496
}
430
497
 
 
498
 
431
499
void Field_blob::sort_string(unsigned char *to,uint32_t length)
432
500
{
433
501
  unsigned char *blob;
444
512
      /*
445
513
        Store length of blob last in blob to shorter blobs before longer blobs
446
514
      */
447
 
      length-= sizeof(uint32_t); // size of stored blob length
 
515
      length-= packlength;
448
516
      pos= to+length;
449
517
 
450
 
      mi_int4store(pos, blob_length);
 
518
      switch (packlength) {
 
519
      case 1:
 
520
        *pos= (char) blob_length;
 
521
        break;
 
522
      case 2:
 
523
        mi_int2store(pos, blob_length);
 
524
        break;
 
525
      case 3:
 
526
        mi_int3store(pos, blob_length);
 
527
        break;
 
528
      case 4:
 
529
        mi_int4store(pos, blob_length);
 
530
        break;
 
531
      }
451
532
    }
452
 
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
533
    memcpy(&blob,ptr+packlength,sizeof(char*));
453
534
 
454
535
    blob_length=my_strnxfrm(field_charset,
455
536
                            to, length, blob, blob_length);
457
538
  }
458
539
}
459
540
 
 
541
 
460
542
uint32_t Field_blob::pack_length() const
461
543
{
462
 
  return (uint32_t) (sizeof(uint32_t) + portable_sizeof_char_ptr);
 
544
  return (uint32_t) (packlength+table->s->blob_ptr_size);
463
545
}
464
546
 
 
547
 
465
548
void Field_blob::sql_type(String &res) const
466
549
{
467
550
  if (charset() == &my_charset_bin)
471
554
}
472
555
 
473
556
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
474
 
                                uint32_t max_length, bool low_byte_first)
 
557
                        uint32_t max_length, bool low_byte_first)
475
558
{
476
559
  unsigned char *save= ptr;
477
560
  ptr= (unsigned char*) from;
478
 
  uint32_t length= get_length();                        // Length of from string
 
561
  uint32_t length=get_length();                 // Length of from string
479
562
 
480
563
  /*
481
564
    Store max length, which will occupy packlength bytes. If the max
482
565
    length given is smaller than the actual length of the blob, we
483
566
    just store the initial bytes of the blob.
484
567
  */
485
 
  store_length(to, min(length, max_length), low_byte_first);
 
568
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
486
569
 
487
570
  /*
488
571
    Store the actual blob data, which will occupy 'length' bytes.
490
573
  if (length > 0)
491
574
  {
492
575
    get_ptr((unsigned char**) &from);
493
 
    memcpy(to+sizeof(uint32_t), from,length);
 
576
    memcpy(to+packlength, from,length);
494
577
  }
495
 
 
496
 
  ptr= save;                                    // Restore org row pointer
497
 
  return(to+sizeof(uint32_t)+length);
 
578
  ptr=save;                                     // Restore org row pointer
 
579
  return(to+packlength+length);
498
580
}
499
581
 
 
582
 
500
583
/**
501
584
   Unpack a blob field from row data.
502
585
 
515
598
   @return  New pointer into memory based on from + length of the data
516
599
*/
517
600
const unsigned char *Field_blob::unpack(unsigned char *,
518
 
                                        const unsigned char *from,
519
 
                                        uint32_t,
520
 
                                        bool low_byte_first)
 
601
                                const unsigned char *from,
 
602
                                uint32_t param_data,
 
603
                                bool low_byte_first)
521
604
{
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),
 
605
  uint32_t const master_packlength=
 
606
    param_data > 0 ? param_data & 0xFF : packlength;
 
607
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
 
608
  bitmap_set_bit(table->write_set, field_index);
 
609
  store(reinterpret_cast<const char*>(from) + master_packlength,
525
610
        length, field_charset);
526
 
  return(from + sizeof(uint32_t) + length);
 
611
  return(from + master_packlength + length);
 
612
}
 
613
 
 
614
/* Keys for blobs are like keys on varchars */
 
615
 
 
616
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
 
617
                         bool insert_or_update)
 
618
{
 
619
  uint32_t a_length, b_length;
 
620
  if (key_length_arg > 255)
 
621
  {
 
622
    a_length=uint2korr(a); a+=2;
 
623
    b_length=uint2korr(b); b+=2;
 
624
  }
 
625
  else
 
626
  {
 
627
    a_length= (uint32_t) *a++;
 
628
    b_length= (uint32_t) *b++;
 
629
  }
 
630
  return field_charset->coll->strnncollsp(field_charset,
 
631
                                          a, a_length,
 
632
                                          b, b_length,
 
633
                                          insert_or_update);
 
634
}
 
635
 
 
636
 
 
637
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
 
638
                         bool insert_or_update)
 
639
{
 
640
  unsigned char *a;
 
641
  uint32_t a_length, b_length;
 
642
  memcpy(&a,ptr+packlength,sizeof(char*));
 
643
  if (!a)
 
644
    return key_length_arg > 0 ? -1 : 0;
 
645
 
 
646
  a_length= get_length(ptr);
 
647
  if (key_length_arg > 255)
 
648
  {
 
649
    b_length= uint2korr(b); b+=2;
 
650
  }
 
651
  else
 
652
    b_length= (uint32_t) *b++;
 
653
  return field_charset->coll->strnncollsp(field_charset,
 
654
                                          a, a_length,
 
655
                                          b, b_length,
 
656
                                          insert_or_update);
527
657
}
528
658
 
529
659
/** Create a packed key that will be used for storage from a MySQL row. */
553
683
 
554
684
 
555
685
/**
 
686
  Unpack a blob key into a record buffer.
 
687
 
 
688
  A blob key has a maximum size of 64K-1.
 
689
  In its packed form, the length field is one or two bytes long,
 
690
  depending on 'max_length'.
 
691
  Depending on the maximum length of a blob, its length field is
 
692
  put into 1 to 4 bytes. This is a property of the blob object,
 
693
  described by 'packlength'.
 
694
  Blobs are internally stored apart from the record buffer, which
 
695
  contains a pointer to the blob buffer.
 
696
 
 
697
 
 
698
  @param to                          Pointer into the record buffer.
 
699
  @param from                        Pointer to the packed key.
 
700
  @param max_length                  Key length limit from key description.
 
701
 
 
702
  @return
 
703
    Pointer into 'from' past the last byte copied from packed key.
 
704
*/
 
705
 
 
706
const unsigned char *
 
707
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
708
                       bool )
 
709
{
 
710
  /* get length of the blob key */
 
711
  uint32_t length= *from++;
 
712
  if (max_length > 255)
 
713
    length+= *from++ << 8;
 
714
 
 
715
  /* put the length into the record buffer */
 
716
  put_length(to, length);
 
717
 
 
718
  /* put the address of the blob buffer or NULL */
 
719
  if (length)
 
720
    memcpy(to + packlength, &from, sizeof(from));
 
721
  else
 
722
    memset(to + packlength, 0, sizeof(from));
 
723
 
 
724
  /* point to first byte of next field in 'from' */
 
725
  return from + length;
 
726
}
 
727
 
 
728
 
 
729
/** Create a packed key that will be used for storage from a MySQL key. */
 
730
 
 
731
unsigned char *
 
732
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
733
                                    bool )
 
734
{
 
735
  uint32_t length=uint2korr(from);
 
736
  if (length > max_length)
 
737
    length=max_length;
 
738
  *to++= (char) (length & 255);
 
739
  if (max_length > 255)
 
740
    *to++= (char) (length >> 8);
 
741
  if (length)
 
742
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
 
743
  return to+length;
 
744
}
 
745
 
 
746
 
 
747
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
748
{
 
749
  if (length > 255)
 
750
    return uint2korr(data_ptr)+2;
 
751
  return (uint32_t) *data_ptr + 1;
 
752
}
 
753
 
 
754
 
 
755
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
 
756
{
 
757
  return (max_length > 255 ? 2 : 1)+max_length;
 
758
}
 
759
 
 
760
 
 
761
uint32_t Field_blob::is_equal(Create_field *new_field_ptr)
 
762
{
 
763
  if (compare_str_field_flags(new_field_ptr, flags))
 
764
    return 0;
 
765
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
 
766
 
 
767
  return ((new_field_ptr->sql_type == 
 
768
             get_blob_type_from_length(max_data_length()))
 
769
          && new_field_ptr->charset == field_charset
 
770
          && blob_field_ptr->max_data_length() == max_data_length());
 
771
}
 
772
 
 
773
 
 
774
/**
556
775
  maximum possible display length for blob.
557
776
 
558
777
  @return
561
780
 
562
781
uint32_t Field_blob::max_display_length()
563
782
{
 
783
  switch (packlength)
 
784
  {
 
785
  case 1:
 
786
    return 255 * field_charset->mbmaxlen;
 
787
  case 2:
 
788
    return 65535 * field_charset->mbmaxlen;
 
789
  case 3:
 
790
    return 16777215 * field_charset->mbmaxlen;
 
791
  case 4:
564
792
    return (uint32_t) 4294967295U;
565
 
}
566
 
 
567
 
} /* namespace drizzled */
 
793
  default:
 
794
    assert(0); // we should never go here
 
795
    return 0;
 
796
  }
 
797
}
 
798
 
 
799
bool Field_blob::in_read_set()
 
800
{
 
801
  return bitmap_is_set(table->read_set, field_index);
 
802
}
 
803
 
 
804
 
 
805
bool Field_blob::in_write_set()
 
806
{
 
807
  return bitmap_is_set(table->write_set, field_index);
 
808
}