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
23
#include <drizzled/field/blob.h>
24
#include <drizzled/table.h>
25
#include <drizzled/session.h>
26
#include "plugin/myisam/myisam.h"
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)));
43
/****************************************************************************
45
** A blob is saved as a length and a pointer. The length is stored in the
46
** packlength slot and may be from 1-4.
47
****************************************************************************/
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
uint32_t blob_pack_length,
55
const CHARSET_INFO * const cs)
57
blob_pack_length_to_max_length(blob_pack_length),
62
packlength(blob_pack_length)
66
/* TODO: why do not fill table->getShare()->blob_field array here? */
69
void Field_blob::store_length(unsigned char *i_ptr,
70
uint32_t i_packlength,
74
#ifndef WORDS_BIGENDIAN
77
switch (i_packlength) {
79
i_ptr[0]= (unsigned char) i_number;
82
#ifdef WORDS_BIGENDIAN
85
int2store(i_ptr,(unsigned short) i_number);
89
shortstore(i_ptr,(unsigned short) i_number);
92
int3store(i_ptr,i_number);
95
#ifdef WORDS_BIGENDIAN
98
int4store(i_ptr,i_number);
102
longstore(i_ptr,i_number);
107
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
110
store_length(i_ptr, i_packlength, i_number, getTable()->getShare()->db_low_byte_first);
114
uint32_t Field_blob::get_length(const unsigned char *pos,
115
uint32_t packlength_arg,
118
#ifndef WORDS_BIGENDIAN
119
(void)low_byte_first;
121
switch (packlength_arg) {
123
return (uint32_t) pos[0];
127
#ifdef WORDS_BIGENDIAN
133
return (uint32_t) tmp;
136
return (uint32_t) uint3korr(pos);
140
#ifdef WORDS_BIGENDIAN
146
return (uint32_t) tmp;
149
return 0; // Impossible
153
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
156
return packlength + get_length(ptr_arg, packlength, low_byte_first);
160
uint32_t Field_blob::get_length(uint32_t row_offset)
162
return get_length(ptr+row_offset, this->packlength,
163
getTable()->getShare()->db_low_byte_first);
167
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
169
return get_length(ptr_arg, this->packlength, getTable()->getShare()->db_low_byte_first);
174
Put a blob length field into a record buffer.
176
Depending on the maximum length of a blob, its length field is
177
put into 1 to 4 bytes. This is a property of the blob object,
178
described by 'packlength'.
180
@param pos Pointer into the record buffer.
181
@param length The length value to put.
184
void Field_blob::put_length(unsigned char *pos, uint32_t length)
186
switch (packlength) {
191
int2store(pos, length);
194
int3store(pos, length);
197
int4store(pos, length);
203
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
205
uint32_t copy_length, new_length;
206
const char *well_formed_error_pos;
207
const char *cannot_convert_error_pos;
208
const char *from_end_pos, *tmp;
209
char buff[STRING_BUFFER_USUAL_SIZE];
210
String tmpstr(buff,sizeof(buff), &my_charset_bin);
212
ASSERT_COLUMN_MARKED_FOR_WRITE;
216
memset(ptr, 0, Field_blob::pack_length());
220
if (from == value.ptr())
222
uint32_t dummy_offset;
223
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
225
Field_blob::store_length(length);
226
memmove(ptr+packlength, &from, sizeof(char*));
229
if (tmpstr.copy(from, length, cs))
234
new_length= min(max_data_length(), field_charset->mbmaxlen * length);
235
if (value.alloc(new_length))
239
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
240
is never used to limit the length of the data. The cut of long data
241
is done with the new_length value.
243
copy_length= well_formed_copy_nchars(field_charset,
244
(char*) value.ptr(), new_length,
247
&well_formed_error_pos,
248
&cannot_convert_error_pos,
251
Field_blob::store_length(copy_length);
253
memmove(ptr+packlength, &tmp, sizeof(char*));
255
if (check_string_copy_error(this, well_formed_error_pos,
256
cannot_convert_error_pos, from + length, cs))
259
return report_if_important_data(from_end_pos, from + length);
262
/* Fatal OOM error */
263
memset(ptr, 0, Field_blob::pack_length());
268
int Field_blob::store(double nr)
270
const CHARSET_INFO * const cs=charset();
271
ASSERT_COLUMN_MARKED_FOR_WRITE;
272
value.set_real(nr, NOT_FIXED_DEC, cs);
273
return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
277
int Field_blob::store(int64_t nr, bool unsigned_val)
279
const CHARSET_INFO * const cs=charset();
280
ASSERT_COLUMN_MARKED_FOR_WRITE;
281
value.set_int(nr, unsigned_val, cs);
282
return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
286
double Field_blob::val_real(void)
289
char *end_not_used, *blob;
291
const CHARSET_INFO *cs;
293
ASSERT_COLUMN_MARKED_FOR_READ;
295
memcpy(&blob,ptr+packlength,sizeof(char*));
298
length= get_length(ptr);
300
return my_strntod(cs, blob, length, &end_not_used, ¬_used);
304
int64_t Field_blob::val_int(void)
309
ASSERT_COLUMN_MARKED_FOR_READ;
311
memcpy(&blob,ptr+packlength,sizeof(char*));
314
uint32_t length=get_length(ptr);
315
return my_strntoll(charset(),blob,length,10,NULL,¬_used);
318
String *Field_blob::val_str(String *,
323
ASSERT_COLUMN_MARKED_FOR_READ;
325
memcpy(&blob,ptr+packlength,sizeof(char*));
327
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
329
val_ptr->set((const char*) blob,get_length(ptr),charset());
334
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
339
ASSERT_COLUMN_MARKED_FOR_READ;
341
memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
348
length= get_length(ptr);
350
str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
352
return decimal_value;
356
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
359
return field_charset->coll->strnncollsp(field_charset,
360
a, a_length, b, b_length,
365
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
368
unsigned char *blob1,*blob2;
369
memcpy(&blob1,a_ptr+packlength,sizeof(char*));
370
memcpy(&blob2,b_ptr+packlength,sizeof(char*));
371
uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
372
set_if_smaller(a_len, max_length);
373
set_if_smaller(b_len, max_length);
374
return Field_blob::cmp(blob1,a_len,blob2,b_len);
378
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
383
uint32_t a_length,b_length;
384
memcpy(&a,a_ptr+packlength,sizeof(char*));
385
memcpy(&b,b_ptr+packlength,sizeof(char*));
387
a_length= get_length(a_ptr);
389
if (a_length > max_length)
390
a_length= max_length;
392
b_length= get_length(b_ptr);
394
if (b_length > max_length)
395
b_length= max_length;
397
diff= memcmp(a,b,min(a_length,b_length));
399
return diff ? diff : (int) (a_length - b_length);
402
/* The following is used only when comparing a key */
403
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
405
uint32_t blob_length= get_length(ptr);
409
uint32_t local_char_length= length / field_charset->mbmaxlen;
410
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
412
set_if_smaller(blob_length, local_char_length);
414
if ((uint32_t) length > blob_length)
417
Must clear this as we do a memcmp in optimizer/range.cc to detect
420
memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
421
length=(uint32_t) blob_length;
423
int2store(buff,length);
424
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
425
return HA_KEY_BLOB_LENGTH+length;
429
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
431
uint32_t blob_length= get_length(ptr);
435
uint32_t local_char_length= length / field_charset->mbmaxlen;
436
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
438
set_if_smaller(blob_length, local_char_length);
440
unsigned char len_buff[HA_KEY_BLOB_LENGTH];
441
int2store(len_buff,length);
442
buff.append(len_buff);
443
buff.append(blob, blob_length);
445
if (length > blob_length)
448
Must clear this as we do a memcmp in optimizer/range.cc to detect
452
buff.append(length-blob_length, '0');
454
return HA_KEY_BLOB_LENGTH+length;
457
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
459
length= uint2korr(buff);
460
(void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
463
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
465
unsigned char *blob1;
466
uint32_t blob_length=get_length(ptr);
467
memcpy(&blob1,ptr+packlength,sizeof(char*));
468
const CHARSET_INFO * const cs= charset();
469
uint32_t local_char_length= max_key_length / cs->mbmaxlen;
470
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
472
set_if_smaller(blob_length, local_char_length);
473
return Field_blob::cmp(blob1, blob_length,
474
key_ptr+HA_KEY_BLOB_LENGTH,
478
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
480
return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
481
b+HA_KEY_BLOB_LENGTH, uint2korr(b));
484
uint32_t Field_blob::sort_length() const
486
return (uint32_t) (current_session->variables.max_sort_length +
487
(field_charset == &my_charset_bin ? 0 : packlength));
490
void Field_blob::sort_string(unsigned char *to,uint32_t length)
493
uint32_t blob_length=get_length();
496
memset(to, 0, length);
499
if (field_charset == &my_charset_bin)
504
Store length of blob last in blob to shorter blobs before longer blobs
509
switch (packlength) {
511
*pos= (char) blob_length;
514
mi_int2store(pos, blob_length);
517
mi_int3store(pos, blob_length);
520
mi_int4store(pos, blob_length);
524
memcpy(&blob,ptr+packlength,sizeof(char*));
526
blob_length=my_strnxfrm(field_charset,
527
to, length, blob, blob_length);
528
assert(blob_length == length);
532
uint32_t Field_blob::pack_length() const
534
return (uint32_t) (packlength + getTable()->getShare()->blob_ptr_size);
537
void Field_blob::sql_type(String &res) const
539
if (charset() == &my_charset_bin)
540
res.set_ascii(STRING_WITH_LEN("blob"));
542
res.set_ascii(STRING_WITH_LEN("text"));
545
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
546
uint32_t max_length, bool low_byte_first)
548
unsigned char *save= ptr;
549
ptr= (unsigned char*) from;
550
uint32_t length= get_length(); // Length of from string
553
Store max length, which will occupy packlength bytes. If the max
554
length given is smaller than the actual length of the blob, we
555
just store the initial bytes of the blob.
557
store_length(to, packlength, min(length, max_length), low_byte_first);
560
Store the actual blob data, which will occupy 'length' bytes.
564
get_ptr((unsigned char**) &from);
565
memcpy(to+packlength, from,length);
568
ptr= save; // Restore org row pointer
569
return(to+packlength+length);
573
Unpack a blob field from row data.
575
This method is used to unpack a blob field from a master whose size of
576
the field is less than that of the slave. Note: This method is included
577
to satisfy inheritance rules, but is not needed for blob fields. It
578
simply is used as a pass-through to the original unpack() method for
581
@param to Destination of the data
582
@param from Source of the data
583
@param param_data @c true if base types should be stored in little-
584
endian format, @c false if native format should
587
@return New pointer into memory based on from + length of the data
589
const unsigned char *Field_blob::unpack(unsigned char *,
590
const unsigned char *from,
594
uint32_t const master_packlength=
595
param_data > 0 ? param_data & 0xFF : packlength;
596
uint32_t const length= get_length(from, master_packlength, low_byte_first);
597
getTable()->setWriteSet(field_index);
598
store(reinterpret_cast<const char*>(from) + master_packlength,
599
length, field_charset);
600
return(from + master_packlength + length);
603
/** Create a packed key that will be used for storage from a MySQL row. */
606
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
609
unsigned char *save= ptr;
610
ptr= (unsigned char*) from;
611
uint32_t length=get_length(); // Length of from string
612
uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
613
max_length/field_charset->mbmaxlen : max_length);
615
get_ptr((unsigned char**) &from);
616
if (length > local_char_length)
617
local_char_length= my_charpos(field_charset, from, from+length,
619
set_if_smaller(length, local_char_length);
620
*to++= (unsigned char) length;
621
if (max_length > 255) // 2 byte length
622
*to++= (unsigned char) (length >> 8);
623
memcpy(to, from, length);
624
ptr=save; // Restore org row pointer
630
maximum possible display length for blob.
636
uint32_t Field_blob::max_display_length()
641
return 255 * field_charset->mbmaxlen;
643
return 65535 * field_charset->mbmaxlen;
645
return 16777215 * field_charset->mbmaxlen;
647
return (uint32_t) 4294967295U;
649
assert(0); // we should never go here
654
} /* namespace drizzled */