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/varstring.h>
24
#include <drizzled/table.h>
25
#include <drizzled/session.h>
26
#include "plugin/myisam/myisam.h"
35
/****************************************************************************
37
Data in field->ptr is stored as:
38
1 or 2 bytes length-prefix-header (from Field_varstring::length_bytes)
42
When VARCHAR is stored in a key (for handler::index_read() etc) it's always
43
stored with a 2 byte prefix. (Just like blob keys).
45
Normally length_bytes is calculated as (field_length < 256 : 1 ? 2)
46
The exception is if there is a prefix key field that is part of a long
47
VARCHAR, in which case field_length for this may be 1 but the length_bytes
49
****************************************************************************/
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 * 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 * 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 * 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)
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)
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 *,
158
uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
160
ASSERT_COLUMN_MARKED_FOR_READ;
162
val_ptr->set((const char*) ptr+length_bytes, length, field_charset);
168
my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
172
ASSERT_COLUMN_MARKED_FOR_READ;
174
length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
176
str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
177
charset(), decimal_value);
178
return decimal_value;
182
int Field_varstring::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
185
uint32_t a_length, b_length;
188
if (length_bytes == 1)
190
a_length= (uint32_t) *a_ptr;
191
b_length= (uint32_t) *b_ptr;
195
a_length= uint2korr(a_ptr);
196
b_length= uint2korr(b_ptr);
198
set_if_smaller(a_length, max_len);
199
set_if_smaller(b_length, max_len);
200
diff= field_charset->coll->strnncollsp(field_charset,
213
varstring and blob keys are ALWAYS stored with a 2 byte length prefix
216
int Field_varstring::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
218
uint32_t length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
219
uint32_t local_char_length= max_key_length / field_charset->mbmaxlen;
221
local_char_length= my_charpos(field_charset, ptr + length_bytes,
222
ptr + length_bytes + length, local_char_length);
223
set_if_smaller(length, local_char_length);
224
return field_charset->coll->strnncollsp(field_charset,
229
uint2korr(key_ptr), 0);
234
Compare to key segments (always 2 byte length prefix).
237
This is used only to compare key segments created for index_read().
238
(keys are created and compared in key.cc)
241
int Field_varstring::key_cmp(const unsigned char *a,const unsigned char *b)
243
return field_charset->coll->strnncollsp(field_charset,
244
a + HA_KEY_BLOB_LENGTH,
246
b + HA_KEY_BLOB_LENGTH,
252
void Field_varstring::sort_string(unsigned char *to,uint32_t length)
254
uint32_t tot_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
256
if (field_charset == &my_charset_bin)
258
/* Store length last in high-byte order to sort longer strings first */
259
if (length_bytes == 1)
260
to[length-1]= tot_length;
262
mi_int2store(to+length-2, tot_length);
263
length-= length_bytes;
266
tot_length= my_strnxfrm(field_charset,
267
to, length, ptr + length_bytes,
269
assert(tot_length == length);
273
enum ha_base_keytype Field_varstring::key_type() const
275
enum ha_base_keytype res;
278
res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2;
280
res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2;
285
void Field_varstring::sql_type(String &res) const
287
const CHARSET_INFO * const cs=res.charset();
290
length= cs->cset->snprintf(cs,(char*) res.ptr(),
291
res.alloced_length(), "%s(%d)",
292
(has_charset() ? "varchar" : "varbinary"),
293
(int) field_length / charset()->mbmaxlen);
298
uint32_t Field_varstring::used_length()
300
return length_bytes == 1 ? 1 + (uint32_t) (unsigned char) *ptr : 2 + uint2korr(ptr);
304
Functions to create a packed row.
305
Here the number of length bytes are depending on the given max_length
308
unsigned char *Field_varstring::pack(unsigned char *to, const unsigned char *from,
312
uint32_t length= length_bytes == 1 ? (uint32_t) *from : uint2korr(from);
313
set_if_smaller(max_length, field_length);
314
if (length > max_length)
317
/* Length always stored little-endian */
318
*to++= length & 0xFF;
319
if (max_length > 255)
320
*to++= (length >> 8) & 0xFF;
322
/* Store bytes of string */
324
memcpy(to, from+length_bytes, length);
330
Unpack a varstring field from row data.
332
This method is used to unpack a varstring field from a master
333
whose size of the field is less than that of the slave.
336
The string length is always packed little-endian.
338
@param to Destination of the data
339
@param from Source of the data
340
@param param_data Length bytes from the master's field data
342
@return New pointer into memory based on from + length of the data
344
const unsigned char *
345
Field_varstring::unpack(unsigned char *to, const unsigned char *from,
350
uint32_t l_bytes= (param_data && (param_data < field_length)) ?
351
(param_data <= 255) ? 1 : 2 : length_bytes;
356
if (length_bytes == 2)
359
else /* l_bytes == 2 */
361
length= uint2korr(from);
366
memcpy(to+ length_bytes, from, length);
371
uint32_t Field_varstring::max_packed_col_length(uint32_t max_length)
373
return (max_length > 255 ? 2 : 1)+max_length;
376
uint32_t Field_varstring::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
378
/* Key is always stored with 2 bytes */
379
const uint32_t key_len= 2;
380
uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
381
uint32_t local_char_length= length / field_charset->mbmaxlen;
382
unsigned char *pos= ptr+length_bytes;
383
local_char_length= my_charpos(field_charset, pos, pos + f_length,
385
set_if_smaller(f_length, local_char_length);
386
unsigned char len_buff[key_len];
387
int2store(len_buff,f_length);
388
buff.append(len_buff);
389
buff.append(pos, f_length);
390
if (f_length < length)
393
Must clear this as we do a memcmp in optimizer/range.cc to detect
396
buff.append(length-f_length, 0);
398
return key_len+f_length;
402
uint32_t Field_varstring::get_key_image(unsigned char *buff, uint32_t length)
404
uint32_t f_length= length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
405
uint32_t local_char_length= length / field_charset->mbmaxlen;
406
unsigned char *pos= ptr+length_bytes;
407
local_char_length= my_charpos(field_charset, pos, pos + f_length,
409
set_if_smaller(f_length, local_char_length);
410
/* Key is always stored with 2 bytes */
411
int2store(buff,f_length);
412
memcpy(buff+HA_KEY_BLOB_LENGTH, pos, f_length);
413
if (f_length < length)
416
Must clear this as we do a memcmp in optimizer/range.cc to detect
419
memset(buff+HA_KEY_BLOB_LENGTH+f_length, 0, (length-f_length));
421
return HA_KEY_BLOB_LENGTH+f_length;
424
void Field_varstring::set_key_image(const unsigned char *buff, uint32_t length)
426
length= uint2korr(buff); // Real length is here
427
(void) Field_varstring::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
430
int Field_varstring::cmp_binary(const unsigned char *a_ptr,
431
const unsigned char *b_ptr,
434
uint32_t a_length,b_length;
436
if (length_bytes == 1)
438
a_length= (uint32_t) *a_ptr;
439
b_length= (uint32_t) *b_ptr;
443
a_length= uint2korr(a_ptr);
444
b_length= uint2korr(b_ptr);
446
set_if_smaller(a_length, max_length);
447
set_if_smaller(b_length, max_length);
448
if (a_length != b_length)
450
return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length);
454
Field *Field_varstring::new_field(memory::Root *root, Table *new_table, bool keep_type)
456
Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
459
res->length_bytes= length_bytes;
464
Field *Field_varstring::new_key_field(memory::Root *root,
466
unsigned char *new_ptr, unsigned char *new_null_ptr,
467
uint32_t new_null_bit)
469
Field_varstring *res;
470
if ((res= (Field_varstring*) Field::new_key_field(root,
476
/* Keys length prefixes are always packed with 2 bytes */
477
res->length_bytes= 2;
482
} /* namespace drizzled */