1
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 MySQL
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
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
#include <drizzled/server_includes.h>
26
#include <drizzled/field/blob.h>
29
blob_pack_length_to_max_length(uint32_t arg)
31
return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
35
/****************************************************************************
37
** A blob is saved as a length and a pointer. The length is stored in the
38
** packlength slot and may be from 1-4.
39
****************************************************************************/
41
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
42
enum utype unireg_check_arg, const char *field_name_arg,
43
TABLE_SHARE *share, uint32_t blob_pack_length,
44
const CHARSET_INFO * const cs)
45
:Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
46
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
48
packlength(blob_pack_length)
52
/* TODO: why do not fill table->s->blob_field array here? */
56
void Field_blob::store_length(unsigned char *i_ptr,
57
uint32_t i_packlength,
59
bool low_byte_first __attribute__((unused)))
61
switch (i_packlength) {
63
i_ptr[0]= (unsigned char) i_number;
66
#ifdef WORDS_BIGENDIAN
69
int2store(i_ptr,(unsigned short) i_number);
73
shortstore(i_ptr,(unsigned short) i_number);
76
int3store(i_ptr,i_number);
79
#ifdef WORDS_BIGENDIAN
82
int4store(i_ptr,i_number);
86
longstore(i_ptr,i_number);
91
uint32_t Field_blob::get_length(const unsigned char *pos,
92
uint32_t packlength_arg,
93
bool low_byte_first __attribute__((unused)))
95
switch (packlength_arg) {
97
return (uint32_t) pos[0];
101
#ifdef WORDS_BIGENDIAN
107
return (uint32_t) tmp;
110
return (uint32_t) uint3korr(pos);
114
#ifdef WORDS_BIGENDIAN
120
return (uint32_t) tmp;
123
return 0; // Impossible
128
Put a blob length field into a record buffer.
130
Depending on the maximum length of a blob, its length field is
131
put into 1 to 4 bytes. This is a property of the blob object,
132
described by 'packlength'.
134
@param pos Pointer into the record buffer.
135
@param length The length value to put.
138
void Field_blob::put_length(unsigned char *pos, uint32_t length)
140
switch (packlength) {
145
int2store(pos, length);
148
int3store(pos, length);
151
int4store(pos, length);
157
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
159
uint32_t copy_length, new_length;
160
const char *well_formed_error_pos;
161
const char *cannot_convert_error_pos;
162
const char *from_end_pos, *tmp;
163
char buff[STRING_BUFFER_USUAL_SIZE];
164
String tmpstr(buff,sizeof(buff), &my_charset_bin);
168
memset(ptr, 0, Field_blob::pack_length());
172
if (from == value.ptr())
174
uint32_t dummy_offset;
175
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
177
Field_blob::store_length(length);
178
memcpy(ptr+packlength, &from, sizeof(char*));
181
if (tmpstr.copy(from, length, cs))
186
new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
187
if (value.alloc(new_length))
191
if (f_is_hex_escape(flags))
193
copy_length= my_copy_with_hex_escaping(field_charset,
194
(char*) value.ptr(), new_length,
196
Field_blob::store_length(copy_length);
198
memcpy(ptr + packlength, &tmp, sizeof(char*));
202
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
203
is never used to limit the length of the data. The cut of long data
204
is done with the new_length value.
206
copy_length= well_formed_copy_nchars(field_charset,
207
(char*) value.ptr(), new_length,
210
&well_formed_error_pos,
211
&cannot_convert_error_pos,
214
Field_blob::store_length(copy_length);
216
memcpy(ptr+packlength, &tmp, sizeof(char*));
218
if (check_string_copy_error(this, well_formed_error_pos,
219
cannot_convert_error_pos, from + length, cs))
222
return report_if_important_data(from_end_pos, from + length);
225
/* Fatal OOM error */
226
memset(ptr, 0, Field_blob::pack_length());
231
int Field_blob::store(double nr)
233
const CHARSET_INFO * const cs=charset();
234
value.set_real(nr, NOT_FIXED_DEC, cs);
235
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
239
int Field_blob::store(int64_t nr, bool unsigned_val)
241
const CHARSET_INFO * const cs=charset();
242
value.set_int(nr, unsigned_val, cs);
243
return Field_blob::store(value.ptr(), (uint) value.length(), cs);
247
double Field_blob::val_real(void)
250
char *end_not_used, *blob;
252
const CHARSET_INFO *cs;
254
memcpy(&blob,ptr+packlength,sizeof(char*));
257
length= get_length(ptr);
259
return my_strntod(cs, blob, length, &end_not_used, ¬_used);
263
int64_t Field_blob::val_int(void)
267
memcpy(&blob,ptr+packlength,sizeof(char*));
270
uint32_t length=get_length(ptr);
271
return my_strntoll(charset(),blob,length,10,NULL,¬_used);
274
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
278
memcpy(&blob,ptr+packlength,sizeof(char*));
280
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
282
val_ptr->set((const char*) blob,get_length(ptr),charset());
287
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
291
memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
298
length= get_length(ptr);
300
str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
302
return decimal_value;
306
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
309
return field_charset->coll->strnncollsp(field_charset,
310
a, a_length, b, b_length,
315
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
318
unsigned char *blob1,*blob2;
319
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
320
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
321
uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
322
set_if_smaller(a_len, max_length);
323
set_if_smaller(b_len, max_length);
324
return Field_blob::cmp(blob1,a_len,blob2,b_len);
328
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
333
uint32_t a_length,b_length;
334
memcpy(&a,a_ptr+packlength,sizeof(char*));
335
memcpy(&b,b_ptr+packlength,sizeof(char*));
336
a_length=get_length(a_ptr);
337
if (a_length > max_length)
339
b_length=get_length(b_ptr);
340
if (b_length > max_length)
342
diff=memcmp(a,b,cmin(a_length,b_length));
343
return diff ? diff : (int) (a_length - b_length);
347
/* The following is used only when comparing a key */
349
uint32_t Field_blob::get_key_image(unsigned char *buff,
351
imagetype type_arg __attribute__((unused)))
353
uint32_t blob_length= get_length(ptr);
357
uint32_t local_char_length= length / field_charset->mbmaxlen;
358
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
360
set_if_smaller(blob_length, local_char_length);
362
if ((uint32_t) length > blob_length)
365
Must clear this as we do a memcmp in opt_range.cc to detect
368
memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
369
length=(uint) blob_length;
371
int2store(buff,length);
372
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
373
return HA_KEY_BLOB_LENGTH+length;
377
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
379
length= uint2korr(buff);
380
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
385
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
387
unsigned char *blob1;
388
uint32_t blob_length=get_length(ptr);
389
memcpy(&blob1,ptr+packlength,sizeof(char*));
390
const CHARSET_INFO * const cs= charset();
391
uint32_t local_char_length= max_key_length / cs->mbmaxlen;
392
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
394
set_if_smaller(blob_length, local_char_length);
395
return Field_blob::cmp(blob1, blob_length,
396
key_ptr+HA_KEY_BLOB_LENGTH,
400
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
402
return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
403
b+HA_KEY_BLOB_LENGTH, uint2korr(b));
408
Save the field metadata for blob fields.
410
Saves the pack length in the first byte of the field metadata array
411
at index of *metadata_ptr.
413
@param metadata_ptr First byte of field metadata
415
@returns number of bytes written to metadata_ptr
417
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
419
*metadata_ptr= pack_length_no_ptr();
424
uint32_t Field_blob::sort_length() const
426
return (uint32_t) (current_thd->variables.max_sort_length +
427
(field_charset == &my_charset_bin ? 0 : packlength));
431
void Field_blob::sort_string(unsigned char *to,uint32_t length)
434
uint32_t blob_length=get_length();
437
memset(to, 0, length);
440
if (field_charset == &my_charset_bin)
445
Store length of blob last in blob to shorter blobs before longer blobs
450
switch (packlength) {
452
*pos= (char) blob_length;
455
mi_int2store(pos, blob_length);
458
mi_int3store(pos, blob_length);
461
mi_int4store(pos, blob_length);
465
memcpy(&blob,ptr+packlength,sizeof(char*));
467
blob_length=my_strnxfrm(field_charset,
468
to, length, blob, blob_length);
469
assert(blob_length == length);
474
void Field_blob::sql_type(String &res) const
476
if (charset() == &my_charset_bin)
477
res.set_ascii(STRING_WITH_LEN("blob"));
479
res.set_ascii(STRING_WITH_LEN("text"));
482
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
483
uint32_t max_length, bool low_byte_first)
485
unsigned char *save= ptr;
486
ptr= (unsigned char*) from;
487
uint32_t length=get_length(); // Length of from string
490
Store max length, which will occupy packlength bytes. If the max
491
length given is smaller than the actual length of the blob, we
492
just store the initial bytes of the blob.
494
store_length(to, packlength, cmin(length, max_length), low_byte_first);
497
Store the actual blob data, which will occupy 'length' bytes.
501
get_ptr((unsigned char**) &from);
502
memcpy(to+packlength, from,length);
504
ptr=save; // Restore org row pointer
505
return(to+packlength+length);
510
Unpack a blob field from row data.
512
This method is used to unpack a blob field from a master whose size of
513
the field is less than that of the slave. Note: This method is included
514
to satisfy inheritance rules, but is not needed for blob fields. It
515
simply is used as a pass-through to the original unpack() method for
518
@param to Destination of the data
519
@param from Source of the data
520
@param param_data @c true if base types should be stored in little-
521
endian format, @c false if native format should
524
@return New pointer into memory based on from + length of the data
526
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
527
const unsigned char *from,
531
uint32_t const master_packlength=
532
param_data > 0 ? param_data & 0xFF : packlength;
533
uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
bitmap_set_bit(table->write_set, field_index);
535
store(reinterpret_cast<const char*>(from) + master_packlength,
536
length, field_charset);
537
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
/** Create a packed key that will be used for storage from a MySQL row. */
588
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
589
bool low_byte_first __attribute__((unused)))
591
unsigned char *save= ptr;
592
ptr= (unsigned char*) from;
593
uint32_t length=get_length(); // Length of from string
594
uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
595
max_length/field_charset->mbmaxlen : max_length);
597
get_ptr((unsigned char**) &from);
598
if (length > local_char_length)
599
local_char_length= my_charpos(field_charset, from, from+length,
601
set_if_smaller(length, local_char_length);
602
*to++= (unsigned char) length;
603
if (max_length > 255) // 2 byte length
604
*to++= (unsigned char) (length >> 8);
605
memcpy(to, from, length);
606
ptr=save; // Restore org row pointer
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))
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() ==
700
maximum possible display length for blob.
706
uint32_t Field_blob::max_display_length()
711
return 255 * field_charset->mbmaxlen;
713
return 65535 * field_charset->mbmaxlen;
715
return 16777215 * field_charset->mbmaxlen;
717
return (uint32_t) 4294967295U;
719
assert(0); // we should never go here