diff --git a/pkg/types/time.go b/pkg/types/time.go index a643e1f77bbec..e2d915df86489 100644 --- a/pkg/types/time.go +++ b/pkg/types/time.go @@ -576,7 +576,10 @@ func GetFsp(s string) int { // GetFracIndex finds the last '.' for get fracStr, index = -1 means fracStr not found. // but for format like '2019.01.01 00:00:00', the index should be -1. -// It will not be affected by the time zone suffix. For format like '2020-01-01 12:00:00.123456+05:00', the index should be 19. +// +// It will not be affected by the time zone suffix. +// For format like '2020-01-01 12:00:00.123456+05:00' and `2020-01-01 12:00:00.123456-05:00`, the index should be 19. +// related issue https://github.com/pingcap/tidb/issues/35291 and https://github.com/pingcap/tidb/issues/49555 func GetFracIndex(s string) (index int) { tzIndex, _, _, _, _ := GetTimezone(s) var end int @@ -587,7 +590,7 @@ func GetFracIndex(s string) (index int) { } index = -1 for i := end; i >= 0; i-- { - if unicode.IsPunct(rune(s[i])) { + if s[i] != '+' && s[i] != '-' && isPunctuation(s[i]) { if s[i] == '.' { index = i } diff --git a/pkg/types/time_test.go b/pkg/types/time_test.go index 263eabfa255f0..c9bc3e7fd2dcb 100644 --- a/pkg/types/time_test.go +++ b/pkg/types/time_test.go @@ -114,6 +114,8 @@ func TestDateTime(t *testing.T) { // For issue 35291 {"2020-01-01 12:00:00.123456+05:00", "2020-01-01 07:00:00.123456"}, + // For issue 49555 + {"2020-01-01 12:00:00.123456-05:00", "2020-01-01 17:00:00.123456"}, } for _, test := range table { @@ -1902,6 +1904,8 @@ func TestGetFracIndex(t *testing.T) { {"2019.01.01 00:00:00", -1}, {"2019.01.01 00:00:00.1", 19}, {"12345.6", 5}, + {"2020-01-01 12:00:00.123456 +0600 PST", 19}, + {"2020-01-01 12:00:00.123456 -0600 PST", 19}, } for _, testCase := range testCases { index := types.GetFracIndex(testCase.str) diff --git a/tests/integrationtest/r/expression/cast.result b/tests/integrationtest/r/expression/cast.result index 6628ec0af24c6..d54c9aea37ea1 100644 --- a/tests/integrationtest/r/expression/cast.result +++ b/tests/integrationtest/r/expression/cast.result @@ -78,6 +78,16 @@ select cast(col4 as time(31)) from t where col1 is null; Error 1426 (42000): Too big precision 31 specified for column 'CAST'. Maximum is 6. select cast(col5 as time(31)) from t where col1 is null; Error 1426 (42000): Too big precision 31 specified for column 'CAST'. Maximum is 6. +drop table if exists t; +create table t(a varchar(50)); +insert into t values ('2020-01-01 12:00:00.123456 +0600 PST'); +insert into t values ('2020-01-01 12:00:00.123456 -0600 PST'); +insert into t values ('2020-01-01 12:00:00.123456'); +select cast(a as datetime(3)) from t; +cast(a as datetime(3)) +2020-01-01 12:00:00.123 +2020-01-01 12:00:00.123 +2020-01-01 12:00:00.123 drop table if exists t1; create table t1 (c1 text); insert into t1 values ('a'); diff --git a/tests/integrationtest/t/expression/cast.test b/tests/integrationtest/t/expression/cast.test index e1681e4d87934..854daad9756b5 100644 --- a/tests/integrationtest/t/expression/cast.test +++ b/tests/integrationtest/t/expression/cast.test @@ -45,6 +45,12 @@ select cast(col3 as time(31)) from t where col1 is null; select cast(col4 as time(31)) from t where col1 is null; -- error 1426 select cast(col5 as time(31)) from t where col1 is null; +drop table if exists t; +create table t(a varchar(50)); +insert into t values ('2020-01-01 12:00:00.123456 +0600 PST'); +insert into t values ('2020-01-01 12:00:00.123456 -0600 PST'); +insert into t values ('2020-01-01 12:00:00.123456'); +select cast(a as datetime(3)) from t; # TestCastErrMsg drop table if exists t1;