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
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/blob.h>
26
blob_pack_length_to_max_length(uint32_t arg)
28
return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
32
/****************************************************************************
34
** A blob is saved as a length and a pointer. The length is stored in the
35
** packlength slot and may be from 1-4.
36
****************************************************************************/
38
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
39
enum utype unireg_check_arg, const char *field_name_arg,
40
TABLE_SHARE *share, uint32_t blob_pack_length,
41
const CHARSET_INFO * const cs)
42
:Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
43
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
45
packlength(blob_pack_length)
49
/* TODO: why do not fill table->s->blob_field array here? */
53
void Field_blob::store_length(unsigned char *i_ptr,
54
uint32_t i_packlength,
56
bool low_byte_first __attribute__((unused)))
58
switch (i_packlength) {
60
i_ptr[0]= (unsigned char) i_number;
63
#ifdef WORDS_BIGENDIAN
66
int2store(i_ptr,(unsigned short) i_number);
70
shortstore(i_ptr,(unsigned short) i_number);
73
int3store(i_ptr,i_number);
76
#ifdef WORDS_BIGENDIAN
79
int4store(i_ptr,i_number);
83
longstore(i_ptr,i_number);
88
uint32_t Field_blob::get_length(const unsigned char *pos,
89
uint32_t packlength_arg,
90
bool low_byte_first __attribute__((unused)))
92
switch (packlength_arg) {
94
return (uint32_t) pos[0];
98
#ifdef WORDS_BIGENDIAN
104
return (uint32_t) tmp;
107
return (uint32_t) uint3korr(pos);
111
#ifdef WORDS_BIGENDIAN
117
return (uint32_t) tmp;
120
return 0; // Impossible
125
Put a blob length field into a record buffer.
127
Depending on the maximum length of a blob, its length field is
128
put into 1 to 4 bytes. This is a property of the blob object,
129
described by 'packlength'.
131
@param pos Pointer into the record buffer.
132
@param length The length value to put.
135
void Field_blob::put_length(unsigned char *pos, uint32_t length)
137
switch (packlength) {
142
int2store(pos, length);
145
int3store(pos, length);
148
int4store(pos, length);
154
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
156
uint32_t copy_length, new_length;
157
const char *well_formed_error_pos;
158
const char *cannot_convert_error_pos;
159
const char *from_end_pos, *tmp;
160
char buff[STRING_BUFFER_USUAL_SIZE];
161
String tmpstr(buff,sizeof(buff), &my_charset_bin);
165
memset(ptr, 0, Field_blob::pack_length());
169
if (from == value.ptr())
171
uint32_t dummy_offset;
172
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
174
Field_blob::store_length(length);
175
memcpy(ptr+packlength, &from, sizeof(char*));
178
if (tmpstr.copy(from, length, cs))
183
new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
184
if (value.alloc(new_length))
188
if (f_is_hex_escape(flags))
190
copy_length= my_copy_with_hex_escaping(field_charset,
191
(char*) value.ptr(), new_length,
193
Field_blob::store_length(copy_length);
195
memcpy(ptr + packlength, &tmp, sizeof(char*));
199
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
200
is never used to limit the length of the data. The cut of long data
201
is done with the new_length value.
203
copy_length= well_formed_copy_nchars(field_charset,
204
(char*) value.ptr(), new_length,
207
&well_formed_error_pos,
208
&cannot_convert_error_pos,
211
Field_blob::store_length(copy_length);
213
memcpy(ptr+packlength, &tmp, sizeof(char*));
215
if (check_string_copy_error(this, well_formed_error_pos,
216
cannot_convert_error_pos, from + length, cs))
219
return report_if_important_data(from_end_pos, from + length);
222
/* Fatal OOM error */
223
memset(ptr, 0, Field_blob::pack_length());
228
int Field_blob::store(double nr)
230
const CHARSET_INFO * const cs=charset();
231
value.set_real(nr, NOT_FIXED_DEC, cs);
232
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
236
int Field_blob::store(int64_t nr, bool unsigned_val)
238
const CHARSET_INFO * const cs=charset();
239
value.set_int(nr, unsigned_val, cs);
240
return Field_blob::store(value.ptr(), (uint) value.length(), cs);
244
double Field_blob::val_real(void)
247
char *end_not_used, *blob;
249
const CHARSET_INFO *cs;
251
memcpy(&blob,ptr+packlength,sizeof(char*));
254
length= get_length(ptr);
256
return my_strntod(cs, blob, length, &end_not_used, ¬_used);
260
int64_t Field_blob::val_int(void)
264
memcpy(&blob,ptr+packlength,sizeof(char*));
267
uint32_t length=get_length(ptr);
268
return my_strntoll(charset(),blob,length,10,NULL,¬_used);
271
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
275
memcpy(&blob,ptr+packlength,sizeof(char*));
277
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
279
val_ptr->set((const char*) blob,get_length(ptr),charset());
284
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
288
memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
295
length= get_length(ptr);
297
str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
299
return decimal_value;
303
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
306
return field_charset->coll->strnncollsp(field_charset,
307
a, a_length, b, b_length,
312
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
315
unsigned char *blob1,*blob2;
316
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
317
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
318
uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
319
set_if_smaller(a_len, max_length);
320
set_if_smaller(b_len, max_length);
321
return Field_blob::cmp(blob1,a_len,blob2,b_len);
325
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
330
uint32_t a_length,b_length;
331
memcpy(&a,a_ptr+packlength,sizeof(char*));
332
memcpy(&b,b_ptr+packlength,sizeof(char*));
333
a_length=get_length(a_ptr);
334
if (a_length > max_length)
336
b_length=get_length(b_ptr);
337
if (b_length > max_length)
339
diff=memcmp(a,b,cmin(a_length,b_length));
340
return diff ? diff : (int) (a_length - b_length);
344
/* The following is used only when comparing a key */
346
uint32_t Field_blob::get_key_image(unsigned char *buff,
348
imagetype type_arg __attribute__((unused)))
350
uint32_t blob_length= get_length(ptr);
354
uint32_t local_char_length= length / field_charset->mbmaxlen;
355
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
357
set_if_smaller(blob_length, local_char_length);
359
if ((uint32_t) length > blob_length)
362
Must clear this as we do a memcmp in opt_range.cc to detect
365
memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
366
length=(uint) blob_length;
368
int2store(buff,length);
369
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
370
return HA_KEY_BLOB_LENGTH+length;
374
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
376
length= uint2korr(buff);
377
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
382
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
384
unsigned char *blob1;
385
uint32_t blob_length=get_length(ptr);
386
memcpy(&blob1,ptr+packlength,sizeof(char*));
387
const CHARSET_INFO * const cs= charset();
388
uint32_t local_char_length= max_key_length / cs->mbmaxlen;
389
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
391
set_if_smaller(blob_length, local_char_length);
392
return Field_blob::cmp(blob1, blob_length,
393
key_ptr+HA_KEY_BLOB_LENGTH,
397
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
399
return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
400
b+HA_KEY_BLOB_LENGTH, uint2korr(b));
405
Save the field metadata for blob fields.
407
Saves the pack length in the first byte of the field metadata array
408
at index of *metadata_ptr.
410
@param metadata_ptr First byte of field metadata
412
@returns number of bytes written to metadata_ptr
414
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
416
*metadata_ptr= pack_length_no_ptr();
421
uint32_t Field_blob::sort_length() const
423
return (uint32_t) (current_thd->variables.max_sort_length +
424
(field_charset == &my_charset_bin ? 0 : packlength));
428
void Field_blob::sort_string(unsigned char *to,uint32_t length)
431
uint32_t blob_length=get_length();
434
memset(to, 0, length);
437
if (field_charset == &my_charset_bin)
442
Store length of blob last in blob to shorter blobs before longer blobs
447
switch (packlength) {
449
*pos= (char) blob_length;
452
mi_int2store(pos, blob_length);
455
mi_int3store(pos, blob_length);
458
mi_int4store(pos, blob_length);
462
memcpy(&blob,ptr+packlength,sizeof(char*));
464
blob_length=my_strnxfrm(field_charset,
465
to, length, blob, blob_length);
466
assert(blob_length == length);
471
void Field_blob::sql_type(String &res) const
473
if (charset() == &my_charset_bin)
474
res.set_ascii(STRING_WITH_LEN("blob"));
476
res.set_ascii(STRING_WITH_LEN("text"));
479
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
480
uint32_t max_length, bool low_byte_first)
482
unsigned char *save= ptr;
483
ptr= (unsigned char*) from;
484
uint32_t length=get_length(); // Length of from string
487
Store max length, which will occupy packlength bytes. If the max
488
length given is smaller than the actual length of the blob, we
489
just store the initial bytes of the blob.
491
store_length(to, packlength, cmin(length, max_length), low_byte_first);
494
Store the actual blob data, which will occupy 'length' bytes.
498
get_ptr((unsigned char**) &from);
499
memcpy(to+packlength, from,length);
501
ptr=save; // Restore org row pointer
502
return(to+packlength+length);
507
Unpack a blob field from row data.
509
This method is used to unpack a blob field from a master whose size of
510
the field is less than that of the slave. Note: This method is included
511
to satisfy inheritance rules, but is not needed for blob fields. It
512
simply is used as a pass-through to the original unpack() method for
515
@param to Destination of the data
516
@param from Source of the data
517
@param param_data @c true if base types should be stored in little-
518
endian format, @c false if native format should
521
@return New pointer into memory based on from + length of the data
523
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
524
const unsigned char *from,
528
uint32_t const master_packlength=
529
param_data > 0 ? param_data & 0xFF : packlength;
530
uint32_t const length= get_length(from, master_packlength, low_byte_first);
531
bitmap_set_bit(table->write_set, field_index);
532
store(reinterpret_cast<const char*>(from) + master_packlength,
533
length, field_charset);
534
return(from + master_packlength + length);
537
/* Keys for blobs are like keys on varchars */
539
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
540
bool insert_or_update)
542
uint32_t a_length, b_length;
543
if (key_length_arg > 255)
545
a_length=uint2korr(a); a+=2;
546
b_length=uint2korr(b); b+=2;
550
a_length= (uint) *a++;
551
b_length= (uint) *b++;
553
return field_charset->coll->strnncollsp(field_charset,
560
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
561
bool insert_or_update)
564
uint32_t a_length, b_length;
565
memcpy(&a,ptr+packlength,sizeof(char*));
567
return key_length_arg > 0 ? -1 : 0;
569
a_length= get_length(ptr);
570
if (key_length_arg > 255)
572
b_length= uint2korr(b); b+=2;
575
b_length= (uint) *b++;
576
return field_charset->coll->strnncollsp(field_charset,
582
/** Create a packed key that will be used for storage from a MySQL row. */
585
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
586
bool low_byte_first __attribute__((unused)))
588
unsigned char *save= ptr;
589
ptr= (unsigned char*) from;
590
uint32_t length=get_length(); // Length of from string
591
uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
592
max_length/field_charset->mbmaxlen : max_length);
594
get_ptr((unsigned char**) &from);
595
if (length > local_char_length)
596
local_char_length= my_charpos(field_charset, from, from+length,
598
set_if_smaller(length, local_char_length);
599
*to++= (unsigned char) length;
600
if (max_length > 255) // 2 byte length
601
*to++= (unsigned char) (length >> 8);
602
memcpy(to, from, length);
603
ptr=save; // Restore org row pointer
609
Unpack a blob key into a record buffer.
611
A blob key has a maximum size of 64K-1.
612
In its packed form, the length field is one or two bytes long,
613
depending on 'max_length'.
614
Depending on the maximum length of a blob, its length field is
615
put into 1 to 4 bytes. This is a property of the blob object,
616
described by 'packlength'.
617
Blobs are internally stored apart from the record buffer, which
618
contains a pointer to the blob buffer.
621
@param to Pointer into the record buffer.
622
@param from Pointer to the packed key.
623
@param max_length Key length limit from key description.
626
Pointer into 'from' past the last byte copied from packed key.
629
const unsigned char *
630
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
631
bool low_byte_first __attribute__((unused)))
633
/* get length of the blob key */
634
uint32_t length= *from++;
635
if (max_length > 255)
636
length+= *from++ << 8;
638
/* put the length into the record buffer */
639
put_length(to, length);
641
/* put the address of the blob buffer or NULL */
643
memcpy(to + packlength, &from, sizeof(from));
645
memset(to + packlength, 0, sizeof(from));
647
/* point to first byte of next field in 'from' */
648
return from + length;
652
/** Create a packed key that will be used for storage from a MySQL key. */
655
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
656
bool low_byte_first __attribute__((unused)))
658
uint32_t length=uint2korr(from);
659
if (length > max_length)
661
*to++= (char) (length & 255);
662
if (max_length > 255)
663
*to++= (char) (length >> 8);
665
memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
670
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
673
return uint2korr(data_ptr)+2;
674
return (uint) *data_ptr + 1;
678
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
680
return (max_length > 255 ? 2 : 1)+max_length;
684
uint32_t Field_blob::is_equal(Create_field *new_field)
686
if (compare_str_field_flags(new_field, flags))
689
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
690
&& new_field->charset == field_charset &&
691
((Field_blob *)new_field->field)->max_data_length() ==
697
maximum possible display length for blob.
703
uint32_t Field_blob::max_display_length()
708
return 255 * field_charset->mbmaxlen;
710
return 65535 * field_charset->mbmaxlen;
712
return 16777215 * field_charset->mbmaxlen;
714
return (uint32_t) 4294967295U;
716
assert(0); // we should never go here