23 #include <drizzled/field/varstring.h>
24 #include <drizzled/table.h>
25 #include <drizzled/session.h>
26 #include <plugin/myisam/myisam.h>
51 const uint32_t Field_varstring::MAX_SIZE= UINT16_MAX;
53 Field_varstring::Field_varstring(
unsigned char *ptr_arg,
55 uint32_t length_bytes_arg,
56 unsigned char *null_ptr_arg,
57 unsigned char null_bit_arg,
58 const char *field_name_arg,
59 const charset_info_st *
const cs) :
65 length_bytes(length_bytes_arg)
69 Field_varstring::Field_varstring(uint32_t len_arg,
71 const char *field_name_arg,
72 const charset_info_st *
const cs) :
73 Field_str((unsigned char*) 0,
75 maybe_null_arg ? (unsigned char*)
"": 0,
79 length_bytes(len_arg < 256 ? 1 :2)
83 int Field_varstring::store(
const char *from,uint32_t length,
const charset_info_st *
const cs)
86 const char *well_formed_error_pos;
87 const char *cannot_convert_error_pos;
88 const char *from_end_pos;
90 ASSERT_COLUMN_MARKED_FOR_WRITE;
92 copy_length= well_formed_copy_nchars(field_charset,
93 (
char*) ptr + length_bytes,
96 field_length / field_charset->mbmaxlen,
97 &well_formed_error_pos,
98 &cannot_convert_error_pos,
101 if (length_bytes == 1)
102 *ptr= (
unsigned char) copy_length;
104 int2store(ptr, copy_length);
106 if (check_string_copy_error(
this, well_formed_error_pos,
107 cannot_convert_error_pos, from + length, cs))
110 return report_if_important_data(from_end_pos, from + length);
114 int Field_varstring::store(int64_t nr,
bool unsigned_val)
118 length= (uint32_t) (field_charset->cset->int64_t10_to_str)(field_charset,
121 (unsigned_val ? 10: -10),
123 return Field_varstring::store(buff, length, field_charset);
127 double Field_varstring::val_real(
void)
const
132 ASSERT_COLUMN_MARKED_FOR_READ;
134 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
136 return my_strntod(field_charset, (
char*) ptr+length_bytes, length,
137 &end_not_used, ¬_used);
141 int64_t Field_varstring::val_int(
void)
const
147 ASSERT_COLUMN_MARKED_FOR_READ;
149 length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
151 return my_strntoll(field_charset, (
char*) ptr+length_bytes, length, 10,
152 &end_not_used, ¬_used);
155 String *Field_varstring::val_str(String *, String *val_ptr)
const
157 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
159 ASSERT_COLUMN_MARKED_FOR_READ;
161 val_ptr->set((
const char*) ptr+length_bytes, length, field_charset);
167 type::Decimal *Field_varstring::val_decimal(type::Decimal *decimal_value)
const
171 ASSERT_COLUMN_MARKED_FOR_READ;
173 length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
175 decimal_value->store(E_DEC_FATAL_ERROR, (
char*) ptr+length_bytes, length, charset());
177 return decimal_value;
181 int Field_varstring::cmp_max(
const unsigned char *a_ptr,
const unsigned char *b_ptr,
184 uint32_t a_length, b_length;
187 if (length_bytes == 1)
189 a_length= (uint32_t) *a_ptr;
190 b_length= (uint32_t) *b_ptr;
194 a_length= uint2korr(a_ptr);
195 b_length= uint2korr(b_ptr);
197 set_if_smaller(a_length, max_len);
198 set_if_smaller(b_length, max_len);
199 diff= field_charset->coll->strnncollsp(field_charset,
217 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
218 uint32_t local_char_length= max_key_length / field_charset->mbmaxlen;
220 local_char_length= my_charpos(field_charset, ptr + length_bytes,
221 ptr + length_bytes + length, local_char_length);
222 set_if_smaller(length, local_char_length);
223 return field_charset->coll->strnncollsp(field_charset,
228 uint2korr(key_ptr), 0);
242 return field_charset->coll->strnncollsp(field_charset,
243 a + HA_KEY_BLOB_LENGTH,
245 b + HA_KEY_BLOB_LENGTH,
251 void Field_varstring::sort_string(
unsigned char *to,uint32_t length)
253 uint32_t tot_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
255 if (field_charset == &my_charset_bin)
258 if (length_bytes == 1)
259 to[length-1]= tot_length;
261 mi_int2store(to+length-2, tot_length);
262 length-= length_bytes;
265 tot_length= field_charset->strnxfrm(to, length, ptr + length_bytes, tot_length);
266 assert(tot_length == length);
270 enum ha_base_keytype Field_varstring::key_type()
const
272 enum ha_base_keytype res;
275 res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2;
277 res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2;
284 return length_bytes == 1 ? 1 + (uint32_t) (
unsigned char) *ptr : 2 + uint2korr(ptr);
296 uint32_t length= length_bytes == 1 ? (uint32_t) *from : uint2korr(from);
297 set_if_smaller(max_length, field_length);
298 if (length > max_length)
302 *to++= length & 0xFF;
303 if (max_length > 255)
304 *to++= (length >> 8) & 0xFF;
308 memcpy(to, from+length_bytes, length);
328 const unsigned char *
334 uint32_t l_bytes= (param_data && (param_data < field_length)) ?
335 (param_data <= 255) ? 1 : 2 : length_bytes;
340 if (length_bytes == 2)
345 length= uint2korr(from);
350 memcpy(to+ length_bytes, from, length);
355 uint32_t Field_varstring::max_packed_col_length(uint32_t max_length)
357 return (max_length > 255 ? 2 : 1)+max_length;
363 const uint32_t key_len= 2;
364 uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
365 uint32_t local_char_length= length / field_charset->mbmaxlen;
366 unsigned char *pos= ptr+length_bytes;
367 local_char_length= my_charpos(field_charset, pos, pos + f_length,
369 set_if_smaller(f_length, local_char_length);
370 unsigned char len_buff[key_len];
371 int2store(len_buff,f_length);
372 buff.append(len_buff);
373 buff.append(pos, f_length);
374 if (f_length < length)
380 buff.append(length-f_length, 0);
382 return key_len+f_length;
388 uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
389 uint32_t local_char_length= length / field_charset->mbmaxlen;
390 unsigned char *pos= ptr+length_bytes;
391 local_char_length= my_charpos(field_charset, pos, pos + f_length,
393 set_if_smaller(f_length, local_char_length);
395 int2store(buff,f_length);
396 memcpy(buff+HA_KEY_BLOB_LENGTH, pos, f_length);
397 if (f_length < length)
403 memset(buff+HA_KEY_BLOB_LENGTH+f_length, 0, (length-f_length));
405 return HA_KEY_BLOB_LENGTH+f_length;
408 void Field_varstring::set_key_image(
const unsigned char *buff, uint32_t length)
410 length= uint2korr(buff);
411 (void) Field_varstring::store((
const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
414 int Field_varstring::cmp_binary(
const unsigned char *a_ptr,
415 const unsigned char *b_ptr,
418 uint32_t a_length,b_length;
420 if (length_bytes == 1)
422 a_length= (uint32_t) *a_ptr;
423 b_length= (uint32_t) *b_ptr;
427 a_length= uint2korr(a_ptr);
428 b_length= uint2korr(b_ptr);
430 set_if_smaller(a_length, max_length);
431 set_if_smaller(b_length, max_length);
432 if (a_length != b_length)
434 return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length);
438 Field *Field_varstring::new_field(memory::Root *root, Table *new_table,
bool keep_type)
440 Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
443 res->length_bytes= length_bytes;
448 Field *Field_varstring::new_key_field(memory::Root *root,
450 unsigned char *new_ptr,
unsigned char *new_null_ptr,
451 uint32_t new_null_bit)
453 Field_varstring *res;
454 if ((res= (Field_varstring*) Field::new_key_field(root,
461 res->length_bytes= 2;