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
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/str.h>
24
#include <drizzled/error.h>
25
#include <drizzled/table.h>
26
#include <drizzled/session.h>
29
Field_str::Field_str(unsigned char *ptr_arg,uint32_t len_arg,
30
unsigned char *null_ptr_arg,
31
unsigned char null_bit_arg, utype unireg_check_arg,
32
const char *field_name_arg,
33
const CHARSET_INFO * const charset_arg)
34
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
35
unireg_check_arg, field_name_arg)
37
field_charset= charset_arg;
38
if (charset_arg->state & MY_CS_BINSORT)
40
field_derivation= DERIVATION_IMPLICIT;
44
Check if we lost any important data and send a truncation error/warning
47
Field_str::report_if_important_data()
48
ptr - Truncated rest of string
49
end - End of truncated string
52
0 - None was truncated (or we don't count cut fields)
53
2 - Some bytes was truncated
56
Check if we lost any important data (anything in a binary string,
57
or any non-space in others). If only trailing spaces was lost,
58
send a truncation note, otherwise send a truncation error.
62
Field_str::report_if_important_data(const char *field_ptr, const char *end)
64
if ((field_ptr < end) && table->in_use->count_cuted_fields)
66
if (test_if_important_data(field_charset, field_ptr, end))
68
if (table->in_use->abort_on_warning)
69
set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
71
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
73
else /* If we lost only spaces then produce a NOTE, not a WARNING */
74
set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
81
Decimal representation of Field_str.
83
@param d value for storing
86
Field_str is the base class for fields like Field_enum,
87
Field_date and some similar. Some dates use fraction and also
88
string value should be converted to floating point value according
89
our rules, so we use double to store value of decimal in string.
100
int Field_str::store_decimal(const my_decimal *d)
102
char buff[DECIMAL_MAX_STR_LENGTH+1];
103
String str(buff, sizeof(buff), &my_charset_bin);
104
my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
105
return store(str.ptr(), str.length(), str.charset());
108
my_decimal *Field_str::val_decimal(my_decimal *decimal_value)
110
int64_t nr= val_int();
111
int2my_decimal(E_DEC_FATAL_ERROR, nr, 0, decimal_value);
112
return decimal_value;
116
Store double value in Field_varstring.
118
Pretty prints double number into field_length characters buffer.
123
int Field_str::store(double nr)
125
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
126
uint32_t local_char_length= field_length / charset()->mbmaxlen;
130
ASSERT_COLUMN_MARKED_FOR_WRITE;
132
length= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error);
135
if (table->in_use->abort_on_warning)
136
set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
138
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
140
return store(buff, length, charset());
143
/* If one of the fields is binary and the other one isn't return 1 else 0 */
145
bool Field_str::compare_str_field_flags(CreateField *new_field_ptr,
148
return (((new_field_ptr->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
149
!(flag_arg & (BINCMP_FLAG | BINARY_FLAG))) ||
150
(!(new_field_ptr->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
151
(flag_arg & (BINCMP_FLAG | BINARY_FLAG))));
155
uint32_t Field_str::is_equal(CreateField *new_field_ptr)
157
if (compare_str_field_flags(new_field_ptr, flags))
160
return ((new_field_ptr->sql_type == real_type()) &&
161
new_field_ptr->charset == field_charset &&
162
new_field_ptr->length == max_display_length());
166
bool check_string_copy_error(Field_str *field,
167
const char *well_formed_error_pos,
168
const char *cannot_convert_error_pos,
170
const CHARSET_INFO * const cs)
172
const char *pos, *end_orig;
175
if (!(pos= well_formed_error_pos) &&
176
!(pos= cannot_convert_error_pos))
180
set_if_smaller(end, pos + 6);
182
for (t= tmp; pos < end; pos++)
185
If the source string is ASCII compatible (mbminlen==1)
186
and the source character is in ASCII printable range (0x20..0x7F),
187
then display the character as is.
189
Otherwise, if the source string is not ASCII compatible (e.g. UCS2),
190
or the source character is not in the printable range,
191
then print the character using HEX notation.
193
if (((unsigned char) *pos) >= 0x20 &&
194
((unsigned char) *pos) <= 0x7F &&
203
*t++= _dig_vec_upper[((unsigned char) *pos) >> 4];
204
*t++= _dig_vec_upper[((unsigned char) *pos) & 15];
214
push_warning_printf(field->table->in_use,
215
field->table->in_use->abort_on_warning ?
216
DRIZZLE_ERROR::WARN_LEVEL_ERROR :
217
DRIZZLE_ERROR::WARN_LEVEL_WARN,
218
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
219
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
220
"string", tmp, field->field_name,
221
(uint32_t) field->table->in_use->row_count);
225
uint32_t Field_str::max_data_length() const
227
return field_length + (field_length > 255 ? 2 : 1);