~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

Moved the last of the libdrizzleclient calls into Protocol.

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
 
46
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
 
                       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),
 
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),
62
52
   packlength(blob_pack_length)
63
53
{
64
54
  flags|= BLOB_FLAG;
66
56
  /* TODO: why do not fill table->s->blob_field array here? */
67
57
}
68
58
 
 
59
 
69
60
void Field_blob::store_length(unsigned char *i_ptr,
70
61
                              uint32_t i_packlength,
71
62
                              uint32_t i_number,
209
200
  char buff[STRING_BUFFER_USUAL_SIZE];
210
201
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
211
202
 
212
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
213
 
 
214
203
  if (!length)
215
204
  {
216
205
    memset(ptr, 0, Field_blob::pack_length());
231
220
    from= tmpstr.ptr();
232
221
  }
233
222
 
234
 
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
 
223
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
235
224
  if (value.alloc(new_length))
236
225
    goto oom_error;
237
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
  }
238
238
  /*
239
239
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
240
240
    is never used to limit the length of the data. The cut of long data
268
268
int Field_blob::store(double nr)
269
269
{
270
270
  const CHARSET_INFO * const cs=charset();
271
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
272
271
  value.set_real(nr, NOT_FIXED_DEC, cs);
273
272
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
274
273
}
277
276
int Field_blob::store(int64_t nr, bool unsigned_val)
278
277
{
279
278
  const CHARSET_INFO * const cs=charset();
280
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
281
279
  value.set_int(nr, unsigned_val, cs);
282
280
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
283
281
}
290
288
  uint32_t length;
291
289
  const CHARSET_INFO *cs;
292
290
 
293
 
  ASSERT_COLUMN_MARKED_FOR_READ;
294
 
 
295
291
  memcpy(&blob,ptr+packlength,sizeof(char*));
296
292
  if (!blob)
297
293
    return 0.0;
305
301
{
306
302
  int not_used;
307
303
  char *blob;
308
 
 
309
 
  ASSERT_COLUMN_MARKED_FOR_READ;
310
 
 
311
304
  memcpy(&blob,ptr+packlength,sizeof(char*));
312
305
  if (!blob)
313
306
    return 0;
319
312
                            String *val_ptr)
320
313
{
321
314
  char *blob;
322
 
 
323
 
  ASSERT_COLUMN_MARKED_FOR_READ;
324
 
 
325
315
  memcpy(&blob,ptr+packlength,sizeof(char*));
326
316
  if (!blob)
327
317
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
335
325
{
336
326
  const char *blob;
337
327
  size_t length;
338
 
 
339
 
  ASSERT_COLUMN_MARKED_FOR_READ;
340
 
 
341
328
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
342
329
  if (!blob)
343
330
  {
376
363
 
377
364
 
378
365
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
379
 
                           uint32_t max_length)
 
366
                           uint32_t max_length)
380
367
{
381
368
  char *a,*b;
382
369
  uint32_t diff;
383
370
  uint32_t a_length,b_length;
384
371
  memcpy(&a,a_ptr+packlength,sizeof(char*));
385
372
  memcpy(&b,b_ptr+packlength,sizeof(char*));
386
 
 
387
 
  a_length= get_length(a_ptr);
388
 
 
 
373
  a_length=get_length(a_ptr);
389
374
  if (a_length > max_length)
390
 
    a_length= max_length;
391
 
 
392
 
  b_length= get_length(b_ptr);
393
 
 
 
375
    a_length=max_length;
 
376
  b_length=get_length(b_ptr);
394
377
  if (b_length > max_length)
395
 
    b_length= max_length;
396
 
 
397
 
  diff= memcmp(a,b,min(a_length,b_length));
398
 
 
 
378
    b_length=max_length;
 
379
  diff=memcmp(a,b,cmin(a_length,b_length));
399
380
  return diff ? diff : (int) (a_length - b_length);
400
381
}
401
382
 
 
383
 
402
384
/* The following is used only when comparing a key */
403
 
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)
404
389
{
405
390
  uint32_t blob_length= get_length(ptr);
406
391
  unsigned char *blob;
414
399
  if ((uint32_t) length > blob_length)
415
400
  {
416
401
    /*
417
 
      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
418
403
      identical keys
419
404
    */
420
405
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
426
411
}
427
412
 
428
413
 
429
 
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)
430
417
{
431
418
  uint32_t blob_length= get_length(ptr);
432
419
  unsigned char *blob;
445
432
  if (length > blob_length)
446
433
  {
447
434
    /*
448
 
      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
449
436
      identical keys
450
437
    */
451
438
 
454
441
  return HA_KEY_BLOB_LENGTH+length;
455
442
}
456
443
 
 
444
 
457
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
458
446
{
459
447
  length= uint2korr(buff);
460
 
  (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);
461
450
}
462
451
 
 
452
 
463
453
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
464
454
{
465
455
  unsigned char *blob1;
481
471
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
482
472
}
483
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
 
484
492
uint32_t Field_blob::sort_length() const
485
493
{
486
494
  return (uint32_t) (current_session->variables.max_sort_length +
487
495
                   (field_charset == &my_charset_bin ? 0 : packlength));
488
496
}
489
497
 
 
498
 
490
499
void Field_blob::sort_string(unsigned char *to,uint32_t length)
491
500
{
492
501
  unsigned char *blob;
529
538
  }
530
539
}
531
540
 
 
541
 
532
542
uint32_t Field_blob::pack_length() const
533
543
{
534
544
  return (uint32_t) (packlength+table->s->blob_ptr_size);
535
545
}
536
546
 
 
547
 
537
548
void Field_blob::sql_type(String &res) const
538
549
{
539
550
  if (charset() == &my_charset_bin)
543
554
}
544
555
 
545
556
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
546
 
                                uint32_t max_length, bool low_byte_first)
 
557
                        uint32_t max_length, bool low_byte_first)
547
558
{
548
559
  unsigned char *save= ptr;
549
560
  ptr= (unsigned char*) from;
550
 
  uint32_t length= get_length();                        // Length of from string
 
561
  uint32_t length=get_length();                 // Length of from string
551
562
 
552
563
  /*
553
564
    Store max length, which will occupy packlength bytes. If the max
554
565
    length given is smaller than the actual length of the blob, we
555
566
    just store the initial bytes of the blob.
556
567
  */
557
 
  store_length(to, packlength, min(length, max_length), low_byte_first);
 
568
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
558
569
 
559
570
  /*
560
571
    Store the actual blob data, which will occupy 'length' bytes.
564
575
    get_ptr((unsigned char**) &from);
565
576
    memcpy(to+packlength, from,length);
566
577
  }
567
 
 
568
 
  ptr= save;                                    // Restore org row pointer
 
578
  ptr=save;                                     // Restore org row pointer
569
579
  return(to+packlength+length);
570
580
}
571
581
 
 
582
 
572
583
/**
573
584
   Unpack a blob field from row data.
574
585
 
587
598
   @return  New pointer into memory based on from + length of the data
588
599
*/
589
600
const unsigned char *Field_blob::unpack(unsigned char *,
590
 
                                        const unsigned char *from,
591
 
                                        uint32_t param_data,
592
 
                                        bool low_byte_first)
 
601
                                const unsigned char *from,
 
602
                                uint32_t param_data,
 
603
                                bool low_byte_first)
593
604
{
594
605
  uint32_t const master_packlength=
595
606
    param_data > 0 ? param_data & 0xFF : packlength;
596
607
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
597
 
  table->setWriteSet(field_index);
 
608
  bitmap_set_bit(table->write_set, field_index);
598
609
  store(reinterpret_cast<const char*>(from) + master_packlength,
599
610
        length, field_charset);
600
611
  return(from + master_packlength + length);
601
612
}
602
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);
 
657
}
 
658
 
603
659
/** Create a packed key that will be used for storage from a MySQL row. */
604
660
 
605
661
unsigned char *
627
683
 
628
684
 
629
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
/**
630
775
  maximum possible display length for blob.
631
776
 
632
777
  @return
651
796
  }
652
797
}
653
798
 
654
 
} /* namespace drizzled */
 
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
}