diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-08-07 10:48:42 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-08-07 10:48:42 +0400 |
commit | cb7b5fbf1cf7c5bcd0509e428a53a8b8d6fbba0f (patch) | |
tree | 97a2de6b50c55fdecbaacbde75775196ff347421 /sql/my_decimal.h | |
parent | 01e4426a6352740973ff275eac60ddacc90da119 (diff) | |
download | mariadb-git-cb7b5fbf1cf7c5bcd0509e428a53a8b8d6fbba0f.tar.gz |
MDEV-16910 Add class VDec
Adding classes VDec and VDec2_lazy, according to the task description.
This patch removes around 250 duplicate code lines.
Diffstat (limited to 'sql/my_decimal.h')
-rw-r--r-- | sql/my_decimal.h | 134 |
1 files changed, 79 insertions, 55 deletions
diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 22800c24338..d035641cfa6 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -39,6 +39,7 @@ C_MODE_START C_MODE_END class String; +class Field; typedef struct st_mysql_time MYSQL_TIME; /** @@ -63,6 +64,25 @@ inline int my_decimal_int_part(uint precision, uint decimals) } +#ifndef MYSQL_CLIENT +int decimal_operation_results(int result, const char *value, const char *type); +#else +inline int decimal_operation_results(int result, const char *value, + const char *type) +{ + return result; +} +#endif /*MYSQL_CLIENT*/ + + +inline int check_result(uint mask, int result) +{ + if (result & mask) + decimal_operation_results(result, "", "DECIMAL"); + return result; +} + + /** my_decimal class limits 'decimal_t' type to what we need in MySQL. @@ -125,6 +145,12 @@ public: { init(); } + my_decimal(const uchar *bin, int prec, int scale) + { + init(); + check_result(E_DEC_FATAL_ERROR, bin2decimal(bin, this, prec, scale)); + } + my_decimal(Field *field); ~my_decimal() { sanity_check(); @@ -141,7 +167,59 @@ public: bool sign() const { return decimal_t::sign; } void sign(bool s) { decimal_t::sign= s; } uint precision() const { return intg + frac; } + void set_zero() + { + /* + We need the up-cast here, since my_decimal has sign() member functions, + which conflicts with decimal_t::sign + (and decimal_make_zero is a macro, rather than a funcion). + */ + decimal_make_zero(static_cast<decimal_t*>(this)); + } + int cmp(const my_decimal *other) const + { + return decimal_cmp(this, other); + } +#ifndef MYSQL_CLIENT + bool to_bool() const + { + return !decimal_is_zero(this); + } + double to_double() const + { + double res; + decimal2double(this, &res); + return res; + } + longlong to_longlong(bool unsigned_flag) const; + // Convert to string returning decimal2string() error code + int to_string_native(String *to, uint prec, uint dec, char filler, + uint mask= E_DEC_FATAL_ERROR) const; + // Convert to string returning the String pointer + String *to_string(String *to, uint prec, uint dec, char filler) const + { + return to_string_native(to, prec, dec, filler) ? NULL : to; + } + String *to_string(String *to) const + { + return to_string(to, 0, 0, 0); + } + String *to_string_round(String *to, uint scale, my_decimal *round_buff) const + { + (void) round_to(round_buff, scale, HALF_UP); // QQ: check result? + return round_buff->to_string(to); + } + int round_to(my_decimal *to, uint scale, decimal_round_mode mode, + int mask= E_DEC_FATAL_ERROR) const + { + return check_result(mask, decimal_round(this, to, (int) scale, mode)); + } + bool to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate, + const char *field_name); + int to_binary(uchar *bin, int prec, int scale, + uint mask= E_DEC_FATAL_ERROR) const; +#endif /** Swap two my_decimal values */ void swap(my_decimal &rhs) { @@ -164,16 +242,6 @@ bool str_set_decimal(uint mask, const my_decimal *val, uint fixed_prec, extern my_decimal decimal_zero; -#ifndef MYSQL_CLIENT -int decimal_operation_results(int result, const char *value, const char *type); -#else -inline int decimal_operation_results(int result, const char *value, - const char *type) -{ - return result; -} -#endif /*MYSQL_CLIENT*/ - inline void max_my_decimal(my_decimal *to, int precision, int frac) { @@ -187,13 +255,6 @@ inline void max_internal_decimal(my_decimal *to) max_my_decimal(to, DECIMAL_MAX_PRECISION, 0); } -inline int check_result(uint mask, int result) -{ - if (result & mask) - decimal_operation_results(result, "", "DECIMAL"); - return result; -} - inline int check_result_and_overflow(uint mask, int result, my_decimal *val) { if (check_result(mask, result) & E_DEC_OVERFLOW) @@ -271,10 +332,6 @@ void my_decimal2decimal(const my_decimal *from, my_decimal *to) } -int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec, - int scale); - - inline int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec, int scale) @@ -286,12 +343,7 @@ int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec, inline int my_decimal_set_zero(my_decimal *d) { - /* - We need the up-cast here, since my_decimal has sign() member functions, - which conflicts with decimal_t::sign - (and decimal_make_zero is a macro, rather than a funcion). - */ - decimal_make_zero(static_cast<decimal_t*>(d)); + d->set_zero(); return 0; } @@ -303,40 +355,12 @@ bool my_decimal_is_zero(const my_decimal *decimal_value) } -inline -int my_decimal_round(uint mask, const my_decimal *from, int scale, - bool truncate, my_decimal *to) -{ - return check_result(mask, decimal_round(from, to, scale, - (truncate ? TRUNCATE : HALF_UP))); -} - - -inline -int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to) -{ - return check_result(mask, decimal_round(from, to, 0, FLOOR)); -} - - -inline -int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to) -{ - return check_result(mask, decimal_round(from, to, 0, CEILING)); -} - - inline bool str_set_decimal(const my_decimal *val, String *str, CHARSET_INFO *cs) { return str_set_decimal(E_DEC_FATAL_ERROR, val, 0, 0, 0, str, cs); } -#ifndef MYSQL_CLIENT -class String; -int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec, - uint fixed_dec, char filler, String *str); -#endif bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec); |