18 #include <drizzled/sql_string.h>
20 #include <drizzled/type/time.h>
32 typedef int32_t decimal_digit_t;
40 inline void set_zero()
61 int fixed_precision,
int fixed_decimals,
63 int decimal2uint64_t(
const decimal_t *from, uint64_t *to);
64 int uint64_t2decimal(
const uint64_t from,
decimal_t *to);
65 int decimal2int64_t(
const decimal_t *from, int64_t *to);
66 int int64_t2decimal(
const int64_t from,
decimal_t *to);
84 decimal_round_mode mode);
87 inline int string2decimal(
char *from,
decimal_t *to,
char **end)
97 inline int decimal_string_size(
const decimal_t *dec)
99 return (dec->intg ? dec->intg : 1) + dec->frac + (dec->frac > 0) + 2;
113 #define E_DEC_TRUNCATED 1
114 #define E_DEC_OVERFLOW 2
115 #define E_DEC_DIV_ZERO 4
116 #define E_DEC_BAD_NUM 8
119 #define E_DEC_ERROR 31
120 #define E_DEC_FATAL_ERROR 30
123 #define DECIMAL_LONGLONG_DIGITS 22
126 #define DECIMAL_BUFF_LENGTH 9
129 #define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
138 #define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
139 #define DECIMAL_MAX_SCALE 30
140 #define DECIMAL_NOT_SPECIFIED 31
146 #define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
148 inline int class_decimal_int_part(uint32_t precision, uint32_t decimals)
150 return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
155 inline void max_Decimal(type::Decimal *to,
int precision,
int frac)
157 assert((precision <= DECIMAL_MAX_PRECISION)&&
158 (frac <= DECIMAL_MAX_SCALE));
162 inline void max_internal_decimal(type::Decimal *to)
164 max_Decimal(to, DECIMAL_MAX_PRECISION, 0);
167 inline int check_result(uint32_t mask,
int result)
185 decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
191 len= DECIMAL_BUFF_LENGTH;
193 #if !defined (HAVE_VALGRIND)
195 for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
205 void fix_buffer_pointer() { buf= buffer; }
206 bool sign()
const {
return decimal_t::sign; }
207 void sign(
bool s) { decimal_t::sign= s; }
208 uint32_t precision()
const {
return intg + frac; }
210 int val_int32(uint32_t mask,
bool unsigned_flag, int64_t *l)
const
214 decimal_round(static_cast<const decimal_t*>(
this), &rounded, 0, HALF_UP);
215 return check_result(mask, (unsigned_flag ?
216 decimal2uint64_t(&rounded, reinterpret_cast<uint64_t *>(l)) :
217 decimal2int64_t(&rounded, l)));
220 int string_length()
const
222 return decimal_string_size(
this);
225 int val_binary(uint32_t mask,
unsigned char *bin,
int prec,
int scale)
const;
229 int store(uint32_t mask,
char *str,
char **end)
231 return check_result_and_overflow(mask, string2decimal(str, static_cast<decimal_t*>(
this), end));
236 return store(mask, str->ptr(), str->length(), str->charset());
239 int check_result_and_overflow(uint32_t mask,
int result)
241 if (check_result(mask, result) & E_DEC_OVERFLOW)
244 fix_buffer_pointer();
245 max_internal_decimal(
this);
251 void convert(
double &value)
const;
256 std::ostream& operator<<(std::ostream& output,
const type::Decimal &dec);
258 inline uint32_t class_decimal_length_to_precision(uint32_t length, uint32_t scale,
261 return (uint32_t) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
264 inline uint32_t class_decimal_precision_to_length(uint32_t precision, uint8_t scale,
267 set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
268 return static_cast<uint32_t
>(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
273 int class_decimal_max_length(
const type::Decimal *d)
276 return decimal_string_size(d) - 1;
281 int class_decimal_get_binary_size(uint32_t precision, uint32_t scale)
283 return decimal_bin_size(static_cast<int>(precision), static_cast<int>(scale));
288 void class_decimal2decimal(
const type::Decimal *from, type::Decimal *to)
291 to->fix_buffer_pointer();
296 int binary2_class_decimal(uint32_t mask,
const unsigned char *bin, type::Decimal *d,
int prec,
299 return check_result(mask,
bin2decimal(bin, static_cast<decimal_t*>(d), prec, scale));
304 int class_decimal_round(uint32_t mask,
const type::Decimal *from,
int scale,
305 bool truncate, type::Decimal *to)
307 return check_result(mask,
decimal_round(static_cast<const decimal_t*>(from), to, scale,
308 (truncate ? TRUNCATE : HALF_UP)));
313 int class_decimal_floor(uint32_t mask,
const type::Decimal *from, type::Decimal *to)
315 return check_result(mask,
decimal_round(static_cast<const decimal_t*>(from), to, 0, FLOOR));
320 int class_decimal_ceiling(uint32_t mask,
const type::Decimal *from, type::Decimal *to)
322 return check_result(mask,
decimal_round(static_cast<const decimal_t*>(from), to, 0, CEILING));
327 uint32_t fixed_dec, String *str);
331 int class_decimal2double(uint32_t,
const type::Decimal *d,
double *result)
338 type::Decimal *date2_class_decimal(type::Time *ltime, type::Decimal *dec);
342 int double2_class_decimal(uint32_t mask,
double val, type::Decimal *d)
344 return d->check_result_and_overflow(mask,
double2decimal(val, static_cast<decimal_t*>(d)));
349 int int2_class_decimal(uint32_t mask, int64_t i,
bool unsigned_flag, type::Decimal *d)
351 return check_result(mask, (unsigned_flag ?
352 uint64_t2decimal(static_cast<uint64_t>(i), d) :
353 int64_t2decimal(i, d)));
358 void class_decimal_neg(decimal_t *arg)
370 int class_decimal_add(uint32_t mask, type::Decimal *res,
const type::Decimal *a,
371 const type::Decimal *b)
373 return res->check_result_and_overflow(mask,
374 decimal_add(static_cast<const decimal_t*>(a),
375 static_cast<const decimal_t*>(b), res));
380 int class_decimal_sub(uint32_t mask, type::Decimal *res,
const type::Decimal *a,
381 const type::Decimal *b)
383 return res->check_result_and_overflow(mask,
384 decimal_sub(static_cast<const decimal_t*>(a),
385 static_cast<const decimal_t*>(b), res));
390 int class_decimal_mul(uint32_t mask, type::Decimal *res,
const type::Decimal *a,
391 const type::Decimal *b)
393 return res->check_result_and_overflow(mask,
395 static_cast<const decimal_t*>(b),res));
400 int class_decimal_div(uint32_t mask, type::Decimal *res,
const type::Decimal *a,
401 const type::Decimal *b,
int div_scale_inc)
403 return res->check_result_and_overflow(mask,
405 static_cast<const decimal_t*>(b),res,
411 int class_decimal_mod(uint32_t mask, type::Decimal *res,
const type::Decimal *a,
412 const type::Decimal *b)
414 return res->check_result_and_overflow(mask,
416 static_cast<const decimal_t*>(b),res));
427 return decimal_cmp(static_cast<const decimal_t*>(a),
428 static_cast<const decimal_t*>(b));
433 int class_decimal_intg(
const type::Decimal *a)
435 return decimal_intg(static_cast<const decimal_t*>(a));
439 void class_decimal_trim(uint32_t *precision, uint32_t *scale);
441 inline type::Decimal &decimal_zero_const()
443 static type::Decimal _decimal_zero;
444 return _decimal_zero;
447 double my_double_round(
double value, int64_t dec,
bool dec_unsigned,
451 #define decimal_zero decimal_zero_const()
int decimal_round(const decimal_t *from, decimal_t *to, int scale, decimal_round_mode mode)
Rounds the decimal to "scale" digits.
int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
division of two decimals
int class_decimal_cmp(const type::Decimal *a, const type::Decimal *b)
void max_decimal(int precision, int frac, decimal_t *to)
Get maximum value for given precision and scale.
int store(uint32_t mask, const char *from, uint32_t length, const charset_info_st *charset)
Convert string for decimal when string can be in some multibyte charset.
int internal_str2dec(char *from, decimal_t *to, char **end, bool fixed)
Convert string to decimal.
int decimal2bin(const decimal_t *from, unsigned char *to, int precision, int frac)
Convert decimal to its binary fixed-length representation (suitable for comparing with memcmp) ...
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
modulus
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
multiply two decimals
int decimal_actual_fraction(decimal_t *from)
Count actual length of fraction part (without ending zeroes)
int class_decimal2string(const type::Decimal *d, uint32_t fixed_dec, String *str)
Converting decimal to string.
int decimal_operation_results(int result)
int double2decimal(const double from, decimal_t *to)
int bin2decimal(const unsigned char *from, decimal_t *to, int precision, int scale)
Restores decimal from its binary fixed-length representation.
int decimal_bin_size(int precision, int scale)
Returns the size of array to hold a binary representation of a decimal.
int decimal2double(const decimal_t *from, double *to)
int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals, char filler)
Convert decimal to its printable string representation.