Commit 863d5b4f authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23350 ROUND(bigint_22_or_longer) returns a wrong data type

The condition in Item_func_round::fix_arg_int() to decide whether:
- we can preserve the data type of args[0] versus
- the result can go outside of the args[0] data type
was wrong.

The data type of the first argument can be preserved in these cases:
- TRUNCATE(x, n)
- ROUND(x, n>=0)

Fixing the condition accordingly.
parent da78e952
This diff is collapsed.
......@@ -295,6 +295,7 @@ DROP TABLE t1;
--echo #
--echo # MDEV-23337 Rounding functions create a wrong data type for numeric input
--echo # MDEV-23350 ROUND(bigint_22_or_longer) returns a wrong data type
--echo #
DELIMITER $$;
......@@ -304,7 +305,7 @@ BEGIN
EXECUTE IMMEDIATE REPLACE('CREATE TABLE t1 (a TYPE)', 'TYPE', t);
INSERT IGNORE INTO t1 VALUES (-100000000000000000000000000000);
INSERT IGNORE INTO t1 VALUES (100000000000000000000000000000);
CREATE TABLE t2 AS SELECT a, ROUND(a), TRUNCATE(a,0), FLOOR(a), CEILING(a) FROM t1;
CREATE TABLE t2 AS SELECT a, ROUND(a), ROUND(a,1), ROUND(a,10), TRUNCATE(a,0), FLOOR(a), CEILING(a) FROM t1;
SHOW CREATE TABLE t2;
SELECT * FROM t2;
DROP TABLE t1, t2;
......@@ -318,12 +319,22 @@ CALL p1('smallint');
CALL p1('mediumint');
CALL p1('int');
CALL p1('bigint');
CALL p1('bigint(20)');
CALL p1('bigint(21)');
CALL p1('bigint(22)');
CALL p1('bigint(23)');
CALL p1('bigint(30)');
CALL p1('tinyint unsigned');
CALL p1('smallint unsigned');
CALL p1('mediumint unsigned');
CALL p1('int unsigned');
CALL p1('bigint unsigned');
CALL p1('bigint(20) unsigned');
CALL p1('bigint(21) unsigned');
CALL p1('bigint(22) unsigned');
CALL p1('bigint(23) unsigned');
CALL p1('bigint(30) unsigned');
--horizontal_results
DROP PROCEDURE p1;
......
......@@ -2472,7 +2472,8 @@ void Item_func_round::fix_arg_int(const Type_handler *preferred,
Longlong_hybrid val1= args[1]->to_longlong_hybrid();
if (args[1]->null_value)
fix_length_and_dec_double(NOT_FIXED_DEC);
else if ((!val1.to_uint(DECIMAL_MAX_SCALE) && truncate) ||
else if (truncate ||
!val1.neg() /* ROUND(x, n>=0) */ ||
args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)
{
// Here we can keep INT_RESULT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment