Commit 9ff0c9f7 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-5858 MySQL Bug#12744991 - DECIMAL_ROUND(X,D) GIVES WRONG RESULTS WHEN D == N*(-9)

don't use mysql-5.6 change.
correct fix: zero-out rounded tail after the number was shifted because
of the carry digit (otherwise the carry digit will be zeroed out too).
parent 47f43867
...@@ -728,6 +728,21 @@ select (1.175494351E-37 div 1.7976931348623157E+308); ...@@ -728,6 +728,21 @@ select (1.175494351E-37 div 1.7976931348623157E+308);
Warnings: Warnings:
Warning 1916 Got overflow when converting '' to DECIMAL. Value truncated. Warning 1916 Got overflow when converting '' to DECIMAL. Value truncated.
# #
# Bug#12744991 - DECIMAL_ROUND(X,D) GIVES WRONG RESULTS WHEN D == N*(-9)
#
select round(999999999, -9);
round(999999999, -9)
1000000000
select round(999999999.0, -9);
round(999999999.0, -9)
1000000000
select round(999999999999999999, -18);
round(999999999999999999, -18)
1000000000000000000
select round(999999999999999999.0, -18);
round(999999999999999999.0, -18)
1000000000000000000
#
# Bug#12537160 ASSERTION FAILED: # Bug#12537160 ASSERTION FAILED:
# STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER. # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER.
# #
......
...@@ -538,6 +538,15 @@ SELECT 1 div null; ...@@ -538,6 +538,15 @@ SELECT 1 div null;
--echo # --echo #
select (1.175494351E-37 div 1.7976931348623157E+308); select (1.175494351E-37 div 1.7976931348623157E+308);
--echo #
--echo # Bug#12744991 - DECIMAL_ROUND(X,D) GIVES WRONG RESULTS WHEN D == N*(-9)
--echo #
select round(999999999, -9);
select round(999999999.0, -9);
select round(999999999999999999, -18);
select round(999999999999999999.0, -18);
--echo # --echo #
--echo # Bug#12537160 ASSERTION FAILED: --echo # Bug#12537160 ASSERTION FAILED:
--echo # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER. --echo # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER.
......
...@@ -1594,24 +1594,6 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1594,24 +1594,6 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
x+=10; x+=10;
*buf1=powers10[pos]*(x-y); *buf1=powers10[pos]*(x-y);
} }
/*
In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
the buffer are as follows.
Before <1, 5e8>
After <2, 5e8>
Hence we need to set the 2nd field to 0.
The same holds if we round 1.5e-9 to 2e-9.
*/
if (frac0 < frac1)
{
dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
dec1 *end= to->buf + len;
while (buf < end)
*buf++=0;
}
if (*buf1 >= DIG_BASE) if (*buf1 >= DIG_BASE)
{ {
carry=1; carry=1;
...@@ -1633,6 +1615,7 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1633,6 +1615,7 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
} }
*buf1=1; *buf1=1;
to->intg++; to->intg++;
intg0++;
} }
} }
else else
...@@ -1654,6 +1637,24 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1654,6 +1637,24 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
} }
} }
} }
/*
In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
the buffer are as follows.
Before <1, 5e8>
After <2, 5e8>
Hence we need to set the 2nd field to 0.
The same holds if we round 1.5e-9 to 2e-9.
*/
if (frac0 < frac1)
{
dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
dec1 *end= to->buf + len;
while (buf < end)
*buf++=0;
}
/* Here we check 999.9 -> 1000 case when we need to increase intg */ /* Here we check 999.9 -> 1000 case when we need to increase intg */
first_dig= to->intg % DIG_PER_DEC1; first_dig= to->intg % DIG_PER_DEC1;
......
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