Skip to content

Commit f0a26dd

Browse files
authored
expression: Fix the issue that cast str as datetime with time_zone results in loss of precision (pingcap#50958)
close pingcap#49555
1 parent bb43e2d commit f0a26dd

File tree

4 files changed

+25
-2
lines changed

4 files changed

+25
-2
lines changed

pkg/types/time.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,10 @@ func GetFsp(s string) int {
576576

577577
// GetFracIndex finds the last '.' for get fracStr, index = -1 means fracStr not found.
578578
// but for format like '2019.01.01 00:00:00', the index should be -1.
579-
// 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.
579+
//
580+
// It will not be affected by the time zone suffix.
581+
// 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.
582+
// related issue https://github.com/pingcap/tidb/issues/35291 and https://github.com/pingcap/tidb/issues/49555
580583
func GetFracIndex(s string) (index int) {
581584
tzIndex, _, _, _, _ := GetTimezone(s)
582585
var end int
@@ -587,7 +590,7 @@ func GetFracIndex(s string) (index int) {
587590
}
588591
index = -1
589592
for i := end; i >= 0; i-- {
590-
if unicode.IsPunct(rune(s[i])) {
593+
if s[i] != '+' && s[i] != '-' && isPunctuation(s[i]) {
591594
if s[i] == '.' {
592595
index = i
593596
}

pkg/types/time_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ func TestDateTime(t *testing.T) {
114114

115115
// For issue 35291
116116
{"2020-01-01 12:00:00.123456+05:00", "2020-01-01 07:00:00.123456"},
117+
// For issue 49555
118+
{"2020-01-01 12:00:00.123456-05:00", "2020-01-01 17:00:00.123456"},
117119
}
118120

119121
for _, test := range table {
@@ -1902,6 +1904,8 @@ func TestGetFracIndex(t *testing.T) {
19021904
{"2019.01.01 00:00:00", -1},
19031905
{"2019.01.01 00:00:00.1", 19},
19041906
{"12345.6", 5},
1907+
{"2020-01-01 12:00:00.123456 +0600 PST", 19},
1908+
{"2020-01-01 12:00:00.123456 -0600 PST", 19},
19051909
}
19061910
for _, testCase := range testCases {
19071911
index := types.GetFracIndex(testCase.str)

tests/integrationtest/r/expression/cast.result

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ select cast(col4 as time(31)) from t where col1 is null;
7878
Error 1426 (42000): Too big precision 31 specified for column 'CAST'. Maximum is 6.
7979
select cast(col5 as time(31)) from t where col1 is null;
8080
Error 1426 (42000): Too big precision 31 specified for column 'CAST'. Maximum is 6.
81+
drop table if exists t;
82+
create table t(a varchar(50));
83+
insert into t values ('2020-01-01 12:00:00.123456 +0600 PST');
84+
insert into t values ('2020-01-01 12:00:00.123456 -0600 PST');
85+
insert into t values ('2020-01-01 12:00:00.123456');
86+
select cast(a as datetime(3)) from t;
87+
cast(a as datetime(3))
88+
2020-01-01 12:00:00.123
89+
2020-01-01 12:00:00.123
90+
2020-01-01 12:00:00.123
8191
drop table if exists t1;
8292
create table t1 (c1 text);
8393
insert into t1 values ('a');

tests/integrationtest/t/expression/cast.test

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ select cast(col3 as time(31)) from t where col1 is null;
4545
select cast(col4 as time(31)) from t where col1 is null;
4646
-- error 1426
4747
select cast(col5 as time(31)) from t where col1 is null;
48+
drop table if exists t;
49+
create table t(a varchar(50));
50+
insert into t values ('2020-01-01 12:00:00.123456 +0600 PST');
51+
insert into t values ('2020-01-01 12:00:00.123456 -0600 PST');
52+
insert into t values ('2020-01-01 12:00:00.123456');
53+
select cast(a as datetime(3)) from t;
4854

4955
# TestCastErrMsg
5056
drop table if exists t1;

0 commit comments

Comments
 (0)