22
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);
27
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
28
((ulong) ((1LL << min(arg, 4) * 8) - 1LL))
35
30
/****************************************************************************
38
33
** packlength slot and may be from 1-4.
39
34
****************************************************************************/
41
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
36
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
42
37
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),
38
TABLE_SHARE *share, uint blob_pack_length,
40
:Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
46
41
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
48
43
packlength(blob_pack_length)
157
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
152
int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
159
uint32_t copy_length, new_length;
154
uint copy_length, new_length;
160
155
const char *well_formed_error_pos;
161
156
const char *cannot_convert_error_pos;
162
157
const char *from_end_pos, *tmp;
175
170
if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
177
172
Field_blob::store_length(length);
178
memcpy(ptr+packlength, &from, sizeof(char*));
173
bmove(ptr+packlength,(char*) &from,sizeof(char*));
181
176
if (tmpstr.copy(from, length, cs))
214
209
Field_blob::store_length(copy_length);
215
210
tmp= value.ptr();
216
memcpy(ptr+packlength, &tmp, sizeof(char*));
211
bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*));
218
213
if (check_string_copy_error(this, well_formed_error_pos,
219
214
cannot_convert_error_pos, from + length, cs))
225
220
/* Fatal OOM error */
226
memset(ptr, 0, Field_blob::pack_length());
221
bzero(ptr,Field_blob::pack_length());
231
226
int Field_blob::store(double nr)
233
const CHARSET_INFO * const cs=charset();
228
CHARSET_INFO *cs=charset();
234
229
value.set_real(nr, NOT_FIXED_DEC, cs);
235
230
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
315
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
310
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *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);
314
memcpy_fixed(&blob1,a_ptr+packlength,sizeof(char*));
315
memcpy_fixed(&blob2,b_ptr+packlength,sizeof(char*));
316
uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
322
317
set_if_smaller(a_len, max_length);
323
318
set_if_smaller(b_len, max_length);
324
319
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,
323
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
329
324
uint32_t max_length)
333
328
uint32_t a_length,b_length;
334
memcpy(&a,a_ptr+packlength,sizeof(char*));
335
memcpy(&b,b_ptr+packlength,sizeof(char*));
329
memcpy_fixed(&a,a_ptr+packlength,sizeof(char*));
330
memcpy_fixed(&b,b_ptr+packlength,sizeof(char*));
336
331
a_length=get_length(a_ptr);
337
332
if (a_length > max_length)
338
333
a_length=max_length;
339
334
b_length=get_length(b_ptr);
340
335
if (b_length > max_length)
341
336
b_length=max_length;
342
diff=memcmp(a,b,cmin(a_length,b_length));
337
diff=memcmp(a,b,min(a_length,b_length));
343
338
return diff ? diff : (int) (a_length - b_length);
347
342
/* 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)))
344
uint Field_blob::get_key_image(uchar *buff,
346
imagetype type_arg __attribute__((__unused__)))
353
348
uint32_t blob_length= get_length(ptr);
357
uint32_t local_char_length= length / field_charset->mbmaxlen;
352
uint local_char_length= length / field_charset->mbmaxlen;
358
353
local_char_length= my_charpos(field_charset, blob, blob + blob_length,
359
354
local_char_length);
360
355
set_if_smaller(blob_length, local_char_length);
385
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
380
int Field_blob::key_cmp(const uchar *key_ptr, uint 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;
383
uint blob_length=get_length(ptr);
384
memcpy_fixed(&blob1,ptr+packlength,sizeof(char*));
385
CHARSET_INFO *cs= charset();
386
uint local_char_length= max_key_length / cs->mbmaxlen;
392
387
local_char_length= my_charpos(cs, blob1, blob1+blob_length,
393
388
local_char_length);
394
389
set_if_smaller(blob_length, local_char_length);
474
469
void Field_blob::sql_type(String &res) const
473
switch (packlength) {
474
default: str="tiny"; length=4; break;
475
case 2: str=""; length=0; break;
476
case 3: str="medium"; length= 6; break;
477
case 4: str="long"; length=4; break;
479
res.set_ascii(str,length);
476
480
if (charset() == &my_charset_bin)
477
res.set_ascii(STRING_WITH_LEN("blob"));
481
res.append(STRING_WITH_LEN("blob"));
479
res.set_ascii(STRING_WITH_LEN("text"));
484
res.append(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)
488
uchar *Field_blob::pack(uchar *to, const uchar *from,
489
uint max_length, bool low_byte_first)
485
unsigned char *save= ptr;
486
ptr= (unsigned char*) from;
487
493
uint32_t length=get_length(); // Length of from string
491
497
length given is smaller than the actual length of the blob, we
492
498
just store the initial bytes of the blob.
494
store_length(to, packlength, cmin(length, max_length), low_byte_first);
500
store_length(to, packlength, min(length, max_length), low_byte_first);
497
503
Store the actual blob data, which will occupy 'length' bytes.
501
get_ptr((unsigned char**) &from);
507
get_ptr((uchar**) &from);
502
508
memcpy(to+packlength, from,length);
504
510
ptr=save; // Restore org row pointer
524
530
@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,
532
const uchar *Field_blob::unpack(uchar *to __attribute__((__unused__)),
529
535
bool low_byte_first)
531
uint32_t const master_packlength=
537
uint const master_packlength=
532
538
param_data > 0 ? param_data & 0xFF : packlength;
533
539
uint32_t const length= get_length(from, master_packlength, low_byte_first);
534
540
bitmap_set_bit(table->write_set, field_index);
540
546
/* 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)
548
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
549
my_bool insert_or_update)
545
uint32_t a_length, b_length;
551
uint a_length, b_length;
546
552
if (key_length_arg > 255)
548
554
a_length=uint2korr(a); a+=2;
563
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
564
bool insert_or_update)
569
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
570
my_bool insert_or_update)
567
uint32_t a_length, b_length;
568
memcpy(&a,ptr+packlength,sizeof(char*));
573
uint a_length, b_length;
574
memcpy_fixed(&a,ptr+packlength,sizeof(char*));
570
576
return key_length_arg > 0 ? -1 : 0;
585
591
/** 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,
594
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
589
595
bool low_byte_first __attribute__((unused)))
591
unsigned char *save= ptr;
592
ptr= (unsigned char*) from;
593
599
uint32_t length=get_length(); // Length of from string
594
uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
600
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
595
601
max_length/field_charset->mbmaxlen : max_length);
597
get_ptr((unsigned char**) &from);
603
get_ptr((uchar**) &from);
598
604
if (length > local_char_length)
599
605
local_char_length= my_charpos(field_charset, from, from+length,
600
606
local_char_length);
601
607
set_if_smaller(length, local_char_length);
602
*to++= (unsigned char) length;
608
*to++= (uchar) length;
603
609
if (max_length > 255) // 2 byte length
604
*to++= (unsigned char) (length >> 8);
610
*to++= (uchar) (length >> 8);
605
611
memcpy(to, from, length);
606
612
ptr=save; // Restore org row pointer
607
613
return to+length;
629
635
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,
639
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
634
640
bool low_byte_first __attribute__((unused)))
636
642
/* get length of the blob key */
644
650
/* put the address of the blob buffer or NULL */
646
memcpy(to + packlength, &from, sizeof(from));
652
memcpy_fixed(to + packlength, &from, sizeof(from));
648
memset(to + packlength, 0, sizeof(from));
654
bzero(to + packlength, sizeof(from));
650
656
/* point to first byte of next field in 'from' */
651
657
return from + length;
655
661
/** 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,
664
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
659
665
bool low_byte_first __attribute__((unused)))
661
uint32_t length=uint2korr(from);
667
uint length=uint2korr(from);
662
668
if (length > max_length)
663
669
length=max_length;
664
670
*to++= (char) (length & 255);