~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 23:47:43 UTC
  • mto: (584.1.10 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116234743-c38gmv0pa2kdefaj
Broke out cached_item.

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
 
#include <drizzled/table.h>
25
 
#include <drizzled/session.h>
26
 
#include "plugin/myisam/myisam.h"
27
 
 
28
 
#include <string>
29
 
#include <algorithm>
30
 
 
31
 
using namespace std;
32
 
 
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)));
 
24
 
 
25
uint32_t
 
26
blob_pack_length_to_max_length(uint32_t arg)
 
27
{
 
28
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
40
29
}
41
30
 
42
31
 
46
35
** packlength slot and may be from 1-4.
47
36
****************************************************************************/
48
37
 
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
 
                       uint32_t blob_pack_length,
55
 
                       const CHARSET_INFO * const cs)
56
 
  :Field_str(ptr_arg,
57
 
             blob_pack_length_to_max_length(blob_pack_length),
58
 
             null_ptr_arg,
59
 
             null_bit_arg,
60
 
             field_name_arg,
61
 
             cs),
 
38
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
39
                       enum utype unireg_check_arg, const char *field_name_arg,
 
40
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
41
                       const CHARSET_INFO * const cs)
 
42
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
43
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
 
44
                 cs),
62
45
   packlength(blob_pack_length)
63
46
{
64
47
  flags|= BLOB_FLAG;
66
49
  /* TODO: why do not fill table->s->blob_field array here? */
67
50
}
68
51
 
 
52
 
69
53
void Field_blob::store_length(unsigned char *i_ptr,
70
54
                              uint32_t i_packlength,
71
55
                              uint32_t i_number,
72
 
                              bool low_byte_first)
 
56
                              bool low_byte_first __attribute__((unused)))
73
57
{
74
 
#ifndef WORDS_BIGENDIAN
75
 
  (void)low_byte_first;
76
 
#endif
77
58
  switch (i_packlength) {
78
59
  case 1:
79
60
    i_ptr[0]= (unsigned char) i_number;
104
85
}
105
86
 
106
87
 
107
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
108
 
                  uint32_t i_number)
109
 
{
110
 
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
111
 
}
112
 
 
113
 
 
114
88
uint32_t Field_blob::get_length(const unsigned char *pos,
115
 
                                uint32_t packlength_arg,
116
 
                                bool low_byte_first)
 
89
                              uint32_t packlength_arg,
 
90
                              bool low_byte_first __attribute__((unused)))
117
91
{
118
 
#ifndef WORDS_BIGENDIAN
119
 
  (void)low_byte_first;
120
 
#endif
121
92
  switch (packlength_arg) {
122
93
  case 1:
123
94
    return (uint32_t) pos[0];
150
121
}
151
122
 
152
123
 
153
 
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
154
 
                                bool low_byte_first)
155
 
{
156
 
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
157
 
}
158
 
 
159
 
 
160
 
uint32_t Field_blob::get_length(uint32_t row_offset)
161
 
{
162
 
  return get_length(ptr+row_offset, this->packlength,
163
 
                    table->s->db_low_byte_first);
164
 
}
165
 
 
166
 
 
167
 
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
168
 
{
169
 
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
170
 
}
171
 
 
172
 
 
173
124
/**
174
125
  Put a blob length field into a record buffer.
175
126
 
209
160
  char buff[STRING_BUFFER_USUAL_SIZE];
210
161
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
211
162
 
212
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
213
 
 
214
163
  if (!length)
215
164
  {
216
165
    memset(ptr, 0, Field_blob::pack_length());
223
172
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
224
173
    {
225
174
      Field_blob::store_length(length);
226
 
      memmove(ptr+packlength, &from, sizeof(char*));
 
175
      memcpy(ptr+packlength, &from, sizeof(char*));
227
176
      return 0;
228
177
    }
229
178
    if (tmpstr.copy(from, length, cs))
231
180
    from= tmpstr.ptr();
232
181
  }
233
182
 
234
 
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
 
183
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
235
184
  if (value.alloc(new_length))
236
185
    goto oom_error;
237
186
 
 
187
 
 
188
  if (f_is_hex_escape(flags))
 
189
  {
 
190
    copy_length= my_copy_with_hex_escaping(field_charset,
 
191
                                           (char*) value.ptr(), new_length,
 
192
                                            from, length);
 
193
    Field_blob::store_length(copy_length);
 
194
    tmp= value.ptr();
 
195
    memcpy(ptr + packlength, &tmp, sizeof(char*));
 
196
    return 0;
 
197
  }
238
198
  /*
239
199
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
240
200
    is never used to limit the length of the data. The cut of long data
250
210
 
251
211
  Field_blob::store_length(copy_length);
252
212
  tmp= value.ptr();
253
 
  memmove(ptr+packlength, &tmp, sizeof(char*));
 
213
  memcpy(ptr+packlength, &tmp, sizeof(char*));
254
214
 
255
215
  if (check_string_copy_error(this, well_formed_error_pos,
256
216
                              cannot_convert_error_pos, from + length, cs))
261
221
oom_error:
262
222
  /* Fatal OOM error */
263
223
  memset(ptr, 0, Field_blob::pack_length());
264
 
  return -1;
 
224
  return -1; 
265
225
}
266
226
 
267
227
 
268
228
int Field_blob::store(double nr)
269
229
{
270
230
  const CHARSET_INFO * const cs=charset();
271
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
272
231
  value.set_real(nr, NOT_FIXED_DEC, cs);
273
 
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
 
232
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
274
233
}
275
234
 
276
235
 
277
236
int Field_blob::store(int64_t nr, bool unsigned_val)
278
237
{
279
238
  const CHARSET_INFO * const cs=charset();
280
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
281
239
  value.set_int(nr, unsigned_val, cs);
282
 
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
 
240
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
283
241
}
284
242
 
285
243
 
290
248
  uint32_t length;
291
249
  const CHARSET_INFO *cs;
292
250
 
293
 
  ASSERT_COLUMN_MARKED_FOR_READ;
294
 
 
295
251
  memcpy(&blob,ptr+packlength,sizeof(char*));
296
252
  if (!blob)
297
253
    return 0.0;
305
261
{
306
262
  int not_used;
307
263
  char *blob;
308
 
 
309
 
  ASSERT_COLUMN_MARKED_FOR_READ;
310
 
 
311
264
  memcpy(&blob,ptr+packlength,sizeof(char*));
312
265
  if (!blob)
313
266
    return 0;
315
268
  return my_strntoll(charset(),blob,length,10,NULL,&not_used);
316
269
}
317
270
 
318
 
String *Field_blob::val_str(String *,
 
271
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
319
272
                            String *val_ptr)
320
273
{
321
274
  char *blob;
322
 
 
323
 
  ASSERT_COLUMN_MARKED_FOR_READ;
324
 
 
325
275
  memcpy(&blob,ptr+packlength,sizeof(char*));
326
276
  if (!blob)
327
277
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
335
285
{
336
286
  const char *blob;
337
287
  size_t length;
338
 
 
339
 
  ASSERT_COLUMN_MARKED_FOR_READ;
340
 
 
341
288
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
342
289
  if (!blob)
343
290
  {
356
303
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
357
304
                    uint32_t b_length)
358
305
{
359
 
  return field_charset->coll->strnncollsp(field_charset,
 
306
  return field_charset->coll->strnncollsp(field_charset, 
360
307
                                          a, a_length, b, b_length,
361
308
                                          0);
362
309
}
376
323
 
377
324
 
378
325
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
379
 
                           uint32_t max_length)
 
326
                           uint32_t max_length)
380
327
{
381
328
  char *a,*b;
382
329
  uint32_t diff;
383
330
  uint32_t a_length,b_length;
384
331
  memcpy(&a,a_ptr+packlength,sizeof(char*));
385
332
  memcpy(&b,b_ptr+packlength,sizeof(char*));
386
 
 
387
 
  a_length= get_length(a_ptr);
388
 
 
 
333
  a_length=get_length(a_ptr);
389
334
  if (a_length > max_length)
390
 
    a_length= max_length;
391
 
 
392
 
  b_length= get_length(b_ptr);
393
 
 
 
335
    a_length=max_length;
 
336
  b_length=get_length(b_ptr);
394
337
  if (b_length > max_length)
395
 
    b_length= max_length;
396
 
 
397
 
  diff= memcmp(a,b,min(a_length,b_length));
398
 
 
 
338
    b_length=max_length;
 
339
  diff=memcmp(a,b,cmin(a_length,b_length));
399
340
  return diff ? diff : (int) (a_length - b_length);
400
341
}
401
342
 
 
343
 
402
344
/* The following is used only when comparing a key */
403
 
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
 
345
 
 
346
uint32_t Field_blob::get_key_image(unsigned char *buff,
 
347
                               uint32_t length,
 
348
                               imagetype type_arg __attribute__((unused)))
404
349
{
405
350
  uint32_t blob_length= get_length(ptr);
406
351
  unsigned char *blob;
414
359
  if ((uint32_t) length > blob_length)
415
360
  {
416
361
    /*
417
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
362
      Must clear this as we do a memcmp in opt_range.cc to detect
418
363
      identical keys
419
364
    */
420
365
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
421
 
    length=(uint32_t) blob_length;
 
366
    length=(uint) blob_length;
422
367
  }
423
368
  int2store(buff,length);
424
369
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
426
371
}
427
372
 
428
373
 
429
 
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
430
 
{
431
 
  uint32_t blob_length= get_length(ptr);
432
 
  unsigned char *blob;
433
 
 
434
 
  get_ptr(&blob);
435
 
  uint32_t local_char_length= length / field_charset->mbmaxlen;
436
 
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
437
 
                                local_char_length);
438
 
  set_if_smaller(blob_length, local_char_length);
439
 
 
440
 
  unsigned char len_buff[HA_KEY_BLOB_LENGTH];
441
 
  int2store(len_buff,length);
442
 
  buff.append(len_buff);
443
 
  buff.append(blob, blob_length);
444
 
 
445
 
  if (length > blob_length)
446
 
  {
447
 
    /*
448
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
449
 
      identical keys
450
 
    */
451
 
 
452
 
    buff.append(length-blob_length, '0');
453
 
  }
454
 
  return HA_KEY_BLOB_LENGTH+length;
455
 
}
456
 
 
457
374
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
458
375
{
459
376
  length= uint2korr(buff);
460
 
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
 
377
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
 
378
                           field_charset);
461
379
}
462
380
 
 
381
 
463
382
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
464
383
{
465
384
  unsigned char *blob1;
481
400
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
482
401
}
483
402
 
 
403
 
 
404
/**
 
405
   Save the field metadata for blob fields.
 
406
 
 
407
   Saves the pack length in the first byte of the field metadata array
 
408
   at index of *metadata_ptr.
 
409
 
 
410
   @param   metadata_ptr   First byte of field metadata
 
411
 
 
412
   @returns number of bytes written to metadata_ptr
 
413
*/
 
414
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
415
{
 
416
  *metadata_ptr= pack_length_no_ptr();
 
417
  return 1;
 
418
}
 
419
 
 
420
 
484
421
uint32_t Field_blob::sort_length() const
485
422
{
486
 
  return (uint32_t) (current_session->variables.max_sort_length +
 
423
  return (uint32_t) (current_session->variables.max_sort_length + 
487
424
                   (field_charset == &my_charset_bin ? 0 : packlength));
488
425
}
489
426
 
 
427
 
490
428
void Field_blob::sort_string(unsigned char *to,uint32_t length)
491
429
{
492
430
  unsigned char *blob;
522
460
      }
523
461
    }
524
462
    memcpy(&blob,ptr+packlength,sizeof(char*));
525
 
 
 
463
    
526
464
    blob_length=my_strnxfrm(field_charset,
527
465
                            to, length, blob, blob_length);
528
466
    assert(blob_length == length);
529
467
  }
530
468
}
531
469
 
532
 
uint32_t Field_blob::pack_length() const
533
 
{
534
 
  return (uint32_t) (packlength+table->s->blob_ptr_size);
535
 
}
536
470
 
537
471
void Field_blob::sql_type(String &res) const
538
472
{
543
477
}
544
478
 
545
479
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
546
 
                                uint32_t max_length, bool low_byte_first)
 
480
                        uint32_t max_length, bool low_byte_first)
547
481
{
548
482
  unsigned char *save= ptr;
549
483
  ptr= (unsigned char*) from;
550
 
  uint32_t length= get_length();                        // Length of from string
 
484
  uint32_t length=get_length();                 // Length of from string
551
485
 
552
486
  /*
553
487
    Store max length, which will occupy packlength bytes. If the max
554
488
    length given is smaller than the actual length of the blob, we
555
489
    just store the initial bytes of the blob.
556
490
  */
557
 
  store_length(to, packlength, min(length, max_length), low_byte_first);
 
491
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
558
492
 
559
493
  /*
560
494
    Store the actual blob data, which will occupy 'length' bytes.
564
498
    get_ptr((unsigned char**) &from);
565
499
    memcpy(to+packlength, from,length);
566
500
  }
567
 
 
568
 
  ptr= save;                                    // Restore org row pointer
 
501
  ptr=save;                                     // Restore org row pointer
569
502
  return(to+packlength+length);
570
503
}
571
504
 
 
505
 
572
506
/**
573
507
   Unpack a blob field from row data.
574
508
 
575
 
   This method is used to unpack a blob field from a master whose size of
 
509
   This method is used to unpack a blob field from a master whose size of 
576
510
   the field is less than that of the slave. Note: This method is included
577
511
   to satisfy inheritance rules, but is not needed for blob fields. It
578
512
   simply is used as a pass-through to the original unpack() method for
586
520
 
587
521
   @return  New pointer into memory based on from + length of the data
588
522
*/
589
 
const unsigned char *Field_blob::unpack(unsigned char *,
590
 
                                        const unsigned char *from,
591
 
                                        uint32_t param_data,
592
 
                                        bool low_byte_first)
 
523
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
 
524
                                const unsigned char *from,
 
525
                                uint32_t param_data,
 
526
                                bool low_byte_first)
593
527
{
594
528
  uint32_t const master_packlength=
595
529
    param_data > 0 ? param_data & 0xFF : packlength;
596
530
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
597
 
  table->setWriteSet(field_index);
 
531
  bitmap_set_bit(table->write_set, field_index);
598
532
  store(reinterpret_cast<const char*>(from) + master_packlength,
599
533
        length, field_charset);
600
534
  return(from + master_packlength + length);
601
535
}
602
536
 
 
537
/* Keys for blobs are like keys on varchars */
 
538
 
 
539
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
 
540
                         bool insert_or_update)
 
541
{
 
542
  uint32_t a_length, b_length;
 
543
  if (key_length_arg > 255)
 
544
  {
 
545
    a_length=uint2korr(a); a+=2;
 
546
    b_length=uint2korr(b); b+=2;
 
547
  }
 
548
  else
 
549
  {
 
550
    a_length= (uint) *a++;
 
551
    b_length= (uint) *b++;
 
552
  }
 
553
  return field_charset->coll->strnncollsp(field_charset,
 
554
                                          a, a_length,
 
555
                                          b, b_length,
 
556
                                          insert_or_update);
 
557
}
 
558
 
 
559
 
 
560
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
 
561
                         bool insert_or_update)
 
562
{
 
563
  unsigned char *a;
 
564
  uint32_t a_length, b_length;
 
565
  memcpy(&a,ptr+packlength,sizeof(char*));
 
566
  if (!a)
 
567
    return key_length_arg > 0 ? -1 : 0;
 
568
 
 
569
  a_length= get_length(ptr);
 
570
  if (key_length_arg > 255)
 
571
  {
 
572
    b_length= uint2korr(b); b+=2;
 
573
  }
 
574
  else
 
575
    b_length= (uint) *b++;
 
576
  return field_charset->coll->strnncollsp(field_charset,
 
577
                                          a, a_length,
 
578
                                          b, b_length,
 
579
                                          insert_or_update);
 
580
}
 
581
 
603
582
/** Create a packed key that will be used for storage from a MySQL row. */
604
583
 
605
584
unsigned char *
606
585
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
607
 
                     bool )
 
586
                     bool low_byte_first __attribute__((unused)))
608
587
{
609
588
  unsigned char *save= ptr;
610
589
  ptr= (unsigned char*) from;
627
606
 
628
607
 
629
608
/**
 
609
  Unpack a blob key into a record buffer.
 
610
 
 
611
  A blob key has a maximum size of 64K-1.
 
612
  In its packed form, the length field is one or two bytes long,
 
613
  depending on 'max_length'.
 
614
  Depending on the maximum length of a blob, its length field is
 
615
  put into 1 to 4 bytes. This is a property of the blob object,
 
616
  described by 'packlength'.
 
617
  Blobs are internally stored apart from the record buffer, which
 
618
  contains a pointer to the blob buffer.
 
619
 
 
620
 
 
621
  @param to                          Pointer into the record buffer.
 
622
  @param from                        Pointer to the packed key.
 
623
  @param max_length                  Key length limit from key description.
 
624
 
 
625
  @return
 
626
    Pointer into 'from' past the last byte copied from packed key.
 
627
*/
 
628
 
 
629
const unsigned char *
 
630
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
631
                       bool low_byte_first __attribute__((unused)))
 
632
{
 
633
  /* get length of the blob key */
 
634
  uint32_t length= *from++;
 
635
  if (max_length > 255)
 
636
    length+= *from++ << 8;
 
637
 
 
638
  /* put the length into the record buffer */
 
639
  put_length(to, length);
 
640
 
 
641
  /* put the address of the blob buffer or NULL */
 
642
  if (length)
 
643
    memcpy(to + packlength, &from, sizeof(from));
 
644
  else
 
645
    memset(to + packlength, 0, sizeof(from));
 
646
 
 
647
  /* point to first byte of next field in 'from' */
 
648
  return from + length;
 
649
}
 
650
 
 
651
 
 
652
/** Create a packed key that will be used for storage from a MySQL key. */
 
653
 
 
654
unsigned char *
 
655
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
656
                                    bool low_byte_first __attribute__((unused)))
 
657
{
 
658
  uint32_t length=uint2korr(from);
 
659
  if (length > max_length)
 
660
    length=max_length;
 
661
  *to++= (char) (length & 255);
 
662
  if (max_length > 255)
 
663
    *to++= (char) (length >> 8);
 
664
  if (length)
 
665
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
 
666
  return to+length;
 
667
}
 
668
 
 
669
 
 
670
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
671
{
 
672
  if (length > 255)
 
673
    return uint2korr(data_ptr)+2;
 
674
  return (uint) *data_ptr + 1;
 
675
}
 
676
 
 
677
 
 
678
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
 
679
{
 
680
  return (max_length > 255 ? 2 : 1)+max_length;
 
681
}
 
682
 
 
683
 
 
684
uint32_t Field_blob::is_equal(Create_field *new_field)
 
685
{
 
686
  if (compare_str_field_flags(new_field, flags))
 
687
    return 0;
 
688
 
 
689
  return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
 
690
          && new_field->charset == field_charset &&
 
691
          ((Field_blob *)new_field->field)->max_data_length() ==
 
692
          max_data_length());
 
693
}
 
694
 
 
695
 
 
696
/**
630
697
  maximum possible display length for blob.
631
698
 
632
699
  @return
651
718
  }
652
719
}
653
720
 
654
 
} /* namespace drizzled */