summaryrefslogtreecommitdiff
path: root/sql/item_func.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-08-03 13:56:10 +0400
committerAlexander Barkov <bar@mariadb.com>2020-08-04 08:09:08 +0400
commit6a2ee9c8bbec437e7eb50b1a273a017cdefc6e15 (patch)
tree4e8fa89371f463521d61dc3fe33d9a6989a0039e /sql/item_func.h
parent706a7101bfacd29f4f5728034be92240e82df583 (diff)
downloadmariadb-git-6a2ee9c8bbec437e7eb50b1a273a017cdefc6e15.tar.gz
MDEV-23032 FLOOR()/CEIL() incorrectly calculate the precision of a DECIMAL(M,D) column
The code in Item_func_int_val::fix_length_and_dec_int_or_decimal() calculated badly the result data type for FLOOR()/CEIL(), so for example the decimal(38,10) input created a decimal(28,0) result. That was not correct, because one extra integer digit is needed. floor(-9.9) -> -10 ceil(9.9) -> 10 Rewritting the code in a more straightforward way. Additional changes: - FLOOR() now takes into account the presence of the UNSIGNED flag of the argument: FLOOR(unsigned decimal) does not need an extra digits. - FLOOR()/CEILING() now preserve the unsigned flag in the result data type is decimal. These changes give nicer data types.
Diffstat (limited to 'sql/item_func.h')
-rw-r--r--sql/item_func.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/sql/item_func.h b/sql/item_func.h
index 24601983f86..d1292c3e07a 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1695,6 +1695,7 @@ public:
Item_func_int_val(THD *thd, Item *a): Item_func_hybrid_field_type(thd, a) {}
bool check_partition_func_processor(void *int_arg) { return FALSE; }
bool check_vcol_func_processor(void *arg) { return FALSE; }
+ virtual decimal_round_mode round_mode() const= 0;
void fix_length_and_dec_double();
void fix_length_and_dec_int_or_decimal();
void fix_length_and_dec_time()
@@ -1723,6 +1724,7 @@ class Item_func_ceiling :public Item_func_int_val
public:
Item_func_ceiling(THD *thd, Item *a): Item_func_int_val(thd, a) {}
const char *func_name() const { return "ceiling"; }
+ decimal_round_mode round_mode() const { return CEILING; }
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
@@ -1738,6 +1740,7 @@ class Item_func_floor :public Item_func_int_val
public:
Item_func_floor(THD *thd, Item *a): Item_func_int_val(thd, a) {}
const char *func_name() const { return "floor"; }
+ decimal_round_mode round_mode() const { return FLOOR; }
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);