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/str.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/internal/m_string.h>
00028
00029 namespace drizzled {
00030
00031 namespace internal
00032 {
00033 extern char _dig_vec_upper[];
00034 }
00035
00036 Field_str::Field_str(unsigned char *ptr_arg,
00037 uint32_t len_arg,
00038 unsigned char *null_ptr_arg,
00039 unsigned char null_bit_arg,
00040 const char *field_name_arg,
00041 const charset_info_st * const charset_arg)
00042 :Field(ptr_arg, len_arg,
00043 null_ptr_arg,
00044 null_bit_arg,
00045 Field::NONE,
00046 field_name_arg)
00047 {
00048 field_charset= charset_arg;
00049 if (charset_arg->state & MY_CS_BINSORT)
00050 flags|= BINARY_FLAG;
00051 field_derivation= DERIVATION_IMPLICIT;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 int Field_str::report_if_important_data(const char *field_ptr, const char *end)
00073 {
00074 if (field_ptr < end && getTable()->in_use->count_cuted_fields)
00075 {
00076 set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
00077 return 2;
00078 }
00079 return 0;
00080 }
00081
00102 int Field_str::store_decimal(const type::Decimal *d)
00103 {
00104 char buff[DECIMAL_MAX_STR_LENGTH+1];
00105 String str(buff, sizeof(buff), &my_charset_bin);
00106 class_decimal2string(d, 0, &str);
00107 return store(str.ptr(), str.length(), str.charset());
00108 }
00109
00110 type::Decimal *Field_str::val_decimal(type::Decimal *decimal_value) const
00111 {
00112 int2_class_decimal(E_DEC_FATAL_ERROR, val_int(), 0, decimal_value);
00113 return decimal_value;
00114 }
00115
00124 int Field_str::store(double nr)
00125 {
00126 char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
00127 uint32_t local_char_length= field_length / charset()->mbmaxlen;
00128 bool error;
00129
00130 ASSERT_COLUMN_MARKED_FOR_WRITE;
00131
00132 size_t length= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error);
00133 if (error)
00134 {
00135 if (getTable()->getSession()->abortOnWarning())
00136 {
00137 set_warning(DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
00138 }
00139 else
00140 {
00141 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00142 }
00143 }
00144 return store(buff, length, charset());
00145 }
00146
00147
00148 bool check_string_copy_error(Field_str *field,
00149 const char *well_formed_error_pos,
00150 const char *cannot_convert_error_pos,
00151 const char *end,
00152 const charset_info_st * const cs)
00153 {
00154 const char* pos= well_formed_error_pos;
00155 if (not pos && not (pos= cannot_convert_error_pos))
00156 return false;
00157
00158 const char* end_orig= end;
00159 set_if_smaller(end, pos + 6);
00160
00161 char tmp[64];
00162 char* t= tmp;
00163 for (; pos < end; pos++)
00164 {
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 if (((unsigned char) *pos) >= 0x20 && ((unsigned char) *pos) <= 0x7F && cs->mbminlen == 1)
00175 {
00176 *t++= *pos;
00177 }
00178 else
00179 {
00180 *t++= '\\';
00181 *t++= 'x';
00182 *t++= internal::_dig_vec_upper[((unsigned char) *pos) >> 4];
00183 *t++= internal::_dig_vec_upper[((unsigned char) *pos) & 15];
00184 }
00185 }
00186 if (end_orig > end)
00187 {
00188 *t++= '.';
00189 *t++= '.';
00190 *t++= '.';
00191 }
00192 *t= '\0';
00193 push_warning_printf(field->getTable()->in_use,
00194 field->getTable()->in_use->abortOnWarning() ? DRIZZLE_ERROR::WARN_LEVEL_ERROR : DRIZZLE_ERROR::WARN_LEVEL_WARN,
00195 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00196 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00197 "string", tmp, field->field_name,
00198 (uint32_t) field->getTable()->in_use->row_count);
00199 return true;
00200 }
00201
00202 uint32_t Field_str::max_data_length() const
00203 {
00204 return field_length + (field_length > 255 ? 2 : 1);
00205 }
00206
00207 }