From 65fe54c4f62e9865580d1b4657b94421f2d7aee5 Mon Sep 17 00:00:00 2001 From: dengyihao Date: Fri, 12 Jun 2020 19:39:17 +0800 Subject: [PATCH] fixbug TD-327 --- src/client/src/tscParseInsert.c | 2 +- src/client/src/tscSQLParser.c | 4 ++-- src/common/inc/tglobal.h | 1 + src/common/src/tglobal.c | 1 + src/common/src/ttimezone.c | 1 + src/util/inc/ttime.h | 2 +- src/util/src/ttime.c | 40 ++++++++++++++++++++++++++++----- 7 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index c4749e4611..afd1a3e8c8 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -97,7 +97,7 @@ int tsParseTime(SSQLToken *pToken, int64_t *time, char **next, char *error, int1 useconds = str2int64(pToken->z); } else { // strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm); - if (taosParseTime(pToken->z, time, pToken->n, timePrec) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { return tscInvalidSQLErrMsg(error, "invalid timestamp format", pToken->z); } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 8e5a439431..7605fae5e5 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -138,7 +138,7 @@ static int setColumnFilterInfoForTimestamp(SQueryInfo* pQueryInfo, tVariant* pVa STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); if (seg != NULL) { - if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pVar->pz, &time, pVar->nLen, tinfo.precision, tsDaylight) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(pQueryInfo->msg, msg); } } else { @@ -3950,7 +3950,7 @@ int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t t char* seg = strnchr(pRight->val.pz, '-', pRight->val.nLen, false); if (seg != NULL) { - if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO) == TSDB_CODE_SUCCESS) { + if (taosParseTime(pRight->val.pz, &val, pRight->val.nLen, TSDB_TIME_PRECISION_MICRO, tsDaylight) == TSDB_CODE_SUCCESS) { parsed = true; } else { return TSDB_CODE_TSC_INVALID_SQL; diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 53d821b3d8..eaceea468b 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -170,6 +170,7 @@ extern char gitinfo[]; extern char gitinfoOfInternal[]; extern char buildinfo[]; +extern int8_t tsDaylight; extern char tsTimezone[64]; extern char tsLocale[64]; extern char tsCharset[64]; // default encode string diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 86fc6deb1b..e80597ca95 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -198,6 +198,7 @@ char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log"; char tsInternalPass[] = "secretkey"; int32_t tsMonitorInterval = 30; // seconds +int8_t tsDaylight = 0; char tsTimezone[64] = {0}; char tsLocale[TSDB_LOCALE_LEN] = {0}; char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string diff --git a/src/common/src/ttimezone.c b/src/common/src/ttimezone.c index 0e8e1316b3..ae6ffea59a 100644 --- a/src/common/src/ttimezone.c +++ b/src/common/src/ttimezone.c @@ -58,6 +58,7 @@ void tsSetTimeZone() { * (BST, +0100) */ sprintf(tsTimezone, "(%s, %s%02d00)", tzname[daylight], tz >= 0 ? "+" : "-", abs(tz)); + tsDaylight = daylight; uPrint("timezone format changed to %s", tsTimezone); } diff --git a/src/util/inc/ttime.h b/src/util/inc/ttime.h index 61df65f345..576c9a51f6 100644 --- a/src/util/inc/ttime.h +++ b/src/util/inc/ttime.h @@ -56,7 +56,7 @@ static FORCE_INLINE int64_t taosGetTimestamp(int32_t precision) { int32_t getTimestampInUsFromStr(char* token, int32_t tokenlen, int64_t* ts); -int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec); +int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t dayligth); void deltaToUtcInitOnce(); #ifdef __cplusplus diff --git a/src/util/src/ttime.c b/src/util/src/ttime.c index 8355ed9dc1..4dd6360752 100644 --- a/src/util/src/ttime.c +++ b/src/util/src/ttime.c @@ -24,7 +24,6 @@ #include "taosdef.h" #include "ttime.h" #include "tutil.h" - /* * mktime64 - Converts date to seconds. * Converts Gregorian date to seconds since 1970-01-01 00:00:00. @@ -119,15 +118,21 @@ static int month[12] = { 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 parseLocaltime(char* timestr, int64_t* time, int32_t timePrec); +static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec); + +static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = { + parseLocaltime, + parseLocaltimeWithDst +}; int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } -int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec) { +int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t daylight) { /* parse datatime string in with tz */ if (strnchr(timestr, 'T', len, false) != NULL) { return parseTimeWithTz(timestr, time, timePrec); } else { - return parseLocaltime(timestr, time, timePrec); + return (*parseLocaltimeFp[daylight])(timestr, time, timePrec); } } @@ -304,9 +309,6 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) { return -1; } - /* mktime will be affected by TZ, set by using taos_options */ - //int64_t seconds = mktime(&tm); - //int64_t seconds = (int64_t)user_mktime(&tm); int64_t seconds = user_mktime64(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); int64_t fraction = 0; @@ -324,6 +326,32 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) { return 0; } +int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec) { + *time = 0; + struct tm tm = {0}; + tm.tm_isdst = -1; + + char* str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm); + if (str == NULL) { + return -1; + } + + /* mktime will be affected by TZ, set by using taos_options */ + int64_t seconds = mktime(&tm); + + int64_t fraction = 0; + + if (*str == '.') { + /* parse the second fraction part */ + if ((fraction = parseFraction(str + 1, &str, timePrec)) < 0) { + return -1; + } + } + + int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : 1000000; + *time = factor * seconds + fraction; + return 0; +} static int32_t getTimestampInUsFromStrImpl(int64_t val, char unit, int64_t* result) { *result = val; -- GitLab