Commit d0cc7a52 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-15420 Wrong result for CAST from TIME or DATETIME with zero integer part...

MDEV-15420 Wrong result for CAST from TIME or DATETIME with zero integer part and non-zero microseconds to DECIMAL(X,Y)

The loop in ull2dec() does not iterate if "from" is zero,
so to->intg got erroneously set to 0 instead of 1.
Because if this, my_decimal2seconds() wrote the fractional
part into a wrong buf[x].

Catching the special case with zero "from" and properly initialize "to"
using decimal_make_zero().
parent e826d1e6
...@@ -1019,3 +1019,19 @@ cast('-0.0' as decimal(5,1)) < 0 ...@@ -1019,3 +1019,19 @@ cast('-0.0' as decimal(5,1)) < 0
# #
# End of 5.5 tests # End of 5.5 tests
# #
#
# Start of 10.2 tests
#
#
# MDEV-15420 Wrong result for CAST from TIME or DATETIME with zero integer part and non-zero microseconds to DECIMAL(X,Y)
#
SET sql_mode='';
SELECT
CAST(TIMESTAMP'0000-00-00 00:00:00.123456' AS DECIMAL(10,6)) AS c1,
CAST(TIME'00:00:00.123456' AS DECIMAL(10,6)) AS c2;
c1 c2
0.123456 0.123456
SET sql_mode=DEFAULT;
#
# End of 10.2 tests
#
...@@ -612,3 +612,21 @@ select cast('-0.0' as decimal(5,1)) < 0; ...@@ -612,3 +612,21 @@ select cast('-0.0' as decimal(5,1)) < 0;
--echo # --echo #
--echo # End of 5.5 tests --echo # End of 5.5 tests
--echo # --echo #
--echo #
--echo # Start of 10.2 tests
--echo #
--echo #
--echo # MDEV-15420 Wrong result for CAST from TIME or DATETIME with zero integer part and non-zero microseconds to DECIMAL(X,Y)
--echo #
SET sql_mode=''; # Allow zero date
SELECT
CAST(TIMESTAMP'0000-00-00 00:00:00.123456' AS DECIMAL(10,6)) AS c1,
CAST(TIME'00:00:00.123456' AS DECIMAL(10,6)) AS c2;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.2 tests
--echo #
...@@ -1000,6 +1000,12 @@ static int ull2dec(ulonglong from, decimal_t *to) ...@@ -1000,6 +1000,12 @@ static int ull2dec(ulonglong from, decimal_t *to)
sanity(to); sanity(to);
if (!from)
{
decimal_make_zero(to);
return E_DEC_OK;
}
for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {} for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {}
if (unlikely(intg1 > to->len)) if (unlikely(intg1 > to->len))
{ {
......
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