summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_date_add.result51
-rw-r--r--mysql-test/t/func_date_add.test37
-rw-r--r--sql/item_timefunc.cc14
3 files changed, 98 insertions, 4 deletions
diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result
index e8fbba786a4..0258267b5ec 100644
--- a/mysql-test/r/func_date_add.result
+++ b/mysql-test/r/func_date_add.result
@@ -102,3 +102,54 @@ select * from t1 where case a when adddate( '2012-12-12', 7 ) then true end;
a
drop table t1;
End of 5.5 tests
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong?
+#
+SELECT
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5' DAY_MICROSECOND) c1,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50' DAY_MICROSECOND) c2,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500' DAY_MICROSECOND) c3,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000' DAY_MICROSECOND) c4,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000' DAY_MICROSECOND) c5,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000' DAY_MICROSECOND) c6,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000' DAY_MICROSECOND) c7,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000' DAY_MICROSECOND) c8,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000' DAY_MICROSECOND) c9,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000' DAY_MICROSECOND) c10,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000' DAY_MICROSECOND) c11,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000' DAY_MICROSECOND) c12,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000' DAY_MICROSECOND) c13,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000' DAY_MICROSECOND) c14,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000' DAY_MICROSECOND) c15,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000' DAY_MICROSECOND) c16,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000' DAY_MICROSECOND) c17,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000000' DAY_MICROSECOND) c18,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000000' DAY_MICROSECOND) c19,
+DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000000' DAY_MICROSECOND) c20
+;
+c1 1000-01-01 00:00:01.500000
+c2 1000-01-01 00:00:01.500000
+c3 1000-01-01 00:00:01.500000
+c4 1000-01-01 00:00:01.500000
+c5 1000-01-01 00:00:01.500000
+c6 1000-01-01 00:00:01.500000
+c7 1000-01-01 00:00:01.500000
+c8 1000-01-01 00:00:01.500000
+c9 1000-01-01 00:00:01.500000
+c10 1000-01-01 00:00:01.500000
+c11 1000-01-01 00:00:01.500000
+c12 1000-01-01 00:00:01.500000
+c13 1000-01-01 00:00:01.500000
+c14 1000-01-01 00:00:01.500000
+c15 1000-01-01 00:00:01.500000
+c16 1000-01-01 00:00:01.500000
+c17 1000-01-01 00:00:01.500000
+c18 1000-01-01 00:00:01.500000
+c19 1000-01-01 00:00:01.500000
+c20 NULL
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test
index 5f27978347c..e7e2b96f0eb 100644
--- a/mysql-test/t/func_date_add.test
+++ b/mysql-test/t/func_date_add.test
@@ -100,3 +100,40 @@ drop table t1;
--echo End of 5.5 tests
+--echo #
+--echo # Start of 10.1 tests
+--echo #
+
+--echo #
+--echo # MDEV-14452 Precision in INTERVAL xxx DAY_MICROSECOND parsed wrong?
+--echo #
+
+--vertical_results
+SELECT
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5' DAY_MICROSECOND) c1,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50' DAY_MICROSECOND) c2,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500' DAY_MICROSECOND) c3,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000' DAY_MICROSECOND) c4,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000' DAY_MICROSECOND) c5,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000' DAY_MICROSECOND) c6,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000' DAY_MICROSECOND) c7,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000' DAY_MICROSECOND) c8,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000' DAY_MICROSECOND) c9,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000' DAY_MICROSECOND) c10,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000' DAY_MICROSECOND) c11,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000' DAY_MICROSECOND) c12,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000' DAY_MICROSECOND) c13,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000' DAY_MICROSECOND) c14,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000' DAY_MICROSECOND) c15,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000' DAY_MICROSECOND) c16,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000' DAY_MICROSECOND) c17,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.500000000000000000' DAY_MICROSECOND) c18,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.5000000000000000000' DAY_MICROSECOND) c19,
+ DATE_ADD('1000-01-01 00:00:00', INTERVAL '0 00:00:01.50000000000000000000' DAY_MICROSECOND) c20
+;
+--horizontal_results
+
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 4a94c3a5f89..d7506026c62 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -702,7 +702,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
{
const char *end=str+length;
uint i;
- long msec_length= 0;
+ long field_length= 0;
while (str != end && !my_isdigit(cs,*str))
str++;
@@ -713,7 +713,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
const char *start= str;
for (value= 0; str != end && my_isdigit(cs, *str); str++)
value= value*10 + *str - '0';
- msec_length= 6 - (str - start);
+ if ((field_length= str - start) >= 20)
+ return true;
values[i]= value;
while (str != end && !my_isdigit(cs,*str))
str++;
@@ -728,8 +729,13 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
}
}
- if (transform_msec && msec_length > 0)
- values[count - 1] *= (long) log_10_int[msec_length];
+ if (transform_msec && field_length > 0)
+ {
+ if (field_length < 6)
+ values[count - 1] *= (long) log_10_int[6 - field_length];
+ else if (field_length > 6)
+ values[count - 1] /= (long) log_10_int[field_length - 6];
+ }
return (str != end);
}