diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 4a1722f4045..991afcbdef0 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -525,6 +525,27 @@ Level Code Message Warning 1292 Truncated incorrect DECIMAL value: '123456789012345678901234567890' Error 1690 BIGINT value is out of range in '('123456789012345678901234567890.123456789012345678901234567890' DIV 1)' # +# Bug #96459 Type resolution of DIV operator produces one less precision +# Notice here uses decimal plus to reveal the precision problem, +# so should any fix to plus changes the outcomes, feel free to fix these tests as well. +# +CREATE TABLE t1 SELECT +5.0 + 96 DIV 1, # Dividend is integer +5.0 + 96.1234 DIV 1, # Dividend is decimal +5.0 + "96" DIV 1, # Dividend is string +5.0 + CAST("96" AS SIGNED) DIV 1, # Dividend is function +5.0 + CAST("96" AS UNSIGNED) DIV 1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `5.0 + 96 DIV 1` decimal(4,1) DEFAULT NULL, + `5.0 + 96.1234 DIV 1` decimal(4,1) DEFAULT NULL, + `5.0 + "96" DIV 1` decimal(4,1) DEFAULT NULL, + `5.0 + CAST("96" AS SIGNED) DIV 1` decimal(4,1) DEFAULT NULL, + `5.0 + CAST("96" AS UNSIGNED) DIV 1` decimal(4,1) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci +DROP TABLE t1; +# # Bug#57810 case/when/then : Assertion failed: length || !scale # SELECT CASE(('')) WHEN (CONVERT(1, CHAR(1))) THEN (('' / 1)) END; diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 5d03c5f9066..44c83e862e7 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -339,6 +339,20 @@ select 123456789012345678901234567890.123456789012345678901234567890 div 1 as x; select "123456789012345678901234567890.123456789012345678901234567890" div 1 as x; SHOW WARNINGS; +-- echo # +-- echo # Bug #96459 Type resolution of DIV operator produces one less precision +-- echo # Notice here uses decimal plus to reveal the precision problem, +-- echo # so should any fix to plus changes the outcomes, feel free to fix these tests as well. +-- echo # +CREATE TABLE t1 SELECT + 5.0 + 96 DIV 1, # Dividend is integer + 5.0 + 96.1234 DIV 1, # Dividend is decimal + 5.0 + "96" DIV 1, # Dividend is string + 5.0 + CAST("96" AS SIGNED) DIV 1, # Dividend is function + 5.0 + CAST("96" AS UNSIGNED) DIV 1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + --echo # --echo # Bug#57810 case/when/then : Assertion failed: length || !scale --echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index 06785220a39..ffccf4399fe 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1947,6 +1947,15 @@ bool Item_func_int_div::resolve_type(THD *) { return reject_geometry_args(arg_count, args, this); } +uint Item_func_int_div::decimal_precision() const { + Item_result argtype = args[0]->result_type(); + uint precision = + args[0]->decimal_precision() - + (argtype == DECIMAL_RESULT || argtype == INT_RESULT ? args[0]->decimals + : 0); + return precision; +} + longlong Item_func_mod::int_op() { DBUG_ASSERT(fixed == 1); longlong val0 = args[0]->val_int(); diff --git a/sql/item_func.h b/sql/item_func.h index ffe42560db4..0f59a3bf109 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1044,6 +1044,7 @@ class Item_func_int_div final : public Item_int_func { longlong val_int() override; const char *func_name() const override { return "DIV"; } bool resolve_type(THD *thd) override; + uint decimal_precision() const override; void print(const THD *thd, String *str, enum_query_type query_type) const override {