00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023 #include <drizzled/field/varstring.h>
00024 #include <drizzled/table.h>
00025 #include <drizzled/session.h>
00026 #include <plugin/myisam/myisam.h>
00027
00028 #include <string>
00029
00030 using namespace std;
00031
00032 namespace drizzled
00033 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 const uint32_t Field_varstring::MAX_SIZE= UINT16_MAX;
00052
00053 Field_varstring::Field_varstring(unsigned char *ptr_arg,
00054 uint32_t len_arg,
00055 uint32_t length_bytes_arg,
00056 unsigned char *null_ptr_arg,
00057 unsigned char null_bit_arg,
00058 const char *field_name_arg,
00059 const charset_info_st * const cs) :
00060 Field_str(ptr_arg,
00061 len_arg,
00062 null_ptr_arg,
00063 null_bit_arg,
00064 field_name_arg, cs),
00065 length_bytes(length_bytes_arg)
00066 {
00067 }
00068
00069 Field_varstring::Field_varstring(uint32_t len_arg,
00070 bool maybe_null_arg,
00071 const char *field_name_arg,
00072 const charset_info_st * const cs) :
00073 Field_str((unsigned char*) 0,
00074 len_arg,
00075 maybe_null_arg ? (unsigned char*) "": 0,
00076 0,
00077 field_name_arg,
00078 cs),
00079 length_bytes(len_arg < 256 ? 1 :2)
00080 {
00081 }
00082
00083 int Field_varstring::store(const char *from,uint32_t length, const charset_info_st * const cs)
00084 {
00085 uint32_t copy_length;
00086 const char *well_formed_error_pos;
00087 const char *cannot_convert_error_pos;
00088 const char *from_end_pos;
00089
00090 ASSERT_COLUMN_MARKED_FOR_WRITE;
00091
00092 copy_length= well_formed_copy_nchars(field_charset,
00093 (char*) ptr + length_bytes,
00094 field_length,
00095 cs, from, length,
00096 field_length / field_charset->mbmaxlen,
00097 &well_formed_error_pos,
00098 &cannot_convert_error_pos,
00099 &from_end_pos);
00100
00101 if (length_bytes == 1)
00102 *ptr= (unsigned char) copy_length;
00103 else
00104 int2store(ptr, copy_length);
00105
00106 if (check_string_copy_error(this, well_formed_error_pos,
00107 cannot_convert_error_pos, from + length, cs))
00108 return 2;
00109
00110 return report_if_important_data(from_end_pos, from + length);
00111 }
00112
00113
00114 int Field_varstring::store(int64_t nr, bool unsigned_val)
00115 {
00116 char buff[64];
00117 uint32_t length;
00118 length= (uint32_t) (field_charset->cset->int64_t10_to_str)(field_charset,
00119 buff,
00120 sizeof(buff),
00121 (unsigned_val ? 10: -10),
00122 nr);
00123 return Field_varstring::store(buff, length, field_charset);
00124 }
00125
00126
00127 double Field_varstring::val_real(void) const
00128 {
00129 int not_used;
00130 char *end_not_used;
00131
00132 ASSERT_COLUMN_MARKED_FOR_READ;
00133
00134 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00135
00136 return my_strntod(field_charset, (char*) ptr+length_bytes, length,
00137 &end_not_used, ¬_used);
00138 }
00139
00140
00141 int64_t Field_varstring::val_int(void) const
00142 {
00143 int not_used;
00144 char *end_not_used;
00145 uint32_t length;
00146
00147 ASSERT_COLUMN_MARKED_FOR_READ;
00148
00149 length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00150
00151 return my_strntoll(field_charset, (char*) ptr+length_bytes, length, 10,
00152 &end_not_used, ¬_used);
00153 }
00154
00155 String *Field_varstring::val_str(String *, String *val_ptr) const
00156 {
00157 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00158
00159 ASSERT_COLUMN_MARKED_FOR_READ;
00160
00161 val_ptr->set((const char*) ptr+length_bytes, length, field_charset);
00162
00163 return val_ptr;
00164 }
00165
00166
00167 type::Decimal *Field_varstring::val_decimal(type::Decimal *decimal_value) const
00168 {
00169 uint32_t length;
00170
00171 ASSERT_COLUMN_MARKED_FOR_READ;
00172
00173 length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00174
00175 decimal_value->store(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length, charset());
00176
00177 return decimal_value;
00178 }
00179
00180
00181 int Field_varstring::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
00182 uint32_t max_len)
00183 {
00184 uint32_t a_length, b_length;
00185 int diff;
00186
00187 if (length_bytes == 1)
00188 {
00189 a_length= (uint32_t) *a_ptr;
00190 b_length= (uint32_t) *b_ptr;
00191 }
00192 else
00193 {
00194 a_length= uint2korr(a_ptr);
00195 b_length= uint2korr(b_ptr);
00196 }
00197 set_if_smaller(a_length, max_len);
00198 set_if_smaller(b_length, max_len);
00199 diff= field_charset->coll->strnncollsp(field_charset,
00200 a_ptr+
00201 length_bytes,
00202 a_length,
00203 b_ptr+
00204 length_bytes,
00205 b_length,0);
00206 return diff;
00207 }
00208
00209
00215 int Field_varstring::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
00216 {
00217 uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00218 uint32_t local_char_length= max_key_length / field_charset->mbmaxlen;
00219
00220 local_char_length= my_charpos(field_charset, ptr + length_bytes,
00221 ptr + length_bytes + length, local_char_length);
00222 set_if_smaller(length, local_char_length);
00223 return field_charset->coll->strnncollsp(field_charset,
00224 ptr + length_bytes,
00225 length,
00226 key_ptr+
00227 HA_KEY_BLOB_LENGTH,
00228 uint2korr(key_ptr), 0);
00229 }
00230
00231
00240 int Field_varstring::key_cmp(const unsigned char *a,const unsigned char *b)
00241 {
00242 return field_charset->coll->strnncollsp(field_charset,
00243 a + HA_KEY_BLOB_LENGTH,
00244 uint2korr(a),
00245 b + HA_KEY_BLOB_LENGTH,
00246 uint2korr(b),
00247 0);
00248 }
00249
00250
00251 void Field_varstring::sort_string(unsigned char *to,uint32_t length)
00252 {
00253 uint32_t tot_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00254
00255 if (field_charset == &my_charset_bin)
00256 {
00257
00258 if (length_bytes == 1)
00259 to[length-1]= tot_length;
00260 else
00261 mi_int2store(to+length-2, tot_length);
00262 length-= length_bytes;
00263 }
00264
00265 tot_length= field_charset->strnxfrm(to, length, ptr + length_bytes, tot_length);
00266 assert(tot_length == length);
00267 }
00268
00269
00270 enum ha_base_keytype Field_varstring::key_type() const
00271 {
00272 enum ha_base_keytype res;
00273
00274 if (binary())
00275 res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2;
00276 else
00277 res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2;
00278 return res;
00279 }
00280
00281
00282 uint32_t Field_varstring::used_length()
00283 {
00284 return length_bytes == 1 ? 1 + (uint32_t) (unsigned char) *ptr : 2 + uint2korr(ptr);
00285 }
00286
00287
00288
00289
00290
00291
00292 unsigned char *Field_varstring::pack(unsigned char *to, const unsigned char *from,
00293 uint32_t max_length,
00294 bool )
00295 {
00296 uint32_t length= length_bytes == 1 ? (uint32_t) *from : uint2korr(from);
00297 set_if_smaller(max_length, field_length);
00298 if (length > max_length)
00299 length=max_length;
00300
00301
00302 *to++= length & 0xFF;
00303 if (max_length > 255)
00304 *to++= (length >> 8) & 0xFF;
00305
00306
00307 if (length > 0)
00308 memcpy(to, from+length_bytes, length);
00309 return to+length;
00310 }
00311
00312
00328 const unsigned char *
00329 Field_varstring::unpack(unsigned char *to, const unsigned char *from,
00330 uint32_t param_data,
00331 bool )
00332 {
00333 uint32_t length;
00334 uint32_t l_bytes= (param_data && (param_data < field_length)) ?
00335 (param_data <= 255) ? 1 : 2 : length_bytes;
00336 if (l_bytes == 1)
00337 {
00338 to[0]= *from++;
00339 length= to[0];
00340 if (length_bytes == 2)
00341 to[1]= 0;
00342 }
00343 else
00344 {
00345 length= uint2korr(from);
00346 to[0]= *from++;
00347 to[1]= *from++;
00348 }
00349 if (length)
00350 memcpy(to+ length_bytes, from, length);
00351 return from+length;
00352 }
00353
00354
00355 uint32_t Field_varstring::max_packed_col_length(uint32_t max_length)
00356 {
00357 return (max_length > 255 ? 2 : 1)+max_length;
00358 }
00359
00360 uint32_t Field_varstring::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
00361 {
00362
00363 const uint32_t key_len= 2;
00364 uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00365 uint32_t local_char_length= length / field_charset->mbmaxlen;
00366 unsigned char *pos= ptr+length_bytes;
00367 local_char_length= my_charpos(field_charset, pos, pos + f_length,
00368 local_char_length);
00369 set_if_smaller(f_length, local_char_length);
00370 unsigned char len_buff[key_len];
00371 int2store(len_buff,f_length);
00372 buff.append(len_buff);
00373 buff.append(pos, f_length);
00374 if (f_length < length)
00375 {
00376
00377
00378
00379
00380 buff.append(length-f_length, 0);
00381 }
00382 return key_len+f_length;
00383 }
00384
00385
00386 uint32_t Field_varstring::get_key_image(unsigned char *buff, uint32_t length)
00387 {
00388 uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
00389 uint32_t local_char_length= length / field_charset->mbmaxlen;
00390 unsigned char *pos= ptr+length_bytes;
00391 local_char_length= my_charpos(field_charset, pos, pos + f_length,
00392 local_char_length);
00393 set_if_smaller(f_length, local_char_length);
00394
00395 int2store(buff,f_length);
00396 memcpy(buff+HA_KEY_BLOB_LENGTH, pos, f_length);
00397 if (f_length < length)
00398 {
00399
00400
00401
00402
00403 memset(buff+HA_KEY_BLOB_LENGTH+f_length, 0, (length-f_length));
00404 }
00405 return HA_KEY_BLOB_LENGTH+f_length;
00406 }
00407
00408 void Field_varstring::set_key_image(const unsigned char *buff, uint32_t length)
00409 {
00410 length= uint2korr(buff);
00411 (void) Field_varstring::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
00412 }
00413
00414 int Field_varstring::cmp_binary(const unsigned char *a_ptr,
00415 const unsigned char *b_ptr,
00416 uint32_t max_length)
00417 {
00418 uint32_t a_length,b_length;
00419
00420 if (length_bytes == 1)
00421 {
00422 a_length= (uint32_t) *a_ptr;
00423 b_length= (uint32_t) *b_ptr;
00424 }
00425 else
00426 {
00427 a_length= uint2korr(a_ptr);
00428 b_length= uint2korr(b_ptr);
00429 }
00430 set_if_smaller(a_length, max_length);
00431 set_if_smaller(b_length, max_length);
00432 if (a_length != b_length)
00433 return 1;
00434 return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length);
00435 }
00436
00437
00438 Field *Field_varstring::new_field(memory::Root *root, Table *new_table, bool keep_type)
00439 {
00440 Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
00441 keep_type);
00442 if (res)
00443 res->length_bytes= length_bytes;
00444 return res;
00445 }
00446
00447
00448 Field *Field_varstring::new_key_field(memory::Root *root,
00449 Table *new_table,
00450 unsigned char *new_ptr, unsigned char *new_null_ptr,
00451 uint32_t new_null_bit)
00452 {
00453 Field_varstring *res;
00454 if ((res= (Field_varstring*) Field::new_key_field(root,
00455 new_table,
00456 new_ptr,
00457 new_null_ptr,
00458 new_null_bit)))
00459 {
00460
00461 res->length_bytes= 2;
00462 }
00463 return res;
00464 }
00465
00466 }