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/field/blob.h>
27
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
28
((ulong) ((1LL << min(arg, 4) * 8) - 1LL))
30
/****************************************************************************
32
** A blob is saved as a length and a pointer. The length is stored in the
33
** packlength slot and may be from 1-4.
34
****************************************************************************/
36
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
37
enum utype unireg_check_arg, const char *field_name_arg,
38
TABLE_SHARE *share, uint blob_pack_length,
40
:Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
41
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
43
packlength(blob_pack_length)
47
/* TODO: why do not fill table->s->blob_field array here? */
51
void Field_blob::store_length(uchar *i_ptr,
54
bool low_byte_first __attribute__((unused)))
56
switch (i_packlength) {
58
i_ptr[0]= (uchar) i_number;
61
#ifdef WORDS_BIGENDIAN
64
int2store(i_ptr,(unsigned short) i_number);
68
shortstore(i_ptr,(unsigned short) i_number);
71
int3store(i_ptr,i_number);
74
#ifdef WORDS_BIGENDIAN
77
int4store(i_ptr,i_number);
81
longstore(i_ptr,i_number);
86
uint32_t Field_blob::get_length(const uchar *pos,
88
bool low_byte_first __attribute__((unused)))
90
switch (packlength_arg) {
92
return (uint32_t) pos[0];
96
#ifdef WORDS_BIGENDIAN
102
return (uint32_t) tmp;
105
return (uint32_t) uint3korr(pos);
109
#ifdef WORDS_BIGENDIAN
115
return (uint32_t) tmp;
118
return 0; // Impossible
123
Put a blob length field into a record buffer.
125
Depending on the maximum length of a blob, its length field is
126
put into 1 to 4 bytes. This is a property of the blob object,
127
described by 'packlength'.
129
@param pos Pointer into the record buffer.
130
@param length The length value to put.
133
void Field_blob::put_length(uchar *pos, uint32_t length)
135
switch (packlength) {
140
int2store(pos, length);
143
int3store(pos, length);
146
int4store(pos, length);
152
int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
154
uint copy_length, new_length;
155
const char *well_formed_error_pos;
156
const char *cannot_convert_error_pos;
157
const char *from_end_pos, *tmp;
158
char buff[STRING_BUFFER_USUAL_SIZE];
159
String tmpstr(buff,sizeof(buff), &my_charset_bin);
163
memset(ptr, 0, Field_blob::pack_length());
167
if (from == value.ptr())
169
uint32_t dummy_offset;
170
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
172
Field_blob::store_length(length);
173
memcpy(ptr+packlength, (char*) &from, sizeof(char*));
176
if (tmpstr.copy(from, length, cs))
181
new_length= min(max_data_length(), field_charset->mbmaxlen * length);
182
if (value.alloc(new_length))
186
if (f_is_hex_escape(flags))
188
copy_length= my_copy_with_hex_escaping(field_charset,
189
(char*) value.ptr(), new_length,
191
Field_blob::store_length(copy_length);
193
memcpy(ptr + packlength, (uchar*) &tmp, sizeof(char*));
197
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
198
is never used to limit the length of the data. The cut of long data
199
is done with the new_length value.
201
copy_length= well_formed_copy_nchars(field_charset,
202
(char*) value.ptr(), new_length,
205
&well_formed_error_pos,
206
&cannot_convert_error_pos,
209
Field_blob::store_length(copy_length);
211
memcpy(ptr+packlength, (uchar*) &tmp, sizeof(char*));
213
if (check_string_copy_error(this, well_formed_error_pos,
214
cannot_convert_error_pos, from + length, cs))
217
return report_if_important_data(from_end_pos, from + length);
220
/* Fatal OOM error */
221
memset(ptr, 0, Field_blob::pack_length());
226
int Field_blob::store(double nr)
228
CHARSET_INFO *cs=charset();
229
value.set_real(nr, NOT_FIXED_DEC, cs);
230
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
234
int Field_blob::store(int64_t nr, bool unsigned_val)
236
CHARSET_INFO *cs=charset();
237
value.set_int(nr, unsigned_val, cs);
238
return Field_blob::store(value.ptr(), (uint) value.length(), cs);
242
double Field_blob::val_real(void)
245
char *end_not_used, *blob;
249
memcpy(&blob,ptr+packlength,sizeof(char*));
252
length= get_length(ptr);
254
return my_strntod(cs, blob, length, &end_not_used, ¬_used);
258
int64_t Field_blob::val_int(void)
262
memcpy(&blob,ptr+packlength,sizeof(char*));
265
uint32_t length=get_length(ptr);
266
return my_strntoll(charset(),blob,length,10,NULL,¬_used);
269
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
273
memcpy(&blob,ptr+packlength,sizeof(char*));
275
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
277
val_ptr->set((const char*) blob,get_length(ptr),charset());
282
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
286
memcpy(&blob, ptr+packlength, sizeof(const uchar*));
293
length= get_length(ptr);
295
str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
297
return decimal_value;
301
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
304
return field_charset->coll->strnncollsp(field_charset,
305
a, a_length, b, b_length,
310
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
314
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
315
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
316
uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
317
set_if_smaller(a_len, max_length);
318
set_if_smaller(b_len, max_length);
319
return Field_blob::cmp(blob1,a_len,blob2,b_len);
323
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
328
uint32_t a_length,b_length;
329
memcpy(&a,a_ptr+packlength,sizeof(char*));
330
memcpy(&b,b_ptr+packlength,sizeof(char*));
331
a_length=get_length(a_ptr);
332
if (a_length > max_length)
334
b_length=get_length(b_ptr);
335
if (b_length > max_length)
337
diff=memcmp(a,b,min(a_length,b_length));
338
return diff ? diff : (int) (a_length - b_length);
342
/* The following is used only when comparing a key */
344
uint Field_blob::get_key_image(uchar *buff,
346
imagetype type_arg __attribute__((unused)))
348
uint32_t blob_length= get_length(ptr);
352
uint local_char_length= length / field_charset->mbmaxlen;
353
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
355
set_if_smaller(blob_length, local_char_length);
357
if ((uint32_t) length > blob_length)
360
Must clear this as we do a memcmp in opt_range.cc to detect
363
memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
364
length=(uint) blob_length;
366
int2store(buff,length);
367
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
368
return HA_KEY_BLOB_LENGTH+length;
372
void Field_blob::set_key_image(const uchar *buff,uint length)
374
length= uint2korr(buff);
375
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
380
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
383
uint blob_length=get_length(ptr);
384
memcpy(&blob1,ptr+packlength,sizeof(char*));
385
CHARSET_INFO *cs= charset();
386
uint local_char_length= max_key_length / cs->mbmaxlen;
387
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
389
set_if_smaller(blob_length, local_char_length);
390
return Field_blob::cmp(blob1, blob_length,
391
key_ptr+HA_KEY_BLOB_LENGTH,
395
int Field_blob::key_cmp(const uchar *a,const uchar *b)
397
return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
398
b+HA_KEY_BLOB_LENGTH, uint2korr(b));
403
Save the field metadata for blob fields.
405
Saves the pack length in the first byte of the field metadata array
406
at index of *metadata_ptr.
408
@param metadata_ptr First byte of field metadata
410
@returns number of bytes written to metadata_ptr
412
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
414
*metadata_ptr= pack_length_no_ptr();
419
uint32_t Field_blob::sort_length() const
421
return (uint32_t) (current_thd->variables.max_sort_length +
422
(field_charset == &my_charset_bin ? 0 : packlength));
426
void Field_blob::sort_string(uchar *to,uint length)
429
uint blob_length=get_length();
432
memset(to, 0, length);
435
if (field_charset == &my_charset_bin)
440
Store length of blob last in blob to shorter blobs before longer blobs
445
switch (packlength) {
447
*pos= (char) blob_length;
450
mi_int2store(pos, blob_length);
453
mi_int3store(pos, blob_length);
456
mi_int4store(pos, blob_length);
460
memcpy(&blob,ptr+packlength,sizeof(char*));
462
blob_length=my_strnxfrm(field_charset,
463
to, length, blob, blob_length);
464
assert(blob_length == length);
469
void Field_blob::sql_type(String &res) const
471
if (charset() == &my_charset_bin)
472
res.set_ascii(STRING_WITH_LEN("blob"));
474
res.set_ascii(STRING_WITH_LEN("text"));
477
uchar *Field_blob::pack(uchar *to, const uchar *from,
478
uint max_length, bool low_byte_first)
482
uint32_t length=get_length(); // Length of from string
485
Store max length, which will occupy packlength bytes. If the max
486
length given is smaller than the actual length of the blob, we
487
just store the initial bytes of the blob.
489
store_length(to, packlength, min(length, max_length), low_byte_first);
492
Store the actual blob data, which will occupy 'length' bytes.
496
get_ptr((uchar**) &from);
497
memcpy(to+packlength, from,length);
499
ptr=save; // Restore org row pointer
500
return(to+packlength+length);
505
Unpack a blob field from row data.
507
This method is used to unpack a blob field from a master whose size of
508
the field is less than that of the slave. Note: This method is included
509
to satisfy inheritance rules, but is not needed for blob fields. It
510
simply is used as a pass-through to the original unpack() method for
513
@param to Destination of the data
514
@param from Source of the data
515
@param param_data @c true if base types should be stored in little-
516
endian format, @c false if native format should
519
@return New pointer into memory based on from + length of the data
521
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
526
uint const master_packlength=
527
param_data > 0 ? param_data & 0xFF : packlength;
528
uint32_t const length= get_length(from, master_packlength, low_byte_first);
529
bitmap_set_bit(table->write_set, field_index);
530
store(reinterpret_cast<const char*>(from) + master_packlength,
531
length, field_charset);
532
return(from + master_packlength + length);
535
/* Keys for blobs are like keys on varchars */
537
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
538
my_bool insert_or_update)
540
uint a_length, b_length;
541
if (key_length_arg > 255)
543
a_length=uint2korr(a); a+=2;
544
b_length=uint2korr(b); b+=2;
548
a_length= (uint) *a++;
549
b_length= (uint) *b++;
551
return field_charset->coll->strnncollsp(field_charset,
558
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
559
my_bool insert_or_update)
562
uint a_length, b_length;
563
memcpy(&a,ptr+packlength,sizeof(char*));
565
return key_length_arg > 0 ? -1 : 0;
567
a_length= get_length(ptr);
568
if (key_length_arg > 255)
570
b_length= uint2korr(b); b+=2;
573
b_length= (uint) *b++;
574
return field_charset->coll->strnncollsp(field_charset,
580
/** Create a packed key that will be used for storage from a MySQL row. */
583
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
584
bool low_byte_first __attribute__((unused)))
588
uint32_t length=get_length(); // Length of from string
589
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
590
max_length/field_charset->mbmaxlen : max_length);
592
get_ptr((uchar**) &from);
593
if (length > local_char_length)
594
local_char_length= my_charpos(field_charset, from, from+length,
596
set_if_smaller(length, local_char_length);
597
*to++= (uchar) length;
598
if (max_length > 255) // 2 byte length
599
*to++= (uchar) (length >> 8);
600
memcpy(to, from, length);
601
ptr=save; // Restore org row pointer
607
Unpack a blob key into a record buffer.
609
A blob key has a maximum size of 64K-1.
610
In its packed form, the length field is one or two bytes long,
611
depending on 'max_length'.
612
Depending on the maximum length of a blob, its length field is
613
put into 1 to 4 bytes. This is a property of the blob object,
614
described by 'packlength'.
615
Blobs are internally stored apart from the record buffer, which
616
contains a pointer to the blob buffer.
619
@param to Pointer into the record buffer.
620
@param from Pointer to the packed key.
621
@param max_length Key length limit from key description.
624
Pointer into 'from' past the last byte copied from packed key.
628
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
629
bool low_byte_first __attribute__((unused)))
631
/* get length of the blob key */
632
uint32_t length= *from++;
633
if (max_length > 255)
634
length+= *from++ << 8;
636
/* put the length into the record buffer */
637
put_length(to, length);
639
/* put the address of the blob buffer or NULL */
641
memcpy(to + packlength, &from, sizeof(from));
643
memset(to + packlength, 0, sizeof(from));
645
/* point to first byte of next field in 'from' */
646
return from + length;
650
/** Create a packed key that will be used for storage from a MySQL key. */
653
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
654
bool low_byte_first __attribute__((unused)))
656
uint length=uint2korr(from);
657
if (length > max_length)
659
*to++= (char) (length & 255);
660
if (max_length > 255)
661
*to++= (char) (length >> 8);
663
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
668
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
671
return uint2korr(data_ptr)+2;
672
return (uint) *data_ptr + 1;
676
uint Field_blob::max_packed_col_length(uint max_length)
678
return (max_length > 255 ? 2 : 1)+max_length;
682
uint Field_blob::is_equal(Create_field *new_field)
684
if (compare_str_field_flags(new_field, flags))
687
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
688
&& new_field->charset == field_charset &&
689
((Field_blob *)new_field->field)->max_data_length() ==
695
maximum possible display length for blob.
701
uint32_t Field_blob::max_display_length()
706
return 255 * field_charset->mbmaxlen;
708
return 65535 * field_charset->mbmaxlen;
710
return 16777215 * field_charset->mbmaxlen;
712
return (uint32_t) 4294967295U;
714
assert(0); // we should never go here