18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#ifdef USE_PRAGMA_IMPLEMENTATION
22
#pragma implementation // gcc: Class implementation
25
22
#include <drizzled/server_includes.h>
26
23
#include <drizzled/field/blob.h>
24
#include <drizzled/table.h>
25
#include <drizzled/session.h>
29
32
blob_pack_length_to_max_length(uint32_t arg)
31
return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
34
return (uint32_t)cmax(UINT32_MAX,
35
(INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1));
41
45
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
42
46
enum utype unireg_check_arg, const char *field_name_arg,
43
TABLE_SHARE *share, uint32_t blob_pack_length,
47
TableShare *share, uint32_t blob_pack_length,
44
48
const CHARSET_INFO * const cs)
45
49
:Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
46
50
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
98
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
101
store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
91
105
uint32_t Field_blob::get_length(const unsigned char *pos,
92
uint32_t packlength_arg,
93
bool low_byte_first __attribute__((unused)))
106
uint32_t packlength_arg,
109
#ifndef WORDS_BIGENDIAN
110
(void)low_byte_first;
95
112
switch (packlength_arg) {
97
114
return (uint32_t) pos[0];
144
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
147
return packlength + get_length(ptr_arg, packlength, low_byte_first);
151
uint32_t Field_blob::get_length(uint32_t row_offset)
153
return get_length(ptr+row_offset, this->packlength,
154
table->s->db_low_byte_first);
158
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
160
return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
128
165
Put a blob length field into a record buffer.
175
212
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
177
214
Field_blob::store_length(length);
178
memcpy(ptr+packlength, &from, sizeof(char*));
215
memmove(ptr+packlength, &from, sizeof(char*));
181
218
if (tmpstr.copy(from, length, cs))
214
251
Field_blob::store_length(copy_length);
215
252
tmp= value.ptr();
216
memcpy(ptr+packlength, &tmp, sizeof(char*));
253
memmove(ptr+packlength, &tmp, sizeof(char*));
218
255
if (check_string_copy_error(this, well_formed_error_pos,
219
256
cannot_convert_error_pos, from + length, cs))
306
343
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
307
344
uint32_t b_length)
309
return field_charset->coll->strnncollsp(field_charset,
346
return field_charset->coll->strnncollsp(field_charset,
310
347
a, a_length, b, b_length,
414
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff,
418
uint32_t blob_length= get_length(ptr);
422
uint32_t local_char_length= length / field_charset->mbmaxlen;
423
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
425
set_if_smaller(blob_length, local_char_length);
427
unsigned char len_buff[HA_KEY_BLOB_LENGTH];
428
int2store(len_buff,length);
429
buff.append(len_buff);
430
buff.append(blob, blob_length);
432
if (length > blob_length)
435
Must clear this as we do a memcmp in opt_range.cc to detect
439
buff.append(length-blob_length, '0');
441
return HA_KEY_BLOB_LENGTH+length;
377
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
379
447
length= uint2korr(buff);
531
605
uint32_t const master_packlength=
532
606
param_data > 0 ? param_data & 0xFF : packlength;
533
607
uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
bitmap_set_bit(table->write_set, field_index);
608
table->setWriteSet(field_index);
535
609
store(reinterpret_cast<const char*>(from) + master_packlength,
536
610
length, field_charset);
537
611
return(from + master_packlength + length);
540
/* Keys for blobs are like keys on varchars */
542
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
543
bool insert_or_update)
545
uint32_t a_length, b_length;
546
if (key_length_arg > 255)
548
a_length=uint2korr(a); a+=2;
549
b_length=uint2korr(b); b+=2;
553
a_length= (uint) *a++;
554
b_length= (uint) *b++;
556
return field_charset->coll->strnncollsp(field_charset,
563
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
564
bool insert_or_update)
567
uint32_t a_length, b_length;
568
memcpy(&a,ptr+packlength,sizeof(char*));
570
return key_length_arg > 0 ? -1 : 0;
572
a_length= get_length(ptr);
573
if (key_length_arg > 255)
575
b_length= uint2korr(b); b+=2;
578
b_length= (uint) *b++;
579
return field_charset->coll->strnncollsp(field_charset,
585
614
/** Create a packed key that will be used for storage from a MySQL row. */
588
617
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
589
bool low_byte_first __attribute__((unused)))
591
620
unsigned char *save= ptr;
592
621
ptr= (unsigned char*) from;
612
Unpack a blob key into a record buffer.
614
A blob key has a maximum size of 64K-1.
615
In its packed form, the length field is one or two bytes long,
616
depending on 'max_length'.
617
Depending on the maximum length of a blob, its length field is
618
put into 1 to 4 bytes. This is a property of the blob object,
619
described by 'packlength'.
620
Blobs are internally stored apart from the record buffer, which
621
contains a pointer to the blob buffer.
624
@param to Pointer into the record buffer.
625
@param from Pointer to the packed key.
626
@param max_length Key length limit from key description.
629
Pointer into 'from' past the last byte copied from packed key.
632
const unsigned char *
633
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
634
bool low_byte_first __attribute__((unused)))
636
/* get length of the blob key */
637
uint32_t length= *from++;
638
if (max_length > 255)
639
length+= *from++ << 8;
641
/* put the length into the record buffer */
642
put_length(to, length);
644
/* put the address of the blob buffer or NULL */
646
memcpy(to + packlength, &from, sizeof(from));
648
memset(to + packlength, 0, sizeof(from));
650
/* point to first byte of next field in 'from' */
651
return from + length;
655
/** Create a packed key that will be used for storage from a MySQL key. */
658
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
659
bool low_byte_first __attribute__((unused)))
661
uint32_t length=uint2korr(from);
662
if (length > max_length)
664
*to++= (char) (length & 255);
665
if (max_length > 255)
666
*to++= (char) (length >> 8);
668
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
673
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
676
return uint2korr(data_ptr)+2;
677
return (uint) *data_ptr + 1;
681
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
683
return (max_length > 255 ? 2 : 1)+max_length;
687
uint32_t Field_blob::is_equal(Create_field *new_field)
689
if (compare_str_field_flags(new_field, flags))
640
uint32_t Field_blob::is_equal(Create_field *new_field_ptr)
642
if (compare_str_field_flags(new_field_ptr, flags))
644
Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
692
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
693
&& new_field->charset == field_charset &&
694
((Field_blob *)new_field->field)->max_data_length() ==
646
return ((new_field_ptr->sql_type ==
647
get_blob_type_from_length(max_data_length()))
648
&& new_field_ptr->charset == field_charset
649
&& blob_field_ptr->max_data_length() == max_data_length());