summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2018-02-25 23:59:01 +0400
committerAlexander Barkov <bar@mariadb.org>2018-02-25 23:59:01 +0400
commitd0cc7a52255fd39dda8b73828e26d3541e0b0c64 (patch)
tree690678affe368bb7068767d4863f9bc165f2ba8c
parente826d1e64d4c03f2365763f64c180b67ed95bb53 (diff)
downloadmariadb-git-d0cc7a52255fd39dda8b73828e26d3541e0b0c64.tar.gz
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().
-rw-r--r--mysql-test/r/type_decimal.result16
-rw-r--r--mysql-test/t/type_decimal.test18
-rw-r--r--strings/decimal.c6
3 files changed, 40 insertions, 0 deletions
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 0ead4ec9aa2..d5232ff92a8 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -1019,3 +1019,19 @@ cast('-0.0' as decimal(5,1)) < 0
#
# 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
+#
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 777bb2f23e5..e8b3ecbf0a9 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -612,3 +612,21 @@ select cast('-0.0' as decimal(5,1)) < 0;
--echo #
--echo # End of 5.5 tests
--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 #
diff --git a/strings/decimal.c b/strings/decimal.c
index 7db5111fc84..029a85b3202 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1000,6 +1000,12 @@ static int ull2dec(ulonglong from, decimal_t *to)
sanity(to);
+ if (!from)
+ {
+ decimal_make_zero(to);
+ return E_DEC_OK;
+ }
+
for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {}
if (unlikely(intg1 > to->len))
{