diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result index e8fbba786a43f..0258267b5ec5e 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 5f27978347c44..e7e2b96f0ebd5 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 4a94c3a5f89dd..d7506026c628b 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); }