~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-02-05 09:11:16 UTC
  • Revision ID: brian@tangent.org-20090205091116-iy0ersp6bhyzt1ad
Removed dead variables.

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
 
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
 
272
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
215
273
}
216
274
 
217
275
 
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
 
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
 
280
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
224
281
}
225
282
 
226
283
 
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
272
321
}
273
322
 
274
323
 
275
 
type::Decimal *Field_blob::val_decimal(type::Decimal *decimal_value)
 
324
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
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= "";
286
332
    length= 0;
287
333
  }
288
334
  else
289
 
  {
290
335
    length= get_length(ptr);
291
 
  }
292
 
 
293
 
  decimal_value->store(E_DEC_FATAL_ERROR, blob, length, charset());
294
 
 
 
336
 
 
337
  str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
 
338
                 decimal_value);
295
339
  return decimal_value;
296
340
}
297
341
 
309
353
                        uint32_t max_length)
310
354
{
311
355
  unsigned char *blob1,*blob2;
312
 
  memcpy(&blob1,a_ptr+sizeof(uint32_t),sizeof(char*));
313
 
  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*));
314
358
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
315
359
  set_if_smaller(a_len, max_length);
316
360
  set_if_smaller(b_len, max_length);
319
363
 
320
364
 
321
365
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
322
 
                           uint32_t max_length)
 
366
                           uint32_t max_length)
323
367
{
324
368
  char *a,*b;
325
369
  uint32_t diff;
326
370
  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*));
329
 
 
330
 
  a_length= get_length(a_ptr);
331
 
 
 
371
  memcpy(&a,a_ptr+packlength,sizeof(char*));
 
372
  memcpy(&b,b_ptr+packlength,sizeof(char*));
 
373
  a_length=get_length(a_ptr);
332
374
  if (a_length > max_length)
333
 
    a_length= max_length;
334
 
 
335
 
  b_length= get_length(b_ptr);
336
 
 
 
375
    a_length=max_length;
 
376
  b_length=get_length(b_ptr);
337
377
  if (b_length > max_length)
338
 
    b_length= max_length;
339
 
 
340
 
  diff= memcmp(a,b,min(a_length,b_length));
341
 
 
342
 
  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);
343
381
}
344
382
 
 
383
 
345
384
/* The following is used only when comparing a key */
346
 
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)
347
389
{
348
390
  uint32_t blob_length= get_length(ptr);
349
391
  unsigned char *blob;
357
399
  if ((uint32_t) length > blob_length)
358
400
  {
359
401
    /*
360
 
      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
361
403
      identical keys
362
404
    */
363
405
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
364
 
    length=(uint32_t) blob_length;
 
406
    length=(uint) blob_length;
365
407
  }
366
408
  int2store(buff,length);
367
409
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
369
411
}
370
412
 
371
413
 
372
 
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)
373
417
{
374
418
  uint32_t blob_length= get_length(ptr);
375
419
  unsigned char *blob;
388
432
  if (length > blob_length)
389
433
  {
390
434
    /*
391
 
      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
392
436
      identical keys
393
437
    */
394
438
 
397
441
  return HA_KEY_BLOB_LENGTH+length;
398
442
}
399
443
 
 
444
 
400
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
401
446
{
402
447
  length= uint2korr(buff);
403
 
  (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);
404
450
}
405
451
 
 
452
 
406
453
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
407
454
{
408
455
  unsigned char *blob1;
409
456
  uint32_t blob_length=get_length(ptr);
410
 
  memcpy(&blob1,ptr+sizeof(uint32_t),sizeof(char*));
 
457
  memcpy(&blob1,ptr+packlength,sizeof(char*));
411
458
  const CHARSET_INFO * const cs= charset();
412
459
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
413
460
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
424
471
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
425
472
}
426
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
 
427
492
uint32_t Field_blob::sort_length() const
428
493
{
429
 
  return (uint32_t) (getTable()->getSession()->variables.max_sort_length +
430
 
                     (field_charset == &my_charset_bin ? 0 : sizeof(uint32_t)));
 
494
  return (uint32_t) (current_session->variables.max_sort_length +
 
495
                   (field_charset == &my_charset_bin ? 0 : packlength));
431
496
}
432
497
 
 
498
 
433
499
void Field_blob::sort_string(unsigned char *to,uint32_t length)
434
500
{
435
501
  unsigned char *blob;
446
512
      /*
447
513
        Store length of blob last in blob to shorter blobs before longer blobs
448
514
      */
449
 
      length-= sizeof(uint32_t); // size of stored blob length
 
515
      length-= packlength;
450
516
      pos= to+length;
451
517
 
452
 
      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
      }
453
532
    }
454
 
    memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
 
533
    memcpy(&blob,ptr+packlength,sizeof(char*));
455
534
 
456
535
    blob_length=my_strnxfrm(field_charset,
457
536
                            to, length, blob, blob_length);
459
538
  }
460
539
}
461
540
 
 
541
 
462
542
uint32_t Field_blob::pack_length() const
463
543
{
464
 
  return (uint32_t) (sizeof(uint32_t) + portable_sizeof_char_ptr);
 
544
  return (uint32_t) (packlength+table->s->blob_ptr_size);
465
545
}
466
546
 
 
547
 
467
548
void Field_blob::sql_type(String &res) const
468
549
{
469
550
  if (charset() == &my_charset_bin)
473
554
}
474
555
 
475
556
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
476
 
                                uint32_t max_length, bool low_byte_first)
 
557
                        uint32_t max_length, bool low_byte_first)
477
558
{
478
559
  unsigned char *save= ptr;
479
560
  ptr= (unsigned char*) from;
480
 
  uint32_t length= get_length();                        // Length of from string
 
561
  uint32_t length=get_length();                 // Length of from string
481
562
 
482
563
  /*
483
564
    Store max length, which will occupy packlength bytes. If the max
484
565
    length given is smaller than the actual length of the blob, we
485
566
    just store the initial bytes of the blob.
486
567
  */
487
 
  store_length(to, min(length, max_length), low_byte_first);
 
568
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
488
569
 
489
570
  /*
490
571
    Store the actual blob data, which will occupy 'length' bytes.
492
573
  if (length > 0)
493
574
  {
494
575
    get_ptr((unsigned char**) &from);
495
 
    memcpy(to+sizeof(uint32_t), from,length);
 
576
    memcpy(to+packlength, from,length);
496
577
  }
497
 
 
498
 
  ptr= save;                                    // Restore org row pointer
499
 
  return(to+sizeof(uint32_t)+length);
 
578
  ptr=save;                                     // Restore org row pointer
 
579
  return(to+packlength+length);
500
580
}
501
581
 
 
582
 
502
583
/**
503
584
   Unpack a blob field from row data.
504
585
 
517
598
   @return  New pointer into memory based on from + length of the data
518
599
*/
519
600
const unsigned char *Field_blob::unpack(unsigned char *,
520
 
                                        const unsigned char *from,
521
 
                                        uint32_t,
522
 
                                        bool low_byte_first)
 
601
                                const unsigned char *from,
 
602
                                uint32_t param_data,
 
603
                                bool low_byte_first)
523
604
{
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),
 
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,
527
610
        length, field_charset);
528
 
  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= (uint) *a++;
 
628
    b_length= (uint) *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= (uint) *b++;
 
653
  return field_charset->coll->strnncollsp(field_charset,
 
654
                                          a, a_length,
 
655
                                          b, b_length,
 
656
                                          insert_or_update);
529
657
}
530
658
 
531
659
/** Create a packed key that will be used for storage from a MySQL row. */
555
683
 
556
684
 
557
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 (uint) *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
/**
558
775
  maximum possible display length for blob.
559
776
 
560
777
  @return
563
780
 
564
781
uint32_t Field_blob::max_display_length()
565
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:
566
792
    return (uint32_t) 4294967295U;
567
 
}
568
 
 
569
 
} /* 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
}