summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_datetime.result19
-rw-r--r--mysql-test/t/type_datetime.test19
-rw-r--r--sql-common/my_time.c13
3 files changed, 50 insertions, 1 deletions
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 6a692ed58e4..b6281443751 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -619,3 +619,22 @@ ERROR 42000: Invalid default value for 'da'
create table t1 (t time default '916:00:00 a');
ERROR 42000: Invalid default value for 't'
set @@sql_mode= @org_mode;
+SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7));
+CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7))
+20060810101112.0123450
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2006-08-10 10:11:12.0123450'
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7));
+CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7))
+20060810101112.0123450
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '00000002006-000008-0000010 000010:0000011:00000012.0123450'
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7));
+CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7))
+20060810101112.0123450
+SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
+CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7))
+20080729104251.1234560
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567'
+End of 5.1 tests
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index eb1b7bde844..d4fa6bed186 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -427,3 +427,22 @@ create table t1 (da date default '1962-03-32 23:33:34', dt datetime default '196
--error 1067
create table t1 (t time default '916:00:00 a');
set @@sql_mode= @org_mode;
+
+#
+# Bug #42146 - DATETIME fractional seconds parse error
+#
+# show we trucate microseconds from the right -- special case: leftmost is 0
+SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7));
+
+# show that we ignore leading zeroes for all other fields
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7));
+# once more with feeling (but no warnings)
+SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7));
+
+#
+# Bug #38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE
+#
+# show we truncate microseconds from the right
+SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
+
+--echo End of 5.1 tests
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 155e0237e3c..747c5797ed4 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -264,8 +264,19 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
{
const char *start= str;
ulong tmp_value= (uint) (uchar) (*str++ - '0');
+
+ /*
+ Internal format means no delimiters; every field has a fixed
+ width. Otherwise, we scan until we find a delimiter and discard
+ leading zeroes -- except for the microsecond part, where leading
+ zeroes are significant, and where we never process more than six
+ digits.
+ */
+ my_bool scan_until_delim= !is_internal_format &&
+ ((i != format_position[6]));
+
while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
- (!is_internal_format || --field_length))
+ (scan_until_delim || --field_length))
{
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
str++;