From 1b5a4492106f1aab2c6c8c12f2cdb23d6da45003 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 29 Jul 2021 09:41:47 +0800 Subject: [PATCH 01/13] add support for parsing timestamp with both letter 'T' and whitespace as timezone indicator --- src/os/src/detail/osTime.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 847d484d9e..8db3fed701 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -82,7 +82,7 @@ void deltaToUtcInitOnce() { } static int64_t parseFraction(char* str, char** end, int32_t timePrec); -static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec); +static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim); static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec); static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec); @@ -96,7 +96,9 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ if (strnchr(timestr, 'T', len, false) != NULL) { - return parseTimeWithTz(timestr, time, timePrec); + return parseTimeWithTz(timestr, time, timePrec, 'T'); + } else if (strnchr(timestr, ' ', len, false) != NULL) { + return parseTimeWithTz(timestr, time, timePrec, ' '); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); } @@ -213,14 +215,23 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) { * 2013-04-12T15:52:01+0800 * 2013-04-12T15:52:01.123+0800 */ -int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec) { +int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim) { int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); int64_t tzOffset = 0; struct tm tm = {0}; - char* str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm); + + char* str; + if (delim == 'T') { + str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm); + } else if (delim == ' ') { + str = strptime(timestr, "%Y-%m-%d%n%H:%M:%S", &tm); + } else { + str = NULL; + } + if (str == NULL) { return -1; } From 02f88d54098ee3648d740e906a86c247539c344e Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 29 Jul 2021 13:03:18 +0800 Subject: [PATCH 02/13] [TD-5505]: add support for parsing timestamp with both letter 'T' and whitespace as timezone indicator --- src/os/src/detail/osTime.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 8db3fed701..c7a249c2e3 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -85,6 +85,7 @@ static int64_t parseFraction(char* str, char** end, int32_t timePrec); static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim); static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec); static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec); +static char* forwardToTimeStringEnd(char* str); static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = { parseLocaltime, @@ -95,9 +96,12 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ + char *seg = forwardToTimeStringEnd(timestr); if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); - } else if (strnchr(timestr, ' ', len, false) != NULL) { + } else if (strnchr(timestr, ' ', len, false) != NULL && + (strnchr(seg, 'Z', len, false) != NULL || strnchr(seg, 'z', len, false) != NULL || + strnchr(seg, '+', len, false) != NULL || strnchr(seg, '-', len, false) != NULL)) { return parseTimeWithTz(timestr, time, timePrec, ' '); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); From f56027daddeda1716b0940806a460ff37e3be41f Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 29 Jul 2021 13:03:18 +0800 Subject: [PATCH 03/13] [TD-5505]: add test cases --- src/os/src/detail/osTime.c | 4 ++-- src/query/tests/unitTest.cpp | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index c7a249c2e3..85970a4790 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -100,8 +100,8 @@ int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePre if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); } else if (strnchr(timestr, ' ', len, false) != NULL && - (strnchr(seg, 'Z', len, false) != NULL || strnchr(seg, 'z', len, false) != NULL || - strnchr(seg, '+', len, false) != NULL || strnchr(seg, '-', len, false) != NULL)) { + (strnchr(seg, 'Z', strlen(seg), false) != NULL || strnchr(seg, 'z', strlen(seg), false) != NULL || + strnchr(seg, '+', strlen(seg), false) != NULL || strnchr(seg, '-', strlen(seg), false) != NULL)) { return parseTimeWithTz(timestr, time, timePrec, ' '); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index e5487a061d..51afca9532 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -407,11 +407,33 @@ TEST(testCase, parse_time) { taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, 852048000999); - int64_t k = timezone; char t42[] = "1997-1-1T0:0:0.999999999Z"; taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND); + // "%Y-%m-%d %H:%M:%S" format with TimeZone appendix is also treated as legal + // and TimeZone will be processed + char t60[] = "2017-4-3 1:1:2.980"; + char t61[] = "2017-4-3 2:1:2.98+9:00"; + taosParseTime(t60, &time, strlen(t60), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t61, &time1, strlen(t61), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t62[] = "2017-4-3 2:1:2.98+09:00"; + taosParseTime(t62, &time, strlen(t62), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t61, &time1, strlen(t61), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t63[] = "2017-4-3 2:1:2.98+0900"; + taosParseTime(t63, &time, strlen(t63), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t62, &time1, strlen(t62), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t64[] = "2017-4-2 17:1:2.98Z"; + taosParseTime(t63, &time, strlen(t63), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t64, &time1, strlen(t64), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + //////////////////////////////////////////////////////////////////// // illegal timestamp format char t15[] = "2017-12-33 0:0:0"; @@ -430,8 +452,7 @@ TEST(testCase, parse_time) { EXPECT_EQ(taosParseTime(t19, &time, strlen(t19), TSDB_TIME_PRECISION_MILLI, 0), -1); char t20[] = "2017-12-31 9:0:0.1+12:99"; - EXPECT_EQ(taosParseTime(t20, &time, strlen(t20), TSDB_TIME_PRECISION_MILLI, 0), 0); - EXPECT_EQ(time, 1514682000100); + EXPECT_EQ(taosParseTime(t20, &time, strlen(t20), TSDB_TIME_PRECISION_MILLI, 0), -1); char t21[] = "2017-12-31T9:0:0.1+12:99"; EXPECT_EQ(taosParseTime(t21, &time, strlen(t21), TSDB_TIME_PRECISION_MILLI, 0), -1); From 20b79cb24ff923523600ac06246894cbbf65b616 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 29 Jul 2021 19:01:50 +0800 Subject: [PATCH 04/13] [TD-5505]:windows build error --- src/os/src/detail/osTime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 85970a4790..2a74ef131b 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -100,8 +100,8 @@ int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePre if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); } else if (strnchr(timestr, ' ', len, false) != NULL && - (strnchr(seg, 'Z', strlen(seg), false) != NULL || strnchr(seg, 'z', strlen(seg), false) != NULL || - strnchr(seg, '+', strlen(seg), false) != NULL || strnchr(seg, '-', strlen(seg), false) != NULL)) { + (strnchr(seg, 'Z', (int32_t)strlen(seg), false) != NULL || strnchr(seg, 'z', (int32_t)strlen(seg), false) != NULL || + strnchr(seg, '+', (int32_t)strlen(seg), false) != NULL || strnchr(seg, '-', (int32_t)strlen(seg), false) != NULL)) { return parseTimeWithTz(timestr, time, timePrec, ' '); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); From db88b17c61d769a72fbb0cfd7b95bb258c9eac85 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 30 Jul 2021 10:42:33 +0800 Subject: [PATCH 05/13] [TD-5505]:fix timezone string part length issue --- src/os/src/detail/osTime.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 2a74ef131b..7ae9f58bc4 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -97,11 +97,12 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ char *seg = forwardToTimeStringEnd(timestr); + int32_t seg_len = len - (seg - timestr); if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); } else if (strnchr(timestr, ' ', len, false) != NULL && - (strnchr(seg, 'Z', (int32_t)strlen(seg), false) != NULL || strnchr(seg, 'z', (int32_t)strlen(seg), false) != NULL || - strnchr(seg, '+', (int32_t)strlen(seg), false) != NULL || strnchr(seg, '-', (int32_t)strlen(seg), false) != NULL)) { + (strnchr(seg, 'Z', seg_len, false) != NULL || strnchr(seg, 'z', seg_len, false) != NULL || + strnchr(seg, '+', seg_len, false) != NULL || strnchr(seg, '-', seg_len, false) != NULL)) { return parseTimeWithTz(timestr, time, timePrec, ' '); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); From 83b5c2a6a7141c7965bd71fbb9495db534b11377 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 30 Jul 2021 11:42:56 +0800 Subject: [PATCH 06/13] [TD-5505]: windows compilation error --- src/os/src/detail/osTime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 7ae9f58bc4..696867e586 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -97,7 +97,7 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ char *seg = forwardToTimeStringEnd(timestr); - int32_t seg_len = len - (seg - timestr); + int32_t seg_len = len - (int32_t)(seg - timestr); if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); } else if (strnchr(timestr, ' ', len, false) != NULL && From 1d9c079d2317dfe3725972b2b3724afad5be60e4 Mon Sep 17 00:00:00 2001 From: wenzhouwww Date: Mon, 2 Aug 2021 15:47:41 +0800 Subject: [PATCH 07/13] this is a test case for date formate about TDengine --- tests/pytest/ZoneTimeTest.py | 174 +++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 tests/pytest/ZoneTimeTest.py diff --git a/tests/pytest/ZoneTimeTest.py b/tests/pytest/ZoneTimeTest.py new file mode 100644 index 0000000000..0e33f1887d --- /dev/null +++ b/tests/pytest/ZoneTimeTest.py @@ -0,0 +1,174 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * +import datetime + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def checkCommunity(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + if ("community" in selfPath): + return False + else: + return True + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosdump" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + + + def run(self): + + # clear envs + + tdSql.execute(" create database ZoneTime precision 'us' ") + tdSql.execute(" use ZoneTime ") + tdSql.execute(" create stable st (ts timestamp , id int , val float) tags (tag1 timestamp ,tag2 int) ") + + # standard case for Timestamp + + tdSql.execute(" insert into tb1 using st tags (\"2021-07-01 00:00:00.000\" , 2) values( \"2021-07-01 00:00:00.000\" , 1 , 1.0 ) ") + case1 = (tdSql.getResult("select * from tb1")) + print(case1) + if case1 == [(datetime.datetime(2021, 7, 1, 0, 0), 1, 1.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01 00:00:00.000' ") + + # RCF-3339 : it allows "T" is replaced by " " + + tdSql.execute(" insert into tb2 using st tags (\"2021-07-01T00:00:00.000+07:50\" , 2) values( \"2021-07-01T00:00:00.000+07:50\" , 2 , 2.0 ) ") + case2 = (tdSql.getResult("select * from tb2")) + print(case2) + if case2 == [(datetime.datetime(2021, 7, 1, 0, 10), 2, 2.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01T00:00:00.000+07:50'! ") + + tdSql.execute(" insert into tb3 using st tags (\"2021-07-01T00:00:00.000+08:00\" , 3) values( \"2021-07-01T00:00:00.000+08:00\" , 3 , 3.0 ) ") + case3 = (tdSql.getResult("select * from tb3")) + print(case3) + if case3 == [(datetime.datetime(2021, 7, 1, 0, 0), 3, 3.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01T00:00:00.000+08:00'! ") + + tdSql.execute(" insert into tb4 using st tags (\"2021-07-01T00:00:00.000Z\" , 4) values( \"2021-07-01T00:00:00.000Z\" , 4 , 4.0 ) ") + case4 = (tdSql.getResult("select * from tb4")) + print(case4) + if case4 == [(datetime.datetime(2021, 7, 1, 8, 0), 4, 4.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01T00:00:00.000Z'! ") + + tdSql.execute(" insert into tb5 using st tags (\"2021-07-01 00:00:00.000+07:50\" , 5) values( \"2021-07-01 00:00:00.000+07:50\" , 5 , 5.0 ) ") + case5 = (tdSql.getResult("select * from tb5")) + print(case5) + if case5 == [(datetime.datetime(2021, 7, 1, 0, 10), 5, 5.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01 00:00:00.000+08:00 ") + + tdSql.execute(" insert into tb6 using st tags (\"2021-07-01 00:00:00.000Z\" , 6) values( \"2021-07-01 00:00:00.000Z\" , 6 , 6.0 ) ") + case6 = (tdSql.getResult("select * from tb6")) + print(case6) + if case6 == [(datetime.datetime(2021, 7, 1, 8, 0), 6, 6.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01 00:00:00.000Z'! ") + + # ISO 8610 timestamp format , time days and hours must be split by "T" + + tdSql.execute(" insert into tb7 using st tags (\"2021-07-01T00:00:00.000+0800\" , 7) values( \"2021-07-01T00:00:00.000+0800\" , 7 , 7.0 ) ") + case7 = (tdSql.getResult("select * from tb7")) + print(case7) + if case7 == [(datetime.datetime(2021, 7, 1, 0, 0), 7, 7.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01T00:00:00.000+0800'! ") + + tdSql.execute(" insert into tb8 using st tags (\"2021-07-01T00:00:00.000+08\" , 8) values( \"2021-07-01T00:00:00.000+08\" , 8 , 8.0 ) ") + case8 = (tdSql.getResult("select * from tb8")) + print(case8) + if case8 == [(datetime.datetime(2021, 7, 1, 0, 0), 8, 8.0)]: + print ("check pass! ") + else: + print ("check failed about timestamp '2021-07-01T00:00:00.000+08'! ") + + # Non-standard case for Timestamp + + tdSql.execute(" insert into tb9 using st tags (\"2021-07-01 00:00:00.000+0800\" , 9) values( \"2021-07-01 00:00:00.000+0800\" , 9 , 9.0 ) ") + case9 = (tdSql.getResult("select * from tb9")) + print(case9) + + tdSql.execute(" insert into tb10 using st tags (\"2021-07-0100:00:00.000\" , 10) values( \"2021-07-0100:00:00.000\" , 10 , 10.0 ) ") + case10 = (tdSql.getResult("select * from tb10")) + print(case10) + + tdSql.execute(" insert into tb11 using st tags (\"2021-07-0100:00:00.000+0800\" , 11) values( \"2021-07-0100:00:00.000+0800\" , 11 , 11.0 ) ") + case11 = (tdSql.getResult("select * from tb11")) + print(case11) + + tdSql.execute(" insert into tb12 using st tags (\"2021-07-0100:00:00.000+08:00\" , 12) values( \"2021-07-0100:00:00.000+08:00\" , 12 , 12.0 ) ") + case12 = (tdSql.getResult("select * from tb12")) + print(case12) + + tdSql.execute(" insert into tb13 using st tags (\"2021-07-0100:00:00.000Z\" , 13) values( \"2021-07-0100:00:00.000Z\" , 13 , 13.0 ) ") + case13 = (tdSql.getResult("select * from tb13")) + print(case13) + + tdSql.execute(" insert into tb14 using st tags (\"2021-07-0100:00:00.000Z\" , 14) values( \"2021-07-0100:00:00.000Z\" , 14 , 14.0 ) ") + case14 = (tdSql.getResult("select * from tb14")) + print(case14) + + tdSql.execute(" insert into tb15 using st tags (\"2021-07-0100:00:00.000+08\" , 15) values( \"2021-07-0100:00:00.000+08\" , 15 , 15.0 ) ") + case15 = (tdSql.getResult("select * from tb15")) + print(case15) + + tdSql.execute(" insert into tb16 using st tags (\"2021-07-0100:00:00.000+07:50\" , 16) values( \"2021-07-0100:00:00.000+07:50\" , 16 , 16.0 ) ") + case16 = (tdSql.getResult("select * from tb16")) + print(case16) + + os.system("rm -rf *.py.sql") + + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) From 3ce28c06792e0473a9764d714d0dd415e5b3e404 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Mon, 2 Aug 2021 16:08:05 +0800 Subject: [PATCH 08/13] [TD-5505]: return error if there're additional illegal characters after timezeone str --- src/os/src/detail/osTime.c | 19 ++++++++++++++----- src/query/tests/unitTest.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 696867e586..9b5a86cbbb 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -72,12 +72,12 @@ int64_t user_mktime64(const unsigned int year0, const unsigned int mon0, // ==== mktime() kernel code =================// static int64_t m_deltaUtc = 0; -void deltaToUtcInitOnce() { +void deltaToUtcInitOnce() { struct tm tm = {0}; - + (void)strptime("1970-01-01 00:00:00", (const char *)("%Y-%m-%d %H:%M:%S"), &tm); m_deltaUtc = (int64_t)mktime(&tm); - //printf("====delta:%lld\n\n", seconds); + //printf("====delta:%lld\n\n", seconds); return; } @@ -90,7 +90,7 @@ static char* forwardToTimeStringEnd(char* str); static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = { parseLocaltime, parseLocaltimeWithDst -}; +}; int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } @@ -194,6 +194,13 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) { i += 2; } + //return error if there're illegal charaters after min(2 Digits) + char *minStr = &str[i]; + if (minStr[1] != '\0' && minStr[2] != '\0') { + return -1; + } + + int64_t minute = strnatoi(&str[i], 2); if (minute > 59) { return -1; @@ -252,7 +259,7 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del int64_t fraction = 0; str = forwardToTimeStringEnd(timestr); - if (str[0] == 'Z' || str[0] == 'z') { + if ((str[0] == 'Z' || str[0] == 'z') && str[1] == '\0') { /* utc time, no millisecond, return directly*/ *time = seconds * factor; } else if (str[0] == '.') { @@ -266,6 +273,8 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del char seg = str[0]; if (seg != 'Z' && seg != 'z' && seg != '+' && seg != '-') { return -1; + } else if ((seg == 'Z' || seg == 'z') && str[1] != '\0') { + return -1; } else if (seg == '+' || seg == '-') { // parse the timezone if (parseTimezone(str, &tzOffset) == -1) { diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index 51afca9532..e898992a40 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -462,6 +462,42 @@ TEST(testCase, parse_time) { char t23[] = "2017-12-31T9:0:0.1+13:1"; EXPECT_EQ(taosParseTime(t23, &time, strlen(t23), TSDB_TIME_PRECISION_MILLI, 0), 0); + + char t24[] = "2017-12-31T9:0:0.1+13:001"; + EXPECT_EQ(taosParseTime(t24, &time, strlen(t24), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t25[] = "2017-12-31T9:0:0.1+13:00abc"; + EXPECT_EQ(taosParseTime(t25, &time, strlen(t25), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t26[] = "2017-12-31T9:0:0.1+13001"; + EXPECT_EQ(taosParseTime(t26, &time, strlen(t26), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t27[] = "2017-12-31T9:0:0.1+1300abc"; + EXPECT_EQ(taosParseTime(t27, &time, strlen(t27), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t28[] = "2017-12-31T9:0:0Z+12:00"; + EXPECT_EQ(taosParseTime(t28, &time, strlen(t28), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t29[] = "2017-12-31T9:0:0.123Z+12:00"; + EXPECT_EQ(taosParseTime(t29, &time, strlen(t29), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t65[] = "2017-12-31 9:0:0.1+13:001"; + EXPECT_EQ(taosParseTime(t65, &time, strlen(t65), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t66[] = "2017-12-31 9:0:0.1+13:00abc"; + EXPECT_EQ(taosParseTime(t66, &time, strlen(t66), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t67[] = "2017-12-31 9:0:0.1+13001"; + EXPECT_EQ(taosParseTime(t67, &time, strlen(t67), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t68[] = "2017-12-31 9:0:0.1+1300abc"; + EXPECT_EQ(taosParseTime(t68, &time, strlen(t68), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t69[] = "2017-12-31 9:0:0Z+12:00"; + EXPECT_EQ(taosParseTime(t69, &time, strlen(t69), TSDB_TIME_PRECISION_MILLI, 0), -1); + + char t70[] = "2017-12-31 9:0:0.123Z+12:00"; + EXPECT_EQ(taosParseTime(t70, &time, strlen(t70), TSDB_TIME_PRECISION_MILLI, 0), -1); } TEST(testCase, tvariant_convert) { From 3cfb2ea995c06f39d0e466a1dae01d5d3870d10d Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 4 Aug 2021 23:48:45 +0800 Subject: [PATCH 09/13] [TD-5505]: if there's no space or 'T' delimiter timezone will also be parsed --- src/os/src/detail/osTime.c | 23 +++++++++++++++-------- src/query/tests/unitTest.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 9b5a86cbbb..078b9c62d0 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -86,6 +86,7 @@ static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, c static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec); static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec); static char* forwardToTimeStringEnd(char* str); +static bool checkTzPresent(char *str, int32_t len); static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = { parseLocaltime, @@ -96,19 +97,25 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { /* parse datatime string in with tz */ - char *seg = forwardToTimeStringEnd(timestr); - int32_t seg_len = len - (int32_t)(seg - timestr); if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec, 'T'); - } else if (strnchr(timestr, ' ', len, false) != NULL && - (strnchr(seg, 'Z', seg_len, false) != NULL || strnchr(seg, 'z', seg_len, false) != NULL || - strnchr(seg, '+', seg_len, false) != NULL || strnchr(seg, '-', seg_len, false) != NULL)) { - return parseTimeWithTz(timestr, time, timePrec, ' '); + } else if (checkTzPresent(timestr, len)) { + return parseTimeWithTz(timestr, time, timePrec, 0); } else { return (*parseLocaltimeFp[day_light])(timestr, time, timePrec); } } +bool checkTzPresent(char *str, int32_t len) { + char *seg = forwardToTimeStringEnd(str); + int32_t seg_len = len - (int32_t)(seg - str); + + return (strnchr(seg, 'Z', seg_len, false) != NULL || + strnchr(seg, 'z', seg_len, false) != NULL || + strnchr(seg, '+', seg_len, false) != NULL || + strnchr(seg, '-', seg_len, false) != NULL); +} + char* forwardToTimeStringEnd(char* str) { int32_t i = 0; int32_t numOfSep = 0; @@ -238,8 +245,8 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del char* str; if (delim == 'T') { str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm); - } else if (delim == ' ') { - str = strptime(timestr, "%Y-%m-%d%n%H:%M:%S", &tm); + } else if (delim == 0) { + str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm); } else { str = NULL; } diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index e898992a40..740a783ca0 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -434,6 +434,29 @@ TEST(testCase, parse_time) { taosParseTime(t64, &time1, strlen(t64), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, time1); + // "%Y-%m-%d%H:%M:%S" format with TimeZone appendix is also treated as legal + // and TimeZone will be processed + char t80[] = "2017-4-51:1:2.980"; + char t81[] = "2017-4-52:1:2.98+9:00"; + taosParseTime(t80, &time, strlen(t80), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t81, &time1, strlen(t81), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t82[] = "2017-4-52:1:2.98+09:00"; + taosParseTime(t82, &time, strlen(t82), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t81, &time1, strlen(t81), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t83[] = "2017-4-52:1:2.98+0900"; + taosParseTime(t83, &time, strlen(t83), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t82, &time1, strlen(t82), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + + char t84[] = "2017-4-417:1:2.98Z"; + taosParseTime(t83, &time, strlen(t83), TSDB_TIME_PRECISION_MILLI, 0); + taosParseTime(t84, &time1, strlen(t84), TSDB_TIME_PRECISION_MILLI, 0); + EXPECT_EQ(time, time1); + //////////////////////////////////////////////////////////////////// // illegal timestamp format char t15[] = "2017-12-33 0:0:0"; @@ -498,6 +521,7 @@ TEST(testCase, parse_time) { char t70[] = "2017-12-31 9:0:0.123Z+12:00"; EXPECT_EQ(taosParseTime(t70, &time, strlen(t70), TSDB_TIME_PRECISION_MILLI, 0), -1); + } TEST(testCase, tvariant_convert) { From 842b3cb3078045d7a93ed445e2a471c0bde95126 Mon Sep 17 00:00:00 2001 From: wenzhouwww Date: Thu, 5 Aug 2021 16:04:07 +0800 Subject: [PATCH 10/13] [TD-5619] : this is test case about parse timezone which is based on RCF3339/ISO8601 --- tests/pytest/TimeZone/TestCaseTimeZone.py | 253 ++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 tests/pytest/TimeZone/TestCaseTimeZone.py diff --git a/tests/pytest/TimeZone/TestCaseTimeZone.py b/tests/pytest/TimeZone/TestCaseTimeZone.py new file mode 100644 index 0000000000..d99af7b995 --- /dev/null +++ b/tests/pytest/TimeZone/TestCaseTimeZone.py @@ -0,0 +1,253 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import os +import subprocess +import time +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * +import datetime + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root)-len("/build/bin")] + break + return buildPath + + def run(self): + tdSql.prepare() + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + binPath = buildPath+ "/build/bin/" + + tdSql.execute("create database timezone") + tdSql.execute("use timezone") + tdSql.execute("create stable st (ts timestamp, id int ) tags (index int)") + + tdSql.execute("insert into tb0 using st tags (1) values ('2021-07-01 00:00:00.000',0)") + res = tdSql.getResult("select * from tb0") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 0)]: + tdLog.info("time format is check pass : '2021-07-01 00:00:00.000' ") + else: + tdLog.info(" '2021-07-01 00:00:00.000' failed ") + + tdSql.execute("insert into tb1 using st tags (1) values ('2021-07-01T00:00:00.000+07:50',1)") + res = tdSql.getResult("select * from tb1") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 10), 1)]: + tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+07:50' ") + else: + tdLog.info(" '2021-07-01T00:00:00.000+07:50' failed ") + + tdSql.execute("insert into tb2 using st tags (1) values ('2021-07-01T00:00:00.000+08:00',2)") + res = tdSql.getResult("select * from tb2") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 2)]: + tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+08:00' ") + else: + tdLog.info(" '2021-07-01T00:00:00.000+08:00' failed ") + + tdSql.execute("insert into tb3 using st tags (1) values ('2021-07-01T00:00:00.000Z',3)") + res = tdSql.getResult("select * from tb3") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 8, 0), 3)]: + tdLog.info("time format is check pass : '2021-07-01T00:00:00.000Z' ") + else: + tdLog.info(" '2021-07-01T00:00:00.000Z' failed ") + + tdSql.execute("insert into tb4 using st tags (1) values ('2021-07-01 00:00:00.000+07:50',4)") + res = tdSql.getResult("select * from tb4") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 10), 4)]: + tdLog.info("time format is check pass : '2021-07-01 00:00:00.000+07:50' ") + else: + tdLog.info(" '2021-07-01 00:00:00.000+07:50' failed ") + + tdSql.execute("insert into tb5 using st tags (1) values ('2021-07-01 00:00:00.000Z',5)") + res = tdSql.getResult("select * from tb5") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 8, 0), 5)]: + tdLog.info("time format is check pass : '2021-07-01 00:00:00.000Z' ") + else: + tdLog.info(" '2021-07-01 00:00:00.000Z' failed ") + + tdSql.execute("insert into tb6 using st tags (1) values ('2021-07-01T00:00:00.000+0800',6)") + res = tdSql.getResult("select * from tb6") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 6)]: + tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+0800' ") + else: + tdLog.info(" '2021-07-01T00:00:00.000+0800' failed ") + + tdSql.execute("insert into tb7 using st tags (1) values ('2021-07-01 00:00:00.000+0800',7)") + res = tdSql.getResult("select * from tb7") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 7)]: + tdLog.info("time format is check pass : '2021-07-01 00:00:00.000+0800' ") + else: + tdLog.info(" '2021-07-01 00:00:00.000+0800' failed ") + + tdSql.execute("insert into tb8 using st tags (1) values ('2021-07-0100:00:00.000',8)") + res = tdSql.getResult("select * from tb8") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 8)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000' ") + else: + tdLog.info(" '2021-07-0100:00:00.000' failed ") + + tdSql.execute("insert into tb9 using st tags (1) values ('2021-07-0100:00:00.000+0800',9)") + res = tdSql.getResult("select * from tb9") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 9)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0800' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+0800' failed ") + + tdSql.execute("insert into tb10 using st tags (1) values ('2021-07-0100:00:00.000+08:00',10)") + res = tdSql.getResult("select * from tb10") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 0), 10)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+08:00' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+08:00' failed ") + + tdSql.execute("insert into tb11 using st tags (1) values ('2021-07-0100:00:00.000+07:00',11)") + res = tdSql.getResult("select * from tb11") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 1, 0), 11)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07:00' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+07:00' failed ") + + tdSql.execute("insert into tb12 using st tags (1) values ('2021-07-0100:00:00.000+07:00',12)") + res = tdSql.getResult("select * from tb12") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 1, 0), 12)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+07' failed ") + + tdSql.execute("insert into tb13 using st tags (1) values ('2021-07-0100:00:00.000+07:12',13)") + res = tdSql.getResult("select * from tb13") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 48), 13)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07:12' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+07:12' failed ") + + tdSql.execute("insert into tb14 using st tags (1) values ('2021-07-0100:00:00.000+712',14)") + res = tdSql.getResult("select * from tb14") + print(res) + if res == [(datetime.datetime(2021, 6, 28, 8, 58), 14)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+712' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+712' failed ") + + tdSql.execute("insert into tb15 using st tags (1) values ('2021-07-0100:00:00.000Z',15)") + res = tdSql.getResult("select * from tb15") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 8, 0), 15)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000Z' ") + else: + tdLog.info(" '2021-07-0100:00:00.000Z' failed ") + + tdSql.execute("insert into tb16 using st tags (1) values ('2021-7-1 00:00:00.000Z',16)") + res = tdSql.getResult("select * from tb16") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 8, 0), 16)]: + tdLog.info("time format is check pass : '2021-7-1 00:00:00.000Z' ") + else: + tdLog.info(" '2021-7-1 00:00:00.000Z' failed ") + + tdSql.execute("insert into tb17 using st tags (1) values ('2021-07-0100:00:00.000+0750',17)") + res = tdSql.getResult("select * from tb17") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 10), 17)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0750' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+0750' failed ") + + tdSql.execute("insert into tb18 using st tags (1) values ('2021-07-0100:00:00.000+0752',18)") + res = tdSql.getResult("select * from tb18") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 8), 18)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0752' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+0752' failed ") + + tdSql.execute("insert into tb19 using st tags (1) values ('2021-07-0100:00:00.000+075',19)") + res = tdSql.getResult("select * from tb19") + print(res) + if res == [(datetime.datetime(2021, 7, 1, 0, 55), 19)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+075' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+075' failed ") + + tdSql.execute("insert into tb20 using st tags (1) values ('2021-07-0100:00:00.000+75',20)") + res = tdSql.getResult("select * from tb20") + print(res) + if res == [(datetime.datetime(2021, 6, 28, 5, 0), 20)]: + tdLog.info("time format is check pass : '2021-07-0100:00:00.000+75' ") + else: + tdLog.info(" '2021-07-0100:00:00.000+75' failed ") + + + tdSql.error("insert into tberror using st tags (1) values ('20210701 00:00:00.000+0800',0)") + tdSql.error("insert into tberror using st tags (1) values ('2021070100:00:00.000+0800',0)") + tdSql.error("insert into tberror using st tags (1) values ('202171 00:00:00.000+0800',0)") + tdSql.error("insert into tberror using st tags (1) values ('2021 07 01 00:00:00.000+0800',0)") + tdSql.error("insert into tberror using st tags (1) values ('2021 -07-0100:00:00.000+0800',0)") + + + + + + + + + + + + + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) From d2dcecda649e8cb11e018c8f5c6c2246d7c9d9f2 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 5 Aug 2021 16:25:15 +0800 Subject: [PATCH 11/13] [TD-5619]: optimized checkTzPresent function --- src/os/src/detail/osTime.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 078b9c62d0..44c6a7d74c 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -110,10 +110,15 @@ bool checkTzPresent(char *str, int32_t len) { char *seg = forwardToTimeStringEnd(str); int32_t seg_len = len - (int32_t)(seg - str); - return (strnchr(seg, 'Z', seg_len, false) != NULL || - strnchr(seg, 'z', seg_len, false) != NULL || - strnchr(seg, '+', seg_len, false) != NULL || - strnchr(seg, '-', seg_len, false) != NULL); + char *c = &seg[seg_len - 1]; + for (int i = 0; i < seg_len; ++i) { + if (*c == 'Z' || *c == 'z' || *c == '+' || *c == '-') { + return true; + } + c--; + } + return false; + } char* forwardToTimeStringEnd(char* str) { From f0c988d92789770c7a824d86929c0cb781a1ef4f Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 5 Aug 2021 16:28:13 +0800 Subject: [PATCH 12/13] [TD-5505]: add taosParseTime profiling unitTests --- src/query/tests/unitTest.cpp | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index 740a783ca0..9f6e219c0a 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -524,6 +524,64 @@ TEST(testCase, parse_time) { } +/* test parse time profiling */ +TEST(testCase, parse_time_profile) { + taos_options(TSDB_OPTION_TIMEZONE, "GMT-8"); + char t1[] = "2018-1-8 1:1:1.952"; + char t2[] = "2018-1-8T1:1:1.952+0800"; + char t3[] = "2018-1-8 1:1:1.952+0800"; + char t4[] = "2018-1-81:1:1.952+0800"; + + char t5[] = "2018-1-8 1:1:1.952"; + char t6[] = "2018-1-8T1:1:1.952+08:00"; + char t7[] = "2018-1-8 1:1:1.952+08:00"; + char t8[] = "2018-1-81:1:1.952+08:00"; + + char t9[] = "2018-1-8 1:1:1.952"; + char t10[] = "2018-1-8T1:1:1.952Z"; + char t11[] = "2018-1-8 1:1:1.952z"; + char t12[] = "2018-1-81:1:1.952Z"; + + struct timeval start, end; + int64_t time = 0, time1 = 0; + + int32_t total_run = 100000000; + long total_time_us; + + gettimeofday(&start, NULL); + for (int i = 0; i < total_run; ++i) { + taosParseTime(t1, &time, strlen(t1), TSDB_TIME_PRECISION_MILLI, 0); + } + gettimeofday(&end, NULL); + total_time_us = ((end.tv_sec - start.tv_sec)* 1000000) + (end.tv_usec - start.tv_usec); + printf("[t1] The elapsed time is %f seconds in %d run, average:%fns\n", total_time_us/1000000.0, total_run, 1000*(float)total_time_us/(float)total_run); + + gettimeofday(&start, NULL); + for (int i = 0; i < total_run; ++i) { + taosParseTime(t2, &time, strlen(t2), TSDB_TIME_PRECISION_MILLI, 0); + } + gettimeofday(&end, NULL); + total_time_us = ((end.tv_sec - start.tv_sec)* 1000000) + (end.tv_usec - start.tv_usec); + printf("[t2] The elapsed time is %f seconds in %d run, average:%fns\n", total_time_us/1000000.0, total_run, 1000*(float)total_time_us/(float)total_run); + + gettimeofday(&start, NULL); + for (int i = 0; i < total_run; ++i) { + taosParseTime(t3, &time, strlen(t3), TSDB_TIME_PRECISION_MILLI, 0); + } + gettimeofday(&end, NULL); + total_time_us = ((end.tv_sec - start.tv_sec)* 1000000) + (end.tv_usec - start.tv_usec); + printf("[t3] The elapsed time is %f seconds in %d run, average:%fns\n", total_time_us/1000000.0, total_run, 1000*(float)total_time_us/(float)total_run); + + gettimeofday(&start, NULL); + for (int i = 0; i < total_run; ++i) { + taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI, 0); + } + gettimeofday(&end, NULL); + total_time_us = ((end.tv_sec - start.tv_sec)* 1000000) + (end.tv_usec - start.tv_usec); + printf("[t4] The elapsed time is %f seconds in %d run, average:%fns\n", total_time_us/1000000.0, total_run, 1000*(float)total_time_us/(float)total_run); +} + + TEST(testCase, tvariant_convert) { // 1. bool data to all other data types tVariant t = {0}; From dbadc405ee6f76afdce284127be073abf5a8f2de Mon Sep 17 00:00:00 2001 From: wenzhouwww Date: Thu, 5 Aug 2021 17:00:07 +0800 Subject: [PATCH 13/13] [TD-5619] add new case for timezone --- tests/pytest/TimeZone/TestCaseTimeZone.py | 195 +++++++--------------- tests/pytest/fulltest.sh | 4 + 2 files changed, 63 insertions(+), 136 deletions(-) diff --git a/tests/pytest/TimeZone/TestCaseTimeZone.py b/tests/pytest/TimeZone/TestCaseTimeZone.py index d99af7b995..0bad52ef98 100644 --- a/tests/pytest/TimeZone/TestCaseTimeZone.py +++ b/tests/pytest/TimeZone/TestCaseTimeZone.py @@ -57,172 +57,100 @@ class TDTestCase: tdSql.execute("create stable st (ts timestamp, id int ) tags (index int)") tdSql.execute("insert into tb0 using st tags (1) values ('2021-07-01 00:00:00.000',0)") - res = tdSql.getResult("select * from tb0") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 0)]: - tdLog.info("time format is check pass : '2021-07-01 00:00:00.000' ") - else: - tdLog.info(" '2021-07-01 00:00:00.000' failed ") + tdSql.query("select ts from tb0") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb1 using st tags (1) values ('2021-07-01T00:00:00.000+07:50',1)") - res = tdSql.getResult("select * from tb1") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 10), 1)]: - tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+07:50' ") - else: - tdLog.info(" '2021-07-01T00:00:00.000+07:50' failed ") - - tdSql.execute("insert into tb2 using st tags (1) values ('2021-07-01T00:00:00.000+08:00',2)") - res = tdSql.getResult("select * from tb2") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 2)]: - tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+08:00' ") - else: - tdLog.info(" '2021-07-01T00:00:00.000+08:00' failed ") + tdSql.query("select ts from tb1") + tdSql.checkData(0, 0, "2021-07-01 00:10:00.000") + tdSql.execute("insert into tb2 using st tags (1) values ('2021-07-01T00:00:00.000+08:00',2)") + tdSql.query("select ts from tb2") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") + tdSql.execute("insert into tb3 using st tags (1) values ('2021-07-01T00:00:00.000Z',3)") - res = tdSql.getResult("select * from tb3") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 8, 0), 3)]: - tdLog.info("time format is check pass : '2021-07-01T00:00:00.000Z' ") - else: - tdLog.info(" '2021-07-01T00:00:00.000Z' failed ") + tdSql.query("select ts from tb3") + tdSql.checkData(0, 0, "2021-07-01 08:00:00.000") tdSql.execute("insert into tb4 using st tags (1) values ('2021-07-01 00:00:00.000+07:50',4)") - res = tdSql.getResult("select * from tb4") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 10), 4)]: - tdLog.info("time format is check pass : '2021-07-01 00:00:00.000+07:50' ") - else: - tdLog.info(" '2021-07-01 00:00:00.000+07:50' failed ") + tdSql.query("select ts from tb4") + tdSql.checkData(0, 0, "2021-07-01 00:10:00.000") tdSql.execute("insert into tb5 using st tags (1) values ('2021-07-01 00:00:00.000Z',5)") - res = tdSql.getResult("select * from tb5") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 8, 0), 5)]: - tdLog.info("time format is check pass : '2021-07-01 00:00:00.000Z' ") - else: - tdLog.info(" '2021-07-01 00:00:00.000Z' failed ") + tdSql.query("select ts from tb5") + tdSql.checkData(0, 0, "2021-07-01 08:00:00.000") tdSql.execute("insert into tb6 using st tags (1) values ('2021-07-01T00:00:00.000+0800',6)") - res = tdSql.getResult("select * from tb6") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 6)]: - tdLog.info("time format is check pass : '2021-07-01T00:00:00.000+0800' ") - else: - tdLog.info(" '2021-07-01T00:00:00.000+0800' failed ") + tdSql.query("select ts from tb6") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb7 using st tags (1) values ('2021-07-01 00:00:00.000+0800',7)") - res = tdSql.getResult("select * from tb7") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 7)]: - tdLog.info("time format is check pass : '2021-07-01 00:00:00.000+0800' ") - else: - tdLog.info(" '2021-07-01 00:00:00.000+0800' failed ") + tdSql.query("select ts from tb7") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb8 using st tags (1) values ('2021-07-0100:00:00.000',8)") - res = tdSql.getResult("select * from tb8") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 8)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000' ") - else: - tdLog.info(" '2021-07-0100:00:00.000' failed ") + tdSql.query("select ts from tb8") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb9 using st tags (1) values ('2021-07-0100:00:00.000+0800',9)") - res = tdSql.getResult("select * from tb9") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 9)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0800' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+0800' failed ") + tdSql.query("select ts from tb9") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb10 using st tags (1) values ('2021-07-0100:00:00.000+08:00',10)") - res = tdSql.getResult("select * from tb10") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 0), 10)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+08:00' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+08:00' failed ") + tdSql.query("select ts from tb10") + tdSql.checkData(0, 0, "2021-07-01 00:00:00.000") tdSql.execute("insert into tb11 using st tags (1) values ('2021-07-0100:00:00.000+07:00',11)") - res = tdSql.getResult("select * from tb11") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 1, 0), 11)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07:00' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+07:00' failed ") + tdSql.query("select ts from tb11") + tdSql.checkData(0, 0, "2021-07-01 01:00:00.000") - tdSql.execute("insert into tb12 using st tags (1) values ('2021-07-0100:00:00.000+07:00',12)") - res = tdSql.getResult("select * from tb12") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 1, 0), 12)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+07' failed ") + tdSql.execute("insert into tb12 using st tags (1) values ('2021-07-0100:00:00.000+0700',12)") + tdSql.query("select ts from tb12") + tdSql.checkData(0, 0, "2021-07-01 01:00:00.000") tdSql.execute("insert into tb13 using st tags (1) values ('2021-07-0100:00:00.000+07:12',13)") - res = tdSql.getResult("select * from tb13") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 48), 13)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+07:12' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+07:12' failed ") + tdSql.query("select ts from tb13") + tdSql.checkData(0, 0, "2021-07-01 00:48:00.000") tdSql.execute("insert into tb14 using st tags (1) values ('2021-07-0100:00:00.000+712',14)") - res = tdSql.getResult("select * from tb14") - print(res) - if res == [(datetime.datetime(2021, 6, 28, 8, 58), 14)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+712' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+712' failed ") + tdSql.query("select ts from tb14") + tdSql.checkData(0, 0, "2021-06-28 08:58:00.000") tdSql.execute("insert into tb15 using st tags (1) values ('2021-07-0100:00:00.000Z',15)") - res = tdSql.getResult("select * from tb15") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 8, 0), 15)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000Z' ") - else: - tdLog.info(" '2021-07-0100:00:00.000Z' failed ") + tdSql.query("select ts from tb15") + tdSql.checkData(0, 0, "2021-07-01 08:00:00.000") tdSql.execute("insert into tb16 using st tags (1) values ('2021-7-1 00:00:00.000Z',16)") - res = tdSql.getResult("select * from tb16") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 8, 0), 16)]: - tdLog.info("time format is check pass : '2021-7-1 00:00:00.000Z' ") - else: - tdLog.info(" '2021-7-1 00:00:00.000Z' failed ") + tdSql.query("select ts from tb16") + tdSql.checkData(0, 0, "2021-07-01 08:00:00.000") tdSql.execute("insert into tb17 using st tags (1) values ('2021-07-0100:00:00.000+0750',17)") - res = tdSql.getResult("select * from tb17") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 10), 17)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0750' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+0750' failed ") + tdSql.query("select ts from tb17") + tdSql.checkData(0, 0, "2021-07-01 00:10:00.000") tdSql.execute("insert into tb18 using st tags (1) values ('2021-07-0100:00:00.000+0752',18)") - res = tdSql.getResult("select * from tb18") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 8), 18)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+0752' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+0752' failed ") + tdSql.query("select ts from tb18") + tdSql.checkData(0, 0, "2021-07-01 00:08:00.000") tdSql.execute("insert into tb19 using st tags (1) values ('2021-07-0100:00:00.000+075',19)") - res = tdSql.getResult("select * from tb19") - print(res) - if res == [(datetime.datetime(2021, 7, 1, 0, 55), 19)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+075' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+075' failed ") + tdSql.query("select ts from tb19") + tdSql.checkData(0, 0, "2021-07-01 00:55:00.000") tdSql.execute("insert into tb20 using st tags (1) values ('2021-07-0100:00:00.000+75',20)") - res = tdSql.getResult("select * from tb20") - print(res) - if res == [(datetime.datetime(2021, 6, 28, 5, 0), 20)]: - tdLog.info("time format is check pass : '2021-07-0100:00:00.000+75' ") - else: - tdLog.info(" '2021-07-0100:00:00.000+75' failed ") + tdSql.query("select ts from tb20") + tdSql.checkData(0, 0, "2021-06-28 05:00:00.000") + + tdSql.execute("insert into tb21 using st tags (1) values ('2021-7-1 1:1:1.234+075',21)") + tdSql.query("select ts from tb21") + tdSql.checkData(0, 0, "2021-07-01 01:56:01.234") + + tdSql.execute("insert into tb22 using st tags (1) values ('2021-7-1T1:1:1.234+075',22)") + tdSql.query("select ts from tb22") + tdSql.checkData(0, 0, "2021-07-01 01:56:01.234") + + tdSql.execute("insert into tb23 using st tags (1) values ('2021-7-131:1:1.234+075',22)") + tdSql.query("select ts from tb23") + tdSql.checkData(0, 0, "2021-07-13 01:56:01.234") tdSql.error("insert into tberror using st tags (1) values ('20210701 00:00:00.000+0800',0)") @@ -230,16 +158,11 @@ class TDTestCase: tdSql.error("insert into tberror using st tags (1) values ('202171 00:00:00.000+0800',0)") tdSql.error("insert into tberror using st tags (1) values ('2021 07 01 00:00:00.000+0800',0)") tdSql.error("insert into tberror using st tags (1) values ('2021 -07-0100:00:00.000+0800',0)") - - + tdSql.error("insert into tberror using st tags (1) values ('2021-7-11:1:1.234+075',0)") + os.system("rm -rf ./TimeZone/*.py.sql") - - - - - diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index bc410107e6..fb609430c9 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -29,6 +29,10 @@ python3 ./test.py -f insert/in_function.py python3 ./test.py -f insert/modify_column.py python3 ./test.py -f insert/line_insert.py +# timezone + +python3 ./test.py -f TimeZone/TestCaseTimeZone.py + #table python3 ./test.py -f table/alter_wal0.py python3 ./test.py -f table/column_name.py