1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-16910 Add class VDec

Adding classes VDec and VDec2_lazy, according to the task description.
This patch removes around 250 duplicate code lines.
This commit is contained in:
Alexander Barkov
2018-08-07 10:48:42 +04:00
parent 01e4426a63
commit cb7b5fbf1c
26 changed files with 595 additions and 847 deletions

View File

@ -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);