23 #include <drizzled/field/blob.h>
24 #include <drizzled/table.h>
25 #include <drizzled/session.h>
26 #include <plugin/myisam/myisam.h>
27 #include <drizzled/system_variables.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)));
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 const charset_info_st *
const cs)
56 blob_pack_length_to_max_length(sizeof(uint32_t)),
67 void Field_blob::store_length(
unsigned char *i_ptr,
71 #ifndef WORDS_BIGENDIAN
75 #ifdef WORDS_BIGENDIAN
78 int4store(i_ptr,i_number);
82 longstore(i_ptr,i_number);
86 void Field_blob::store_length(
unsigned char *i_ptr, uint32_t i_number)
88 store_length(i_ptr, i_number, getTable()->getShare()->db_low_byte_first);
92 uint32_t Field_blob::get_length(
const unsigned char *pos,
93 bool low_byte_first)
const
95 #ifndef WORDS_BIGENDIAN
99 #ifdef WORDS_BIGENDIAN
105 return (uint32_t) tmp;
112 return sizeof(uint32_t) + get_length(ptr_arg, low_byte_first);
116 uint32_t Field_blob::get_length(uint32_t row_offset)
const
118 return get_length(
ptr+row_offset,
119 getTable()->getShare()->db_low_byte_first);
123 uint32_t Field_blob::get_length(
const unsigned char *ptr_arg)
const
125 return get_length(ptr_arg, getTable()->getShare()->db_low_byte_first);
140 int4store(pos, length);
144 int Field_blob::store(
const char *from,uint32_t length,
const charset_info_st *
const cs)
146 uint32_t copy_length, new_length;
147 const char *well_formed_error_pos;
148 const char *cannot_convert_error_pos;
149 const char *from_end_pos, *tmp;
150 char buff[STRING_BUFFER_USUAL_SIZE];
151 String tmpstr(buff,
sizeof(buff), &my_charset_bin);
153 ASSERT_COLUMN_MARKED_FOR_WRITE;
161 if (from == value.ptr())
163 if (!String::needs_conversion(length, cs, field_charset))
165 Field_blob::store_length(length);
166 memmove(
ptr+
sizeof(uint32_t), &from,
sizeof(
char*));
169 tmpstr.copy(from, length, cs);
174 value.alloc(new_length);
181 copy_length= well_formed_copy_nchars(field_charset,
182 (
char*) value.ptr(), new_length,
185 &well_formed_error_pos,
186 &cannot_convert_error_pos,
189 Field_blob::store_length(copy_length);
191 memmove(
ptr+
sizeof(uint32_t), &tmp,
sizeof(
char*));
193 if (check_string_copy_error(
this, well_formed_error_pos,
194 cannot_convert_error_pos, from + length, cs))
197 return report_if_important_data(from_end_pos, from + length);
200 int Field_blob::store(
double nr)
202 const charset_info_st *
const cs=charset();
203 ASSERT_COLUMN_MARKED_FOR_WRITE;
204 value.set_real(nr, NOT_FIXED_DEC, cs);
205 return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
208 int Field_blob::store(int64_t nr,
bool unsigned_val)
210 const charset_info_st *
const cs=charset();
211 ASSERT_COLUMN_MARKED_FOR_WRITE;
212 value.set_int(nr, unsigned_val, cs);
213 return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
217 double Field_blob::val_real(
void)
const
220 char *end_not_used, *blob;
222 const charset_info_st *cs;
224 ASSERT_COLUMN_MARKED_FOR_READ;
226 memcpy(&blob,
ptr+
sizeof(uint32_t),
sizeof(
char*));
229 length= get_length(
ptr);
231 return my_strntod(cs, blob, length, &end_not_used, ¬_used);
235 int64_t Field_blob::val_int(
void)
const
240 ASSERT_COLUMN_MARKED_FOR_READ;
242 memcpy(&blob,
ptr+
sizeof(uint32_t),
sizeof(
char*));
245 uint32_t length= get_length(
ptr);
246 return my_strntoll(charset(),blob,length,10,NULL,¬_used);
249 String *Field_blob::val_str(String *, String *val_ptr)
const
253 ASSERT_COLUMN_MARKED_FOR_READ;
255 memcpy(&blob,
ptr+
sizeof(uint32_t),
sizeof(
char*));
257 val_ptr->set(
"",0,charset());
259 val_ptr->set(blob,get_length(
ptr),charset());
264 type::Decimal *Field_blob::val_decimal(type::Decimal *decimal_value)
const
269 ASSERT_COLUMN_MARKED_FOR_READ;
271 memcpy(&blob,
ptr+
sizeof(uint32_t),
sizeof(
const unsigned char*));
279 length= get_length(
ptr);
282 decimal_value->store(E_DEC_FATAL_ERROR, blob, length, charset());
284 return decimal_value;
288 int Field_blob::cmp(
const unsigned char *a,uint32_t a_length,
const unsigned char *b,
291 return field_charset->coll->strnncollsp(field_charset,
292 a, a_length, b, b_length,
297 int Field_blob::cmp_max(
const unsigned char *a_ptr,
const unsigned char *b_ptr,
300 unsigned char *blob1,*blob2;
301 memcpy(&blob1,a_ptr+
sizeof(uint32_t),
sizeof(
char*));
302 memcpy(&blob2,b_ptr+
sizeof(uint32_t),
sizeof(
char*));
303 uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
304 set_if_smaller(a_len, max_length);
305 set_if_smaller(b_len, max_length);
306 return Field_blob::cmp(blob1,a_len,blob2,b_len);
310 int Field_blob::cmp_binary(
const unsigned char *a_ptr,
const unsigned char *b_ptr,
315 uint32_t a_length,b_length;
316 memcpy(&a,a_ptr+
sizeof(uint32_t),
sizeof(
char*));
317 memcpy(&b,b_ptr+
sizeof(uint32_t),
sizeof(
char*));
319 a_length= get_length(a_ptr);
321 if (a_length > max_length)
322 a_length= max_length;
324 b_length= get_length(b_ptr);
326 if (b_length > max_length)
327 b_length= max_length;
329 diff= memcmp(a,b,min(a_length,b_length));
331 return diff ? diff : (
unsigned int) (a_length - b_length);
337 uint32_t blob_length= get_length(
ptr);
338 unsigned char *blob= get_ptr();
339 uint32_t local_char_length= length / field_charset->mbmaxlen;
340 local_char_length= my_charpos(field_charset, blob, blob + blob_length,
342 set_if_smaller(blob_length, local_char_length);
344 if ((uint32_t) length > blob_length)
350 memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
351 length=(uint32_t) blob_length;
353 int2store(buff,length);
354 memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
355 return HA_KEY_BLOB_LENGTH+length;
360 uint32_t blob_length= get_length(
ptr);
361 unsigned char* blob= get_ptr();
362 uint32_t local_char_length= length / field_charset->mbmaxlen;
363 local_char_length= my_charpos(field_charset, blob, blob + blob_length,
365 set_if_smaller(blob_length, local_char_length);
367 unsigned char len_buff[HA_KEY_BLOB_LENGTH];
368 int2store(len_buff,length);
369 buff.append(len_buff);
370 buff.append(blob, blob_length);
372 if (length > blob_length)
379 buff.append(length-blob_length,
'0');
381 return HA_KEY_BLOB_LENGTH+length;
384 void Field_blob::set_key_image(
const unsigned char *buff,uint32_t length)
386 length= uint2korr(buff);
387 (void) Field_blob::store((
const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
390 int Field_blob::key_cmp(
const unsigned char *key_ptr, uint32_t max_key_length)
392 unsigned char *blob1;
393 uint32_t blob_length=get_length(
ptr);
394 memcpy(&blob1,
ptr+
sizeof(uint32_t),
sizeof(
char*));
395 const charset_info_st *
const cs= charset();
396 uint32_t local_char_length= max_key_length / cs->mbmaxlen;
397 local_char_length= my_charpos(cs, blob1, blob1+blob_length,
399 set_if_smaller(blob_length, local_char_length);
400 return Field_blob::cmp(blob1, blob_length,
401 key_ptr+HA_KEY_BLOB_LENGTH,
405 int Field_blob::key_cmp(
const unsigned char *a,
const unsigned char *b)
407 return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
408 b+HA_KEY_BLOB_LENGTH, uint2korr(b));
411 uint32_t Field_blob::sort_length()
const
413 return (uint32_t) (getTable()->getSession()->
variables.max_sort_length +
414 (field_charset == &my_charset_bin ? 0 :
sizeof(uint32_t)));
417 void Field_blob::sort_string(
unsigned char *to,uint32_t length)
420 uint32_t blob_length=get_length();
423 memset(to, 0, length);
426 if (field_charset == &my_charset_bin)
433 length-=
sizeof(uint32_t);
436 mi_int4store(pos, blob_length);
438 memcpy(&blob,
ptr+
sizeof(uint32_t),
sizeof(
char*));
440 blob_length= field_charset->strnxfrm(to, length, blob, blob_length);
441 assert(blob_length == length);
447 return (uint32_t) (
sizeof(uint32_t) + portable_sizeof_char_ptr);
451 uint32_t max_length,
bool low_byte_first)
453 unsigned char *save=
ptr;
454 ptr= (
unsigned char*) from;
455 uint32_t length= get_length();
462 store_length(to, min(length, max_length), low_byte_first);
470 memcpy(to+
sizeof(uint32_t), from,length);
474 return(to+
sizeof(uint32_t)+length);
495 const unsigned char *from,
499 uint32_t
const length= get_length(from, low_byte_first);
500 getTable()->setWriteSet(position());
501 store(reinterpret_cast<const char*>(from) +
sizeof(uint32_t),
502 length, field_charset);
503 return(from +
sizeof(uint32_t) + length);
512 unsigned char *save=
ptr;
513 ptr= (
unsigned char*) from;
514 uint32_t length=get_length();
515 uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
516 max_length/field_charset->mbmaxlen : max_length);
519 if (length > local_char_length)
520 local_char_length= my_charpos(field_charset, from, from+length,
522 set_if_smaller(length, local_char_length);
523 *to++= (
unsigned char) length;
524 if (max_length > 255)
525 *to++= (
unsigned char) (length >> 8);
526 memcpy(to, from, length);
541 return (uint32_t) 4294967295U;