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/decimal.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027
00028 namespace drizzled
00029 {
00030
00031
00032
00033
00034
00035 Field_decimal::Field_decimal(unsigned char *ptr_arg,
00036 uint32_t len_arg,
00037 unsigned char *null_ptr_arg,
00038 unsigned char null_bit_arg,
00039 enum utype unireg_check_arg,
00040 const char *field_name_arg,
00041 uint8_t dec_arg) :
00042 Field_num(ptr_arg,
00043 len_arg,
00044 null_ptr_arg,
00045 null_bit_arg,
00046 unireg_check_arg,
00047 field_name_arg,
00048 dec_arg, false,
00049 false)
00050 {
00051 precision= class_decimal_length_to_precision(len_arg, dec_arg, false);
00052 set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
00053 assert((precision <= DECIMAL_MAX_PRECISION) && (dec <= DECIMAL_MAX_SCALE));
00054 bin_size= class_decimal_get_binary_size(precision, dec);
00055 }
00056
00057 Field_decimal::Field_decimal(uint32_t len_arg,
00058 bool maybe_null_arg,
00059 const char *name,
00060 uint8_t dec_arg,
00061 bool unsigned_arg) :
00062 Field_num((unsigned char*) 0,
00063 len_arg,
00064 maybe_null_arg ? (unsigned char*) "": 0,
00065 0,
00066 NONE,
00067 name,
00068 dec_arg,
00069 0,
00070 unsigned_arg)
00071 {
00072 precision= class_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
00073 set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
00074 assert((precision <= DECIMAL_MAX_PRECISION) &&
00075 (dec <= DECIMAL_MAX_SCALE));
00076 bin_size= class_decimal_get_binary_size(precision, dec);
00077 }
00078
00079
00080 int Field_decimal::reset(void)
00081 {
00082 store_value(&decimal_zero);
00083 return 0;
00084 }
00085
00086
00094 void Field_decimal::set_value_on_overflow(type::Decimal *decimal_value,
00095 bool sign)
00096 {
00097 max_Decimal(decimal_value, precision, decimals());
00098 if (sign)
00099 decimal_value->sign(true);
00100
00101 return;
00102 }
00103
00104
00120 bool Field_decimal::store_value(const type::Decimal *decimal_value)
00121 {
00122 int error= decimal_value->val_binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, ptr, precision, dec);
00123
00124 if (warn_if_overflow(error))
00125 {
00126 if (error != E_DEC_TRUNCATED)
00127 {
00128 type::Decimal buff;
00129 set_value_on_overflow(&buff, decimal_value->sign());
00130 buff.val_binary(E_DEC_FATAL_ERROR, ptr, precision, dec);
00131 }
00132 error= 1;
00133 }
00134
00135 return(error);
00136 }
00137
00138
00139 int Field_decimal::store(const char *from, uint32_t length,
00140 const CHARSET_INFO * const charset_arg)
00141 {
00142 int err;
00143 type::Decimal decimal_value;
00144
00145 ASSERT_COLUMN_MARKED_FOR_WRITE;
00146
00147 if ((err= decimal_value.store(E_DEC_FATAL_ERROR &
00148 ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
00149 from, length, charset_arg)) &&
00150 getTable()->in_use->abortOnWarning())
00151 {
00152
00153 String from_as_str;
00154 from_as_str.copy(from, length, &my_charset_bin);
00155
00156 push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00157 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00158 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00159 "decimal", from_as_str.c_ptr(), field_name,
00160 (uint32_t) getTable()->in_use->row_count);
00161
00162 return(err);
00163 }
00164
00165 switch (err) {
00166 case E_DEC_TRUNCATED:
00167 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00168 set_value_on_overflow(&decimal_value, decimal_value.sign());
00169 break;
00170 case E_DEC_OVERFLOW:
00171 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00172 set_value_on_overflow(&decimal_value, decimal_value.sign());
00173 break;
00174 case E_DEC_BAD_NUM:
00175 {
00176
00177 String from_as_str;
00178 from_as_str.copy(from, length, &my_charset_bin);
00179
00180 push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00181 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00182 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00183 "decimal", from_as_str.c_ptr(), field_name,
00184 (uint32_t) getTable()->in_use->row_count);
00185 decimal_value.set_zero();
00186
00187 break;
00188 }
00189 }
00190
00191 store_value(&decimal_value);
00192 return(err);
00193 }
00194
00195
00202 int Field_decimal::store(double nr)
00203 {
00204 type::Decimal decimal_value;
00205 int err;
00206
00207 ASSERT_COLUMN_MARKED_FOR_WRITE;
00208
00209 err= double2_class_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
00210 &decimal_value);
00211 if (err)
00212 {
00213 if (check_overflow(err))
00214 set_value_on_overflow(&decimal_value, decimal_value.sign());
00215
00216 getTable()->in_use->got_warning= 0;
00217 }
00218 if (store_value(&decimal_value))
00219 err= 1;
00220 else if (err && !getTable()->in_use->got_warning)
00221 err= warn_if_overflow(err);
00222 return(err);
00223 }
00224
00225
00226 int Field_decimal::store(int64_t nr, bool unsigned_val)
00227 {
00228 type::Decimal decimal_value;
00229 int err;
00230
00231 ASSERT_COLUMN_MARKED_FOR_WRITE;
00232
00233 if ((err= int2_class_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
00234 nr, unsigned_val, &decimal_value)))
00235 {
00236 if (check_overflow(err))
00237 set_value_on_overflow(&decimal_value, decimal_value.sign());
00238
00239 getTable()->in_use->got_warning= 0;
00240 }
00241 if (store_value(&decimal_value))
00242 err= 1;
00243 else if (err && not getTable()->in_use->got_warning)
00244 err= warn_if_overflow(err);
00245 return err;
00246 }
00247
00248
00249 int Field_decimal::store_decimal(const type::Decimal *decimal_value)
00250 {
00251 return store_value(decimal_value);
00252 }
00253
00254
00255 int Field_decimal::store_time(type::Time <ime,
00256 type::timestamp_t )
00257 {
00258 type::Decimal decimal_value;
00259 return store_value(date2_class_decimal(<ime, &decimal_value));
00260 }
00261
00262
00263 double Field_decimal::val_real(void) const
00264 {
00265 double dbl;
00266 type::Decimal decimal_value;
00267
00268 ASSERT_COLUMN_MARKED_FOR_READ;
00269
00270 class_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
00271
00272 return dbl;
00273 }
00274
00275
00276 int64_t Field_decimal::val_int(void) const
00277 {
00278 int64_t i;
00279 type::Decimal decimal_value;
00280
00281 ASSERT_COLUMN_MARKED_FOR_READ;
00282
00283 val_decimal(&decimal_value)->val_int32(E_DEC_FATAL_ERROR, false, &i);
00284
00285 return i;
00286 }
00287
00288
00289 type::Decimal* Field_decimal::val_decimal(type::Decimal *decimal_value) const
00290 {
00291 ASSERT_COLUMN_MARKED_FOR_READ;
00292
00293 binary2_class_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
00294 precision, dec);
00295 return(decimal_value);
00296 }
00297
00298
00299 String *Field_decimal::val_str(String *val_buffer, String *) const
00300 {
00301 type::Decimal decimal_value;
00302
00303 ASSERT_COLUMN_MARKED_FOR_READ;
00304
00305 class_decimal2string(val_decimal(&decimal_value),
00306 dec, val_buffer);
00307 return val_buffer;
00308 }
00309
00310
00311 int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
00312 {
00313 return memcmp(a, b, bin_size);
00314 }
00315
00316
00317 void Field_decimal::sort_string(unsigned char *buff,
00318 uint32_t )
00319 {
00320 memcpy(buff, ptr, bin_size);
00321 }
00322
00323
00324 void Field_decimal::sql_type(String &str) const
00325 {
00326 const CHARSET_INFO * const cs= str.charset();
00327 str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
00328 "decimal(%d,%d)", precision, (int)dec));
00329 }
00330
00331
00344 uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
00345 {
00346 uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
00347 uint32_t const source_decimal= field_metadata & 0x00ff;
00348 uint32_t const source_size= class_decimal_get_binary_size(source_precision,
00349 source_decimal);
00350 return (source_size);
00351 }
00352
00353
00354 uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
00355 {
00356 return ((new_field_ptr->sql_type == real_type()) &&
00357 ((new_field_ptr->flags & UNSIGNED_FLAG) ==
00358 (uint32_t) (flags & UNSIGNED_FLAG)) &&
00359 ((new_field_ptr->flags & AUTO_INCREMENT_FLAG) ==
00360 (uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
00361 (new_field_ptr->length == max_display_length()) &&
00362 (new_field_ptr->decimals == dec));
00363 }
00364
00365
00378 const unsigned char *
00379 Field_decimal::unpack(unsigned char* to,
00380 const unsigned char *from,
00381 uint32_t param_data,
00382 bool low_byte_first)
00383 {
00384 if (param_data == 0)
00385 return Field::unpack(to, from, param_data, low_byte_first);
00386
00387 uint32_t from_precision= (param_data & 0xff00) >> 8U;
00388 uint32_t from_decimal= param_data & 0x00ff;
00389 uint32_t length=pack_length();
00390 uint32_t from_pack_len= class_decimal_get_binary_size(from_precision, from_decimal);
00391 uint32_t len= (param_data && (from_pack_len < length)) ?
00392 from_pack_len : length;
00393 if ((from_pack_len && (from_pack_len < length)) ||
00394 (from_precision < precision) ||
00395 (from_decimal < decimals()))
00396 {
00397
00398
00399
00400
00401
00402 decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
00403 decimal_t conv_dec;
00404 conv_dec.len= from_precision;
00405 conv_dec.buf= dec_buf;
00406
00407
00408
00409
00410
00411 bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
00412 decimal2bin(&conv_dec, to, precision, decimals());
00413 }
00414 else
00415 memcpy(to, from, len);
00416 return from+len;
00417 }
00418
00419 }