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"
31
29
using namespace std;
36
static uint32_t blob_pack_length_to_max_length(uint32_t arg)
38
return max(UINT32_MAX,
39
(uint32_t)((INT64_C(1) << min(arg, 4U) * 8) - INT64_C(1)));
32
blob_pack_length_to_max_length(uint32_t arg)
34
return (uint32_t)cmax(UINT32_MAX,
35
(INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1));
43
39
/****************************************************************************
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
****************************************************************************/
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,
54
const CHARSET_INFO * const cs)
56
blob_pack_length_to_max_length(sizeof(uint32_t)),
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,
52
packlength(blob_pack_length)
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? */
67
60
void Field_blob::store_length(unsigned char *i_ptr,
61
uint32_t i_packlength,
69
63
bool low_byte_first)
71
65
#ifndef WORDS_BIGENDIAN
72
66
(void)low_byte_first;
75
#ifdef WORDS_BIGENDIAN
78
int4store(i_ptr,i_number);
68
switch (i_packlength) {
70
i_ptr[0]= (unsigned char) i_number;
73
#ifdef WORDS_BIGENDIAN
76
int2store(i_ptr,(unsigned short) i_number);
80
shortstore(i_ptr,(unsigned short) i_number);
83
int3store(i_ptr,i_number);
86
#ifdef WORDS_BIGENDIAN
89
int4store(i_ptr,i_number);
93
longstore(i_ptr,i_number);
82
longstore(i_ptr,i_number);
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,
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);
92
105
uint32_t Field_blob::get_length(const unsigned char *pos,
106
uint32_t packlength_arg,
93
107
bool low_byte_first)
95
109
#ifndef WORDS_BIGENDIAN
96
110
(void)low_byte_first;
99
#ifdef WORDS_BIGENDIAN
105
return (uint32_t) tmp;
112
switch (packlength_arg) {
114
return (uint32_t) pos[0];
118
#ifdef WORDS_BIGENDIAN
124
return (uint32_t) tmp;
127
return (uint32_t) uint3korr(pos);
131
#ifdef WORDS_BIGENDIAN
137
return (uint32_t) tmp;
140
return 0; // Impossible
109
144
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
110
145
bool low_byte_first)
112
return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
147
return packlength + get_length(ptr_arg, packlength, low_byte_first);
116
151
uint32_t Field_blob::get_length(uint32_t row_offset)
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);
123
158
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
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);
130
165
Put a blob length field into a record buffer.
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'.
134
171
@param pos Pointer into the record buffer.
135
172
@param length The length value to put.
319
365
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
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*));
328
a_length= get_length(a_ptr);
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;
333
b_length= get_length(b_ptr);
376
b_length=get_length(b_ptr);
335
377
if (b_length > max_length)
336
b_length= max_length;
338
diff= memcmp(a,b,min(a_length,b_length));
340
return diff ? diff : (unsigned int) (a_length - b_length);
379
diff=memcmp(a,b,cmin(a_length,b_length));
380
return diff ? diff : (int) (a_length - b_length);
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)
386
uint32_t Field_blob::get_key_image(unsigned char *buff,
346
390
uint32_t blob_length= get_length(ptr);
347
391
unsigned char *blob;
395
441
return HA_KEY_BLOB_LENGTH+length;
398
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
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,
404
453
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
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));
476
Save the field metadata for blob fields.
478
Saves the pack length in the first byte of the field metadata array
479
at index of *metadata_ptr.
481
@param metadata_ptr First byte of field metadata
483
@returns number of bytes written to metadata_ptr
485
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
487
*metadata_ptr= pack_length_no_ptr();
425
492
uint32_t Field_blob::sort_length() const
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));
431
499
void Field_blob::sort_string(unsigned char *to,uint32_t length)
433
501
unsigned char *blob;
445
513
Store length of blob last in blob to shorter blobs before longer blobs
447
length-= sizeof(uint32_t); // size of stored blob length
450
mi_int4store(pos, blob_length);
518
switch (packlength) {
520
*pos= (char) blob_length;
523
mi_int2store(pos, blob_length);
526
mi_int3store(pos, blob_length);
529
mi_int4store(pos, blob_length);
452
memcpy(&blob,ptr+sizeof(uint32_t),sizeof(char*));
533
memcpy(&blob,ptr+packlength,sizeof(char*));
454
535
blob_length=my_strnxfrm(field_charset,
455
536
to, length, blob, blob_length);
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)
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
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.
485
store_length(to, min(length, max_length), low_byte_first);
568
store_length(to, packlength, cmin(length, max_length), low_byte_first);
488
571
Store the actual blob data, which will occupy 'length' bytes.
515
598
@return New pointer into memory based on from + length of the data
517
600
const unsigned char *Field_blob::unpack(unsigned char *,
518
const unsigned char *from,
601
const unsigned char *from,
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);
614
/* Keys for blobs are like keys on varchars */
616
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
617
bool insert_or_update)
619
uint32_t a_length, b_length;
620
if (key_length_arg > 255)
622
a_length=uint2korr(a); a+=2;
623
b_length=uint2korr(b); b+=2;
627
a_length= (uint32_t) *a++;
628
b_length= (uint32_t) *b++;
630
return field_charset->coll->strnncollsp(field_charset,
637
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
638
bool insert_or_update)
641
uint32_t a_length, b_length;
642
memcpy(&a,ptr+packlength,sizeof(char*));
644
return key_length_arg > 0 ? -1 : 0;
646
a_length= get_length(ptr);
647
if (key_length_arg > 255)
649
b_length= uint2korr(b); b+=2;
652
b_length= (uint32_t) *b++;
653
return field_charset->coll->strnncollsp(field_charset,
529
659
/** Create a packed key that will be used for storage from a MySQL row. */
686
Unpack a blob key into a record buffer.
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.
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.
703
Pointer into 'from' past the last byte copied from packed key.
706
const unsigned char *
707
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
710
/* get length of the blob key */
711
uint32_t length= *from++;
712
if (max_length > 255)
713
length+= *from++ << 8;
715
/* put the length into the record buffer */
716
put_length(to, length);
718
/* put the address of the blob buffer or NULL */
720
memcpy(to + packlength, &from, sizeof(from));
722
memset(to + packlength, 0, sizeof(from));
724
/* point to first byte of next field in 'from' */
725
return from + length;
729
/** Create a packed key that will be used for storage from a MySQL key. */
732
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
735
uint32_t length=uint2korr(from);
736
if (length > max_length)
738
*to++= (char) (length & 255);
739
if (max_length > 255)
740
*to++= (char) (length >> 8);
742
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
747
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
750
return uint2korr(data_ptr)+2;
751
return (uint32_t) *data_ptr + 1;
755
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
757
return (max_length > 255 ? 2 : 1)+max_length;
761
uint32_t Field_blob::is_equal(Create_field *new_field_ptr)
763
if (compare_str_field_flags(new_field_ptr, flags))
765
Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
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());
556
775
maximum possible display length for blob.