From 67a1df626901ea66f7f1aebc12a05d3753dd2c24 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 9 Dec 2024 16:15:48 +0800 Subject: [PATCH] feat:[TD-32642] fix problems reviewd --- include/common/tmsg.h | 2 +- include/libs/command/command.h | 2 +- include/libs/nodes/querynodes.h | 1 + include/libs/planner/planner.h | 1 + source/client/inc/clientInt.h | 3 ++ source/client/src/clientEnv.c | 1 + source/client/src/clientImpl.c | 6 ++-- source/client/src/clientMain.c | 48 ++++++++++++------------- source/common/src/ttime.c | 28 +++++++-------- source/libs/command/src/command.c | 22 ++++++------ source/libs/parser/src/parAstCreater.c | 1 + source/libs/parser/src/parTranslater.c | 16 +++++---- source/libs/planner/src/planOptimizer.c | 40 +++++++++++---------- source/os/src/osTime.c | 2 ++ 14 files changed, 92 insertions(+), 81 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 056f31c583..7abf38fdcf 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1242,7 +1242,7 @@ typedef struct { } STsBufInfo; typedef struct { - int32_t tz; // query client timezone + void* timezone; char intervalUnit; char slidingUnit; char offsetUnit; diff --git a/include/libs/command/command.h b/include/libs/command/command.h index 9fb2ca40b9..dd2441a115 100644 --- a/include/libs/command/command.h +++ b/include/libs/command/command.h @@ -22,7 +22,7 @@ typedef struct SExplainCtx SExplainCtx; -int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode *pStmt, SRetrieveTableRsp **pRsp, int8_t biMode); +int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode *pStmt, SRetrieveTableRsp **pRsp, int8_t biMode, void* charsetCxt); int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp); int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs); diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 129f8806bf..5e4e8b6292 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -338,6 +338,7 @@ typedef struct SIntervalWindowNode { SNode* pSliding; // SValueNode SNode* pFill; STimeWindow timeRange; + void* timezone; } SIntervalWindowNode; typedef struct SEventWindowNode { diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index a78fc4d2a6..92417bbf32 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -46,6 +46,7 @@ typedef struct SPlanContext { int64_t allocatorId; bool destHasPrimaryKey; bool sourceHasPrimaryKey; + void* timezone; } SPlanContext; // Create the physical plan for the query, according to the AST. diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 300ea1e72b..bc80cb2673 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -447,6 +447,9 @@ void stopAllQueries(SRequestObj* pRequest); void doRequestCallback(SRequestObj* pRequest, int32_t code); void freeQueryParam(SSyncQueryParam* param); +int32_t tzInit(); +void tzCleanup(); + #ifdef TD_ENTERPRISE int32_t clientParseSqlImpl(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effeciveUser, SParseSqlRes* pRes); diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 7334d1702e..5313a4f46e 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -976,6 +976,7 @@ void taos_init_imp(void) { tscError("failed to init conv"); return; } + ENV_ERR_RET(tzInit(), "failed to init timezone"); ENV_ERR_RET(monitorInit(), "failed to init monitor"); ENV_ERR_RET(rpcInit(), "failed to init rpc"); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 18298c5a20..e5e304bc79 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -333,7 +333,7 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { SRetrieveTableRsp* pRsp = NULL; int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode); - int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode); + int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode, pRequest->pTscObj->optionInfo.charsetCxt); if (TSDB_CODE_SUCCESS == code && NULL != pRsp) { code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4); } @@ -371,7 +371,7 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { } int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, - atomic_load_8(&pRequest->pTscObj->biMode)); + atomic_load_8(&pRequest->pTscObj->biMode), pRequest->pTscObj->optionInfo.charsetCxt); if (TSDB_CODE_SUCCESS == code && NULL != pRsp) { code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4); } @@ -509,6 +509,7 @@ int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArra .pMsg = pRequest->msgBuf, .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, .pUser = pRequest->pTscObj->user, + .timezone = pRequest->pTscObj->optionInfo.timezone, .sysInfo = pRequest->pTscObj->sysInfo}; return qCreateQueryPlan(&cxt, pPlan, pNodeList); @@ -1363,6 +1364,7 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, .pUser = pRequest->pTscObj->user, .sysInfo = pRequest->pTscObj->sysInfo, + .timezone = pRequest->pTscObj->optionInfo.timezone, .allocatorId = pRequest->allocatorRefId}; if (TSDB_CODE_SUCCESS == code) { code = qCreateQueryPlan(&cxt, &pDag, pMnodeList); diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index a6dba45357..5f106327f2 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -46,7 +46,6 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) { for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) { if (i % 1000 == 0) { - tscInfo("haven't acquire lock after spin %d times.", i); (void)sched_yield(); } } @@ -62,32 +61,27 @@ static void freeTz(void *p){ tzfree(tz); } +int32_t tzInit(){ + pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK); + if (pTimezoneMap == NULL) { + return terrno; + } + taosHashSetFreeFp(pTimezoneMap, freeTz); + + pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK); + if (pTimezoneNameMap == NULL) { + return terrno; + } + return 0; +} + +void tzCleanup(){ + taosHashCleanup(pTimezoneMap); + taosHashCleanup(pTimezoneNameMap); +} + static timezone_t setConnnectionTz(const char* val){ timezone_t tz = NULL; - static int32_t lock_c = 0; - - for (int i = 1; atomic_val_compare_exchange_32(&lock_c, 0, 1) != 0; ++i) { - if (i % 1000 == 0) { - tscInfo("haven't acquire lock after spin %d times.", i); - (void)sched_yield(); - } - } - - if (pTimezoneMap == NULL){ - pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK); - if (pTimezoneMap == NULL) { - goto END; - } - taosHashSetFreeFp(pTimezoneMap, freeTz); - } - - if (pTimezoneNameMap == NULL){ - pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK); - if (pTimezoneNameMap == NULL) { - goto END; - } - } - timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val)); if (tmp != NULL && *tmp != NULL){ tz = *tmp; @@ -107,8 +101,10 @@ static timezone_t setConnnectionTz(const char* val){ } int32_t code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t)); if (code != 0){ + tscError("%s put timezone to tz map error:%d", __func__, code); tzfree(tz); tz = NULL; + goto END; } time_t tx1 = taosGetTimestampSec(); @@ -120,7 +116,6 @@ static timezone_t setConnnectionTz(const char* val){ } END: - atomic_store_32(&lock_c, 0); return tz; } #endif @@ -242,6 +237,7 @@ void taos_cleanup(void) { tscWarn("failed to cleanup task queue"); } + tzCleanup(); tmqMgmtClose(); int32_t id = clientReqRefPool; diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index 0ce5e80b29..9746fea034 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -751,7 +751,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { start /= (int64_t)(TSDB_TICK_PER_SECOND(precision)); struct tm tm; time_t tt = (time_t)start; - if (taosLocalTime(&tt, &tm, NULL, 0, NULL) == NULL){ + if (taosLocalTime(&tt, &tm, NULL, 0, pInterval->timezone) == NULL){ uError("%s failed to convert time to local time, code:%d", __FUNCTION__, errno); return ts; } @@ -770,7 +770,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { tm.tm_mon = mon % 12; } - tt = taosMktime(&tm, NULL); + tt = taosMktime(&tm, pInterval->timezone); if (tt == -1){ uError("%s failed to convert local time to time, code:%d", __FUNCTION__, errno); return ts; @@ -789,12 +789,12 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { start = news; if (news <= ts) { int64_t prev = news; - int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; if (newe < ts) { // move towards the greater endpoint while (newe < ts && news < ts) { news += pInterval->sliding; - newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; } prev = news; @@ -802,7 +802,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { while (newe >= ts) { prev = news; news -= pInterval->sliding; - newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; } } @@ -824,8 +824,6 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { // see // https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019 int64_t timezone = _timezone; - int32_t daylight = _daylight; - char** tzname = _tzname; #endif start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision)); @@ -835,7 +833,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { // not enough time range if (start < 0 || INT64_MAX - start > pInterval->interval - 1) { - end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; while (end < ts) { // move forward to the correct time window start += pInterval->sliding; @@ -854,15 +852,15 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { if (pInterval->offset > 0) { // try to move current window to the left-hande-side, due to the offset effect. - int64_t newe = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + int64_t newe = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; int64_t slidingStart = start; while (newe >= ts) { start = slidingStart; - slidingStart = taosTimeAdd(slidingStart, -pInterval->sliding, pInterval->slidingUnit, precision, NULL); - int64_t news = taosTimeAdd(slidingStart, pInterval->offset, pInterval->offsetUnit, precision, NULL); - newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, NULL) - 1; + slidingStart = taosTimeAdd(slidingStart, -pInterval->sliding, pInterval->slidingUnit, precision, pInterval->timezone); + int64_t news = taosTimeAdd(slidingStart, pInterval->offset, pInterval->offsetUnit, precision, pInterval->timezone); + newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1; } - start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision, NULL); + start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision, pInterval->timezone); } return start; @@ -870,7 +868,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) { // used together with taosTimeTruncate. when offset is great than zero, slide-start/slide-end is the anchor point int64_t taosTimeGetIntervalEnd(int64_t intervalStart, const SInterval* pInterval) { - return taosTimeAdd(intervalStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1; + return taosTimeAdd(intervalStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision, pInterval->timezone) - 1; } void calcIntervalAutoOffset(SInterval* interval) { @@ -889,7 +887,7 @@ void calcIntervalAutoOffset(SInterval* interval) { TSKEY news = start; while (news <= skey) { start = news; - news = taosTimeAdd(start, interval->sliding, interval->slidingUnit, interval->precision, NULL); + news = taosTimeAdd(start, interval->sliding, interval->slidingUnit, interval->precision, interval->timezone); if (news < start) { // overflow happens uError("%s failed and skip, skey [%" PRId64 "], inter[%" PRId64 "(%c)], slid[%" PRId64 "(%c)], precision[%d]", diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index b86621738d..88c3d7307b 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -573,7 +573,7 @@ static void appendTagNameFields(char* buf, int32_t* len, STableCfg* pCfg) { } } -static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) { +static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg, void* charsetCxt) { int32_t code = TSDB_CODE_SUCCESS; SArray* pTagVals = NULL; STag* pTag = (STag*)pCfg->pTags; @@ -585,7 +585,7 @@ static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) { if (tTagIsJson(pTag)) { char* pJson = NULL; - parseTagDatatoJson(pTag, &pJson, NULL); + parseTagDatatoJson(pTag, &pJson, charsetCxt); if (NULL == pJson) { qError("failed to parse tag to json, pJson is NULL"); return terrno; @@ -726,7 +726,7 @@ static void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STab } } -static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg) { +static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg, void* charsetCxt) { int32_t code = TSDB_CODE_SUCCESS; QRY_ERR_RET(blockDataEnsureCapacity(pBlock, 1)); pBlock->info.rows = 1; @@ -760,7 +760,7 @@ static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* p appendTagNameFields(buf2, &len, pCfg); len += tsnprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ") TAGS ("); - code = appendTagValues(buf2, &len, pCfg); + code = appendTagValues(buf2, &len, pCfg, charsetCxt); TAOS_CHECK_ERRNO(code); len += snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")"); @@ -817,11 +817,11 @@ static int32_t setCreateViewResultIntoDataBlock(SSDataBlock* pBlock, SShowCreate return code; } -static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) { +static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) { SSDataBlock* pBlock = NULL; int32_t code = buildCreateTbResultDataBlock(&pBlock); if (TSDB_CODE_SUCCESS == code) { - code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg); + code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg, charsetCxt); } if (TSDB_CODE_SUCCESS == code) { code = buildRetrieveTableRsp(pBlock, SHOW_CREATE_TB_RESULT_COLS, pRsp); @@ -830,14 +830,14 @@ static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRs return code; } -static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) { +static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) { STableCfg* pCfg = (STableCfg*)pStmt->pTableCfg; if (TSDB_SUPER_TABLE != pCfg->tableType) { terrno = TSDB_CODE_TSC_NOT_STABLE_ERROR; return terrno; } - return execShowCreateTable(pStmt, pRsp); + return execShowCreateTable(pStmt, pRsp, charsetCxt); } static int32_t execAlterCmd(char* cmd, char* value, bool* processed) { @@ -1058,7 +1058,7 @@ static int32_t execShowCreateView(SShowCreateViewStmt* pStmt, SRetrieveTableRsp* return code; } -int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp** pRsp, int8_t biMode) { +int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp** pRsp, int8_t biMode, void* charsetCxt) { switch (nodeType(pStmt)) { case QUERY_NODE_DESCRIBE_STMT: return execDescribe(sysInfoUser, pStmt, pRsp, biMode); @@ -1067,9 +1067,9 @@ int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieve case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp); case QUERY_NODE_SHOW_CREATE_TABLE_STMT: - return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp); + return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt); case QUERY_NODE_SHOW_CREATE_STABLE_STMT: - return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp); + return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt); case QUERY_NODE_SHOW_CREATE_VIEW_STMT: return execShowCreateView((SShowCreateViewStmt*)pStmt, pRsp); case QUERY_NODE_ALTER_LOCAL_STMT: diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index f8d77be75a..022dcea462 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1411,6 +1411,7 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode interval->pSliding = pSliding; interval->pFill = pFill; interval->timeRange = TSWINDOW_INITIALIZER; + interval->timezone = pCxt->pQueryCxt->timezone; return (SNode*)interval; _err: nodesDestroyNode((SNode*)interval); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 3896a76877..035d114252 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5935,6 +5935,7 @@ void tryCalcIntervalAutoOffset(SIntervalWindowNode *pInterval) { .slidingUnit = (pSliding != NULL) ? pSliding->unit : pInter->unit, .offset = pOffset->datum.i, .precision = precision, + .timezone = pInterval->timezone, .timeRange = pInterval->timeRange}; /** @@ -10108,7 +10109,7 @@ static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt return code; } -int32_t createIntervalFromCreateSmaIndexStmt(SCreateIndexStmt* pStmt, SInterval* pInterval) { +int32_t createIntervalFromCreateSmaIndexStmt(SCreateIndexStmt* pStmt, SInterval* pInterval, void* timezone) { pInterval->interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit; pInterval->offset = NULL != pStmt->pOptions->pOffset ? ((SValueNode*)pStmt->pOptions->pOffset)->datum.i : 0; @@ -10121,6 +10122,7 @@ int32_t createIntervalFromCreateSmaIndexStmt(SCreateIndexStmt* pStmt, SInterval* parserError("%s failed for invalid interval offset %" PRId64, __func__, pInterval->offset); return TSDB_CODE_INVALID_PARA; } + pInterval->timezone = timezone; return TSDB_CODE_SUCCESS; } @@ -10132,7 +10134,7 @@ int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, SS STranslateContext pCxt = {0}; code = initTranslateContext(pParseCxt, NULL, &pCxt); if (TSDB_CODE_SUCCESS == code) { - code = createIntervalFromCreateSmaIndexStmt(pStmt, &interval); + code = createIntervalFromCreateSmaIndexStmt(pStmt, &interval, pParseCxt->timezone); } if (TSDB_CODE_SUCCESS == code) { @@ -11973,6 +11975,7 @@ static int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->unit : pInterval->intervalUnit); pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision; pInterval->timeRange = pWindow->timeRange; + pInterval->timezone = pWindow->timezone; return code; } @@ -12022,7 +12025,7 @@ int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, SSDa if (TSDB_CODE_SUCCESS == code) { if (interval.interval > 0) { pStmt->pReq->lastTs = taosTimeAdd(taosTimeTruncate(lastTs, &interval), interval.interval, interval.intervalUnit, - interval.precision, NULL); + interval.precision, pParseCxt->timezone); } else { pStmt->pReq->lastTs = lastTs + 1; // start key of the next time window } @@ -12893,7 +12896,7 @@ static int32_t translateCreateTSMA(STranslateContext* pCxt, SCreateTSMAStmt* pSt return code; } -static int32_t buildIntervalForCreateTSMA(SCreateTSMAStmt* pStmt, SInterval* pInterval) { +static int32_t buildIntervalForCreateTSMA(SCreateTSMAStmt* pStmt, SInterval* pInterval, void* timezone) { int32_t code = TSDB_CODE_SUCCESS; pInterval->interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit; @@ -12901,6 +12904,7 @@ static int32_t buildIntervalForCreateTSMA(SCreateTSMAStmt* pStmt, SInterval* pIn pInterval->sliding = pInterval->interval; pInterval->slidingUnit = pInterval->intervalUnit; pInterval->precision = pStmt->pOptions->tsPrecision; + pInterval->timezone = timezone; return code; } @@ -12912,7 +12916,7 @@ int32_t translatePostCreateTSMA(SParseContext* pParseCxt, SQuery* pQuery, SSData int32_t code = initTranslateContext(pParseCxt, NULL, &cxt); if (TSDB_CODE_SUCCESS == code) { - code = buildIntervalForCreateTSMA(pStmt, &interval); + code = buildIntervalForCreateTSMA(pStmt, &interval, pParseCxt->timezone); } if (TSDB_CODE_SUCCESS == code) { @@ -12922,7 +12926,7 @@ int32_t translatePostCreateTSMA(SParseContext* pParseCxt, SQuery* pQuery, SSData if (TSDB_CODE_SUCCESS == code) { if (interval.interval > 0) { pStmt->pReq->lastTs = taosTimeAdd(taosTimeTruncate(lastTs, &interval), interval.interval, interval.intervalUnit, - interval.precision, NULL); + interval.precision, pParseCxt->timezone); } else { pStmt->pReq->lastTs = lastTs + 1; // start key of the next time window } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 4a8df98b8b..8bcd2a9619 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2928,7 +2928,7 @@ static int32_t smaIndexOptCreateSmaScan(SScanLogicNode* pScan, STableIndexInfo* return TSDB_CODE_SUCCESS; } -static bool smaIndexOptEqualInterval(SScanLogicNode* pScan, SWindowLogicNode* pWindow, STableIndexInfo* pIndex) { +static bool smaIndexOptEqualInterval(SScanLogicNode* pScan, SWindowLogicNode* pWindow, STableIndexInfo* pIndex, void* tz) { if (pWindow->interval != pIndex->interval || pWindow->intervalUnit != pIndex->intervalUnit || pWindow->offset != pIndex->offset || pWindow->sliding != pIndex->sliding || pWindow->slidingUnit != pIndex->slidingUnit) { @@ -2941,6 +2941,7 @@ static bool smaIndexOptEqualInterval(SScanLogicNode* pScan, SWindowLogicNode* pW .offsetUnit = TIME_UNIT_MILLISECOND, .sliding = pIndex->sliding, .slidingUnit = pIndex->slidingUnit, + .timezone = tz, .precision = pScan->node.precision}; return (pScan->scanRange.skey == taosTimeTruncate(pScan->scanRange.skey, &interval)) && (pScan->scanRange.ekey + 1 == taosTimeTruncate(pScan->scanRange.ekey + 1, &interval)); @@ -3051,9 +3052,9 @@ static int32_t smaIndexOptCreateSmaCols(SNodeList* pFuncs, uint64_t tableId, SNo return code; } -static int32_t smaIndexOptCouldApplyIndex(SScanLogicNode* pScan, STableIndexInfo* pIndex, SNodeList** pCols) { +static int32_t smaIndexOptCouldApplyIndex(SScanLogicNode* pScan, STableIndexInfo* pIndex, SNodeList** pCols, void* tz) { SWindowLogicNode* pWindow = (SWindowLogicNode*)pScan->node.pParent; - if (!smaIndexOptEqualInterval(pScan, pWindow, pIndex)) { + if (!smaIndexOptEqualInterval(pScan, pWindow, pIndex, tz)) { return TSDB_CODE_SUCCESS; } SNodeList* pSmaFuncs = NULL; @@ -3084,7 +3085,7 @@ static int32_t smaIndexOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogi for (int32_t i = 0; i < nindexes; ++i) { STableIndexInfo* pIndex = taosArrayGet(pScan->pSmaIndexes, i); SNodeList* pSmaCols = NULL; - code = smaIndexOptCouldApplyIndex(pScan, pIndex, &pSmaCols); + code = smaIndexOptCouldApplyIndex(pScan, pIndex, &pSmaCols, pCxt->pPlanCxt->timezone); if (TSDB_CODE_SUCCESS == code && NULL != pSmaCols) { code = smaIndexOptApplyIndex(pLogicSubplan, pScan, pIndex, pSmaCols); pCxt->optimized = true; @@ -6773,7 +6774,7 @@ typedef struct STSMAOptCtx { SNodeList** ppParentTsmaSubplans; } STSMAOptCtx; -static int32_t fillTSMAOptCtx(STSMAOptCtx* pTsmaOptCtx, SScanLogicNode* pScan) { +static int32_t fillTSMAOptCtx(STSMAOptCtx* pTsmaOptCtx, SScanLogicNode* pScan, void* tz) { int32_t code = 0; pTsmaOptCtx->pScan = pScan; pTsmaOptCtx->pParent = pScan->node.pParent; @@ -6793,7 +6794,7 @@ static int32_t fillTSMAOptCtx(STSMAOptCtx* pTsmaOptCtx, SScanLogicNode* pScan) { pTsmaOptCtx->queryInterval->sliding = pWindow->sliding; pTsmaOptCtx->queryInterval->slidingUnit = pWindow->slidingUnit; pTsmaOptCtx->queryInterval->precision = pWindow->node.precision; - pTsmaOptCtx->queryInterval->tz = taosGetLocalTimezoneOffset(); + pTsmaOptCtx->queryInterval->timezone = tz; pTsmaOptCtx->pAggFuncs = pWindow->pFuncs; pTsmaOptCtx->ppParentTsmaSubplans = &pWindow->pTsmaSubplans; } else { @@ -6984,7 +6985,7 @@ static int32_t tsmaInfoCompWithIntervalDesc(const void* pLeft, const void* pRigh return 0; } -static void tsmaOptInitIntervalFromTsma(SInterval* pInterval, const STableTSMAInfo* pTsma, int8_t precision) { +static void tsmaOptInitIntervalFromTsma(SInterval* pInterval, const STableTSMAInfo* pTsma, int8_t precision, void* tz) { pInterval->interval = pTsma->interval; pInterval->intervalUnit = pTsma->unit; pInterval->sliding = pTsma->interval; @@ -6992,15 +6993,16 @@ static void tsmaOptInitIntervalFromTsma(SInterval* pInterval, const STableTSMAIn pInterval->offset = 0; pInterval->offsetUnit = pTsma->unit; pInterval->precision = precision; + pInterval->timezone = tz; } static const STSMAOptUsefulTsma* tsmaOptFindUsefulTsma(const SArray* pUsefulTsmas, int32_t startIdx, int64_t startAlignInterval, int64_t endAlignInterval, - int8_t precision) { + int8_t precision, void* tz) { SInterval tsmaInterval; for (int32_t i = startIdx; i < pUsefulTsmas->size; ++i) { const STSMAOptUsefulTsma* pUsefulTsma = taosArrayGet(pUsefulTsmas, i); - tsmaOptInitIntervalFromTsma(&tsmaInterval, pUsefulTsma->pTsma, precision); + tsmaOptInitIntervalFromTsma(&tsmaInterval, pUsefulTsma->pTsma, precision, tz); if (taosTimeTruncate(startAlignInterval, &tsmaInterval) == startAlignInterval && taosTimeTruncate(endAlignInterval, &tsmaInterval) == endAlignInterval) { return pUsefulTsma; @@ -7009,7 +7011,7 @@ static const STSMAOptUsefulTsma* tsmaOptFindUsefulTsma(const SArray* pUsefulTsma return NULL; } -static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* pScanRange) { +static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* pScanRange, void* tz) { bool needTailWindow = false; bool isSkeyAlignedWithTsma = true, isEkeyAlignedWithTsma = true; int32_t code = 0; @@ -7025,17 +7027,17 @@ static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* if (pScanRange->ekey <= pScanRange->skey) return code; if (!pInterval) { - tsmaOptInitIntervalFromTsma(&interval, pTsma, pTsmaOptCtx->precision); + tsmaOptInitIntervalFromTsma(&interval, pTsma, pTsmaOptCtx->precision, tz); pInterval = &interval; } - tsmaOptInitIntervalFromTsma(&tsmaInterval, pTsma, pTsmaOptCtx->precision); + tsmaOptInitIntervalFromTsma(&tsmaInterval, pTsma, pTsmaOptCtx->precision, tz); // check for head windows if (pScanRange->skey != TSKEY_MIN) { startOfSkeyFirstWin = taosTimeTruncate(pScanRange->skey, pInterval); endOfSkeyFirstWin = - taosTimeAdd(startOfSkeyFirstWin, pInterval->interval, pInterval->intervalUnit, pTsmaOptCtx->precision, NULL); + taosTimeAdd(startOfSkeyFirstWin, pInterval->interval, pInterval->intervalUnit, pTsmaOptCtx->precision, tz); isSkeyAlignedWithTsma = taosTimeTruncate(pScanRange->skey, &tsmaInterval) == pScanRange->skey; } else { endOfSkeyFirstWin = TSKEY_MIN; @@ -7045,7 +7047,7 @@ static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* if (pScanRange->ekey != TSKEY_MAX) { startOfEkeyFirstWin = taosTimeTruncate(pScanRange->ekey, pInterval); endOfEkeyFirstWin = - taosTimeAdd(startOfEkeyFirstWin, pInterval->interval, pInterval->intervalUnit, pTsmaOptCtx->precision, NULL); + taosTimeAdd(startOfEkeyFirstWin, pInterval->interval, pInterval->intervalUnit, pTsmaOptCtx->precision, tz); isEkeyAlignedWithTsma = taosTimeTruncate(pScanRange->ekey + 1, &tsmaInterval) == (pScanRange->ekey + 1); if (startOfEkeyFirstWin > startOfSkeyFirstWin) { needTailWindow = true; @@ -7056,9 +7058,9 @@ static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* if (!isSkeyAlignedWithTsma) { scanRange.ekey = TMIN( scanRange.ekey, - taosTimeAdd(startOfSkeyFirstWin, pInterval->interval * 1, pInterval->intervalUnit, pTsmaOptCtx->precision, NULL) - 1); + taosTimeAdd(startOfSkeyFirstWin, pInterval->interval * 1, pInterval->intervalUnit, pTsmaOptCtx->precision, tz) - 1); const STSMAOptUsefulTsma* pTsmaFound = - tsmaOptFindUsefulTsma(pTsmaOptCtx->pUsefulTsmas, 1, scanRange.skey, scanRange.ekey + 1, pTsmaOptCtx->precision); + tsmaOptFindUsefulTsma(pTsmaOptCtx->pUsefulTsmas, 1, scanRange.skey, scanRange.ekey + 1, pTsmaOptCtx->precision, tz); STSMAOptUsefulTsma usefulTsma = {.pTsma = pTsmaFound ? pTsmaFound->pTsma : NULL, .scanRange = scanRange, .pTsmaScanCols = pTsmaFound ? pTsmaFound->pTsmaScanCols : NULL}; @@ -7083,7 +7085,7 @@ static int32_t tsmaOptSplitWindows(STSMAOptCtx* pTsmaOptCtx, const STimeWindow* scanRange.ekey = pScanRange->ekey; const STSMAOptUsefulTsma* pTsmaFound = tsmaOptFindUsefulTsma(pTsmaOptCtx->pUsefulTsmas, 1, scanRange.skey - startOfEkeyFirstWin, - scanRange.ekey + 1 - startOfEkeyFirstWin, pTsmaOptCtx->precision); + scanRange.ekey + 1 - startOfEkeyFirstWin, pTsmaOptCtx->precision, tz); STSMAOptUsefulTsma usefulTsma = {.pTsma = pTsmaFound ? pTsmaFound->pTsma : NULL, .scanRange = scanRange, .pTsmaScanCols = pTsmaFound ? pTsmaFound->pTsmaScanCols : NULL}; @@ -7522,7 +7524,7 @@ static int32_t tsmaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan SLogicNode* pRootNode = getLogicNodeRootNode((SLogicNode*)pScan); if (getOptHint(pRootNode->pHint, HINT_SKIP_TSMA)) return code; - code = fillTSMAOptCtx(&tsmaOptCtx, pScan); + code = fillTSMAOptCtx(&tsmaOptCtx, pScan, pCxt->pPlanCxt->timezone); if (code == TSDB_CODE_SUCCESS) { // 1. extract useful tsmas code = tsmaOptFilterTsmas(&tsmaOptCtx); @@ -7531,7 +7533,7 @@ static int32_t tsmaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan // 2. sort useful tsmas with interval taosArraySort(tsmaOptCtx.pUsefulTsmas, tsmaInfoCompWithIntervalDesc); // 3. split windows - code = tsmaOptSplitWindows(&tsmaOptCtx, tsmaOptCtx.pTimeRange); + code = tsmaOptSplitWindows(&tsmaOptCtx, tsmaOptCtx.pTimeRange, pCxt->pPlanCxt->timezone); if (TSDB_CODE_SUCCESS == code && tsmaOptIsUsingTsmas(&tsmaOptCtx)) { // 4. create logic plan code = tsmaOptGeneratePlan(&tsmaOptCtx); diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index ff05bcef19..29cbcaeb2c 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -445,6 +445,7 @@ time_t taosMktime(struct tm *timep, timezone_t tz) { if (r == (time_t)-1) { terrno = TAOS_SYSTEM_ERROR(errno); } + timezone = -timep->tm_gmtoff; return r; #endif } @@ -533,6 +534,7 @@ struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf, int3 if (res == NULL && buf != NULL) { (void)snprintf(buf, bufSize, "NaN"); } + timezone = -result->tm_gmtoff; return res; #endif }