From b4c2085ddcc06faff5dec0a3ac77f8af398966a5 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 8 Jun 2023 16:32:35 +0800 Subject: [PATCH 01/21] feat: add pipeline processing for timeslice operator --- source/libs/executor/src/timesliceoperator.c | 112 +++++++++++++------ 1 file changed, 80 insertions(+), 32 deletions(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 3e4055876d..65e3e75bce 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -44,6 +44,7 @@ typedef struct STimeSliceOperatorInfo { uint64_t groupId; SGroupKeys* pPrevGroupKey; SSDataBlock* pNextGroupRes; + SSDataBlock* pRemainRes; // save block unfinished processing } STimeSliceOperatorInfo; static void destroyTimeSliceOperatorInfo(void* param); @@ -641,6 +642,25 @@ static int32_t resetKeeperInfo(STimeSliceOperatorInfo* pInfo) { return TSDB_CODE_SUCCESS; } +static bool checkThresholdReached(STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, int32_t threshold) { + SSDataBlock* pResBlock = pSliceInfo->pRes; + + if (pResBlock->info.rows > threshold) { + pSliceInfo->pRemainRes = pBlock; + return true; + } + + return false; +} + +static bool checkWindowBoundReached(STimeSliceOperatorInfo* pSliceInfo) { + if (pSliceInfo->current > pSliceInfo->win.ekey) { + return true; + } + + return false; +} + static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, bool ignoreNull) { SSDataBlock* pResBlock = pSliceInfo->pRes; @@ -658,10 +678,12 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkNullRow(&pOperator->exprSupp, pBlock, i, ignoreNull)) { continue; } - - if (pSliceInfo->current > pSliceInfo->win.ekey) { + if (checkWindowBoundReached(pSliceInfo)) { break; } + if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + return; + } if (ts == pSliceInfo->current) { addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); @@ -671,9 +693,13 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (pSliceInfo->current > pSliceInfo->win.ekey) { + + if (checkWindowBoundReached(pSliceInfo)) { break; } + if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + return; + } } else if (ts < pSliceInfo->current) { // in case of interpolation window starts and ends between two datapoints, fill(prev) need to interpolate doKeepPrevRows(pSliceInfo, pBlock, i); @@ -694,9 +720,12 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS } } - if (pSliceInfo->current > pSliceInfo->win.ekey) { + if (checkWindowBoundReached(pSliceInfo)) { break; } + if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + return; + } } else { // ignore current row, and do nothing } @@ -727,11 +756,19 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS } doKeepPrevRows(pSliceInfo, pBlock, i); - if (pSliceInfo->current > pSliceInfo->win.ekey) { + if (checkWindowBoundReached(pSliceInfo)) { break; } + if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + return; + } } } + + // if reached here, meaning block processing finished naturally, + // or interpolation reach window upper bound + pSliceInfo->pRemainRes = NULL; + } static void genInterpAfterDataBlock(STimeSliceOperatorInfo* pSliceInfo, SOperatorInfo* pOperator, int32_t index) { @@ -778,34 +815,54 @@ static void resetTimesliceInfo(STimeSliceOperatorInfo* pSliceInfo) { resetKeeperInfo(pSliceInfo); } +static void doHandleTimeslice(SOperatorInfo* pOperator, SSDataBlock* pBlock) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + STimeSliceOperatorInfo* pSliceInfo = pOperator->info; + SExprSupp* pSup = &pOperator->exprSupp; + bool ignoreNull = getIgoreNullRes(pSup); + int32_t order = TSDB_ORDER_ASC; + + int32_t code = initKeeperInfo(pSliceInfo, pBlock, &pOperator->exprSupp); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, code); + } + + if (pSliceInfo->scalarSup.pExprInfo != NULL) { + SExprSupp* pExprSup = &pSliceInfo->scalarSup; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); + doTimesliceImpl(pOperator, pSliceInfo, pBlock, pTaskInfo, ignoreNull); + copyPrevGroupKey(&pOperator->exprSupp, pSliceInfo->pPrevGroupKey, pBlock); +} + static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; STimeSliceOperatorInfo* pSliceInfo = pOperator->info; SSDataBlock* pResBlock = pSliceInfo->pRes; - SExprSupp* pSup = &pOperator->exprSupp; - bool ignoreNull = getIgoreNullRes(pSup); - int32_t order = TSDB_ORDER_ASC; - SInterval* pInterval = &pSliceInfo->interval; SOperatorInfo* downstream = pOperator->pDownstream[0]; - blockDataCleanup(pResBlock); while (1) { if (pSliceInfo->pNextGroupRes != NULL) { - setInputDataBlock(pSup, pSliceInfo->pNextGroupRes, order, MAIN_SCAN, true); - doTimesliceImpl(pOperator, pSliceInfo, pSliceInfo->pNextGroupRes, pTaskInfo, ignoreNull); - copyPrevGroupKey(&pOperator->exprSupp, pSliceInfo->pPrevGroupKey, pSliceInfo->pNextGroupRes); + doHandleTimeslice(pOperator, pSliceInfo->pNextGroupRes); + if (checkThresholdReached(pSliceInfo, pSliceInfo->pRemainRes, pOperator->resultInfo.threshold)) { + doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); + goto _finished; + } pSliceInfo->pNextGroupRes = NULL; } while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + SSDataBlock* pBlock = pSliceInfo->pRemainRes ? pSliceInfo->pRemainRes : downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { setOperatorCompleted(pOperator); break; @@ -821,21 +878,13 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } - if (pSliceInfo->scalarSup.pExprInfo != NULL) { - SExprSupp* pExprSup = &pSliceInfo->scalarSup; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + doHandleTimeslice(pOperator, pBlock); + if (checkThresholdReached(pSliceInfo, pSliceInfo->pRemainRes, pOperator->resultInfo.threshold)) { + doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); + goto _finished; } - - int32_t code = initKeeperInfo(pSliceInfo, pBlock, &pOperator->exprSupp); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, code); - } - - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); - doTimesliceImpl(pOperator, pSliceInfo, pBlock, pTaskInfo, ignoreNull); - copyPrevGroupKey(&pOperator->exprSupp, pSliceInfo->pPrevGroupKey, pBlock); } + // handling post work for a specific group // check if need to interpolate after last datablock // except for fill(next), fill(linear) @@ -848,11 +897,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // restore initial value for next group resetTimesliceInfo(pSliceInfo); - if (pResBlock->info.rows >= 4096) { - break; - } } +_finished: // restore the value setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); if (pResBlock->info.rows == 0) { @@ -908,6 +955,7 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->groupId = 0; pInfo->pPrevGroupKey = NULL; pInfo->pNextGroupRes = NULL; + pInfo->pRemainRes = NULL; if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; From 7ee05df7c6d9f66efbc1e254213f698414f69b37 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 8 Jun 2023 17:46:25 +0800 Subject: [PATCH 02/21] fix lastBlock remain ts not saved --- source/libs/executor/src/timesliceoperator.c | 39 +++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 65e3e75bce..1aa6027a1d 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -45,6 +45,7 @@ typedef struct STimeSliceOperatorInfo { SGroupKeys* pPrevGroupKey; SSDataBlock* pNextGroupRes; SSDataBlock* pRemainRes; // save block unfinished processing + int64_t remainTs; // the remaining timestamp in the block to be processed } STimeSliceOperatorInfo; static void destroyTimeSliceOperatorInfo(void* param); @@ -642,11 +643,9 @@ static int32_t resetKeeperInfo(STimeSliceOperatorInfo* pInfo) { return TSDB_CODE_SUCCESS; } -static bool checkThresholdReached(STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, int32_t threshold) { +static bool checkThresholdReached(STimeSliceOperatorInfo* pSliceInfo, int32_t threshold) { SSDataBlock* pResBlock = pSliceInfo->pRes; - if (pResBlock->info.rows > threshold) { - pSliceInfo->pRemainRes = pBlock; return true; } @@ -661,6 +660,16 @@ static bool checkWindowBoundReached(STimeSliceOperatorInfo* pSliceInfo) { return false; } +static void saveBlockStatus(STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, int32_t curIndex) { + SSDataBlock* pResBlock = pSliceInfo->pRes; + + SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); + if (curIndex < pBlock->info.rows - 1) { + pSliceInfo->pRemainRes = pBlock; + pSliceInfo->remainTs = *(int64_t*)colDataGetData(pTsCol, curIndex + 1); + } +} + static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, bool ignoreNull) { SSDataBlock* pResBlock = pSliceInfo->pRes; @@ -670,6 +679,12 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS for (int32_t i = 0; i < pBlock->info.rows; ++i) { int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); + // check if need to resume from the position of last unfinished block + if (pSliceInfo->pRemainRes != NULL && ts < pSliceInfo->remainTs && + pSliceInfo->current <= pSliceInfo->remainTs) { + continue; + } + // check for duplicate timestamps if (checkDuplicateTimestamps(pSliceInfo, pTsCol, i, pBlock->info.rows)) { T_LONG_JMP(pTaskInfo->env, TSDB_CODE_FUNC_DUP_TIMESTAMP); @@ -681,7 +696,8 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkWindowBoundReached(pSliceInfo)) { break; } - if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + saveBlockStatus(pSliceInfo, pBlock, i); return; } @@ -697,7 +713,8 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkWindowBoundReached(pSliceInfo)) { break; } - if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + saveBlockStatus(pSliceInfo, pBlock, i); return; } } else if (ts < pSliceInfo->current) { @@ -723,7 +740,8 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkWindowBoundReached(pSliceInfo)) { break; } - if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + saveBlockStatus(pSliceInfo, pBlock, i); return; } } else { @@ -759,7 +777,8 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkWindowBoundReached(pSliceInfo)) { break; } - if (checkThresholdReached(pSliceInfo, pBlock, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + saveBlockStatus(pSliceInfo, pBlock, i); return; } } @@ -854,7 +873,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { while (1) { if (pSliceInfo->pNextGroupRes != NULL) { doHandleTimeslice(pOperator, pSliceInfo->pNextGroupRes); - if (checkThresholdReached(pSliceInfo, pSliceInfo->pRemainRes, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); goto _finished; } @@ -879,7 +898,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } doHandleTimeslice(pOperator, pBlock); - if (checkThresholdReached(pSliceInfo, pSliceInfo->pRemainRes, pOperator->resultInfo.threshold)) { + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); goto _finished; } @@ -943,6 +962,7 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->tsCol = extractColumnFromColumnNode((SColumnNode*)pInterpPhyNode->pTimeSeries); pInfo->fillType = convertFillType(pInterpPhyNode->fillMode); initResultSizeInfo(&pOperator->resultInfo, 4096); + pOperator->resultInfo.threshold = 1; pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, NULL, 0, (SNodeListNode*)pInterpPhyNode->pFillValues); pInfo->pLinearInfo = NULL; @@ -956,6 +976,7 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->pPrevGroupKey = NULL; pInfo->pNextGroupRes = NULL; pInfo->pRemainRes = NULL; + pInfo->remainTs = 0; if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; From 21fccc2d48224439ccd9ab37f0e97e088075e323 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 8 Jun 2023 18:25:32 +0800 Subject: [PATCH 03/21] fix switchin group issue --- source/libs/executor/src/timesliceoperator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 1aa6027a1d..8006235391 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -903,7 +903,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { goto _finished; } } - // handling post work for a specific group + // post work for a specific group // check if need to interpolate after last datablock // except for fill(next), fill(linear) @@ -916,6 +916,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // restore initial value for next group resetTimesliceInfo(pSliceInfo); + if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + goto _finished; + } } _finished: From 145bb93967081a7364c3deff68c7dc95dae8ada4 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 8 Jun 2023 19:21:04 +0800 Subject: [PATCH 04/21] fix block only have one row --- source/libs/executor/src/timesliceoperator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 8006235391..56aaf587c3 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -875,6 +875,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doHandleTimeslice(pOperator, pSliceInfo->pNextGroupRes); if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); + if (pSliceInfo->pRemainRes == NULL) { + pSliceInfo->pNextGroupRes = NULL; + } goto _finished; } pSliceInfo->pNextGroupRes = NULL; From bef62149047de1e249fdaba77b619daf5ef2fe4b Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 8 Jun 2023 19:30:05 +0800 Subject: [PATCH 05/21] remove test code --- source/libs/executor/src/timesliceoperator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 56aaf587c3..416925a311 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -968,7 +968,6 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->tsCol = extractColumnFromColumnNode((SColumnNode*)pInterpPhyNode->pTimeSeries); pInfo->fillType = convertFillType(pInterpPhyNode->fillMode); initResultSizeInfo(&pOperator->resultInfo, 4096); - pOperator->resultInfo.threshold = 1; pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, NULL, 0, (SNodeListNode*)pInterpPhyNode->pFillValues); pInfo->pLinearInfo = NULL; From 8663148d6cacc9d69189249c2a848e75c765db53 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 16 Jun 2023 09:20:34 +0800 Subject: [PATCH 06/21] fix: return error from vmPutMsgToQueue while vnode-write is disabled --- source/dnode/mgmt/mgmt_vnode/src/vmWorker.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c index e41c9e10d7..76e2f93027 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -218,6 +218,7 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp if (pMsg->msgType != TDMT_VND_ALTER_CONFIRM && pVnode->disable) { dDebug("vgId:%d, msg:%p put into vnode-write queue failed since its disable", pVnode->vgId, pMsg); terrno = TSDB_CODE_VND_STOPPED; + code = terrno; break; } dGTrace("vgId:%d, msg:%p put into vnode-write queue", pVnode->vgId, pMsg); From fb4f174fbca0909db204864d7174868acc9c3bbf Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Fri, 16 Jun 2023 10:26:09 +0800 Subject: [PATCH 07/21] feature: add input, output ts order for execution plans --- include/common/tcommon.h | 1 + include/libs/nodes/plannodes.h | 12 +- include/libs/nodes/querynodes.h | 1 + source/common/src/tdatablock.c | 4 +- source/libs/command/inc/commandInt.h | 2 +- source/libs/command/src/explain.c | 30 +- source/libs/executor/inc/executorInt.h | 4 +- source/libs/executor/inc/tsort.h | 2 +- source/libs/executor/src/aggregateoperator.c | 17 +- source/libs/executor/src/cachescanoperator.c | 1 + .../libs/executor/src/eventwindowoperator.c | 5 +- source/libs/executor/src/exchangeoperator.c | 1 + source/libs/executor/src/filloperator.c | 12 +- source/libs/executor/src/groupoperator.c | 14 +- source/libs/executor/src/joinoperator.c | 5 +- source/libs/executor/src/projectoperator.c | 27 +- source/libs/executor/src/scanoperator.c | 1 + source/libs/executor/src/sortoperator.c | 10 + source/libs/executor/src/timesliceoperator.c | 1 + source/libs/executor/src/timewindowoperator.c | 66 +- source/libs/executor/src/tsort.c | 1 + source/libs/nodes/src/nodesCloneFuncs.c | 9 +- source/libs/nodes/src/nodesCodeFuncs.c | 33 +- source/libs/nodes/src/nodesMsgFuncs.c | 40 +- source/libs/planner/src/planLogicCreater.c | 22 +- source/libs/planner/src/planOptimizer.c | 78 +- source/libs/planner/src/planPhysiCreater.c | 19 +- source/libs/planner/src/planSpliter.c | 8 +- tests/parallel_test/cases.task | 1 + tests/script/tsim/query/explain_tsorder.sim | 37 + .../tsim/query/r/explain_tsorder.result | 2560 +++++++++++++++++ tests/script/tsim/query/t/explain_tsorder.sql | 73 + utils/tsim/src/simExe.c | 2 +- 33 files changed, 2931 insertions(+), 168 deletions(-) create mode 100644 tests/script/tsim/query/explain_tsorder.sim create mode 100644 tests/script/tsim/query/r/explain_tsorder.result create mode 100644 tests/script/tsim/query/t/explain_tsorder.sql diff --git a/include/common/tcommon.h b/include/common/tcommon.h index d2352e100c..ea17262abd 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -198,6 +198,7 @@ typedef struct SDataBlockInfo { SBlockID id; int16_t hasVarCol; int16_t dataLoad; // denote if the data is loaded or not + uint8_t scanFlag; // TODO: optimize and remove following int64_t version; // used for stream, and need serialization diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index f44b622cc0..453c5d4914 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -53,6 +53,8 @@ typedef struct SLogicNode { EDataOrderLevel requireDataOrder; // requirements for input data EDataOrderLevel resultDataOrder; // properties of the output data EGroupAction groupAction; + EOrder inputTsOrder; + EOrder outputTsOrder; } SLogicNode; typedef enum EScanType { @@ -111,7 +113,6 @@ typedef struct SJoinLogicNode { SNode* pMergeCondition; SNode* pOnConditions; bool isSingleTableJoin; - EOrder inputTsOrder; SNode* pColEqualOnConditions; } SJoinLogicNode; @@ -229,8 +230,6 @@ typedef struct SWindowLogicNode { int8_t igExpired; int8_t igCheckUpdate; EWindowAlgorithm windowAlgo; - EOrder inputTsOrder; - EOrder outputTsOrder; } SWindowLogicNode; typedef struct SFillLogicNode { @@ -241,7 +240,6 @@ typedef struct SFillLogicNode { SNode* pWStartTs; SNode* pValues; // SNodeListNode STimeWindow timeRange; - EOrder inputTsOrder; } SFillLogicNode; typedef struct SSortLogicNode { @@ -310,6 +308,8 @@ typedef struct SDataBlockDescNode { typedef struct SPhysiNode { ENodeType type; + EOrder inputTsOrder; + EOrder outputTsOrder; SDataBlockDescNode* pOutputDataBlockDesc; SNode* pConditions; SNodeList* pChildren; @@ -406,7 +406,6 @@ typedef struct SSortMergeJoinPhysiNode { SNode* pMergeCondition; SNode* pOnConditions; SNodeList* pTargets; - EOrder inputTsOrder; SNode* pColEqualOnConditions; } SSortMergeJoinPhysiNode; @@ -460,8 +459,6 @@ typedef struct SWindowPhysiNode { int64_t watermark; int64_t deleteMark; int8_t igExpired; - EOrder inputTsOrder; - EOrder outputTsOrder; bool mergeDataBlock; } SWindowPhysiNode; @@ -488,7 +485,6 @@ typedef struct SFillPhysiNode { SNode* pWStartTs; // SColumnNode SNode* pValues; // SNodeListNode STimeWindow timeRange; - EOrder inputTsOrder; } SFillPhysiNode; typedef SFillPhysiNode SStreamFillPhysiNode; diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index f570698395..678c694d9b 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -69,6 +69,7 @@ typedef struct SColumnNode { uint64_t tableId; int8_t tableType; col_id_t colId; + uint16_t projIdx; // the idx in project list, start from 1 EColumnType colType; // column or tag bool hasIndex; char dbName[TSDB_DB_NAME_LEN]; diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 033fbb0ef1..4c04fb520c 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -791,8 +791,8 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) { * @return */ size_t blockDataGetSerialMetaSize(uint32_t numOfCols) { - // | version | total length | total rows | total columns | flag seg| block group id | column schema | each column - // length | + // | version | total length | total rows | total columns | flag seg| block group id | column schema + // | each column length | return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t); } diff --git a/source/libs/command/inc/commandInt.h b/source/libs/command/inc/commandInt.h index 2a435b43e8..2a7aeb0060 100644 --- a/source/libs/command/inc/commandInt.h +++ b/source/libs/command/inc/commandInt.h @@ -145,7 +145,7 @@ typedef struct SExplainCtx { SHashObj *groupHash; // Hash } SExplainCtx; -#define EXPLAIN_ORDER_STRING(_order) ((ORDER_ASC == _order) ? "asc" : "desc") +#define EXPLAIN_ORDER_STRING(_order) ((ORDER_ASC == _order) ? "asc" : ORDER_DESC == _order ? "desc" : "unknown") #define EXPLAIN_JOIN_STRING(_type) ((JOIN_TYPE_INNER == _type) ? "Inner join" : "Join") #define INVERAL_TIME_FROM_PRECISION_TO_UNIT(_t, _u, _p) (((_u) == 'n' || (_u) == 'y') ? (_t) : (convertTimeFromPrecisionToUnit(_t, _p, _u))) diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index c5b9eb7475..884c0f7b20 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -499,6 +499,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pPrjNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -544,6 +547,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pJoinNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -597,6 +603,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length); } + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pAggNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -716,6 +725,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i case QUERY_NODE_PHYSICAL_PLAN_SORT: { SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode; EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pSortNode->node.outputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); if (pResNode->pExecInfo) { QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); @@ -796,9 +810,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); - EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); - EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.outputTsOrder)); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -847,6 +862,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pIntNode->window.node.outputTsOrder)); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -895,6 +914,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pFillNode->mode)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pFillNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pFillNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -1080,6 +1102,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_INPUT_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.inputTsOrder)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT, EXPLAIN_ORDER_STRING(pMergeNode->node.outputTsOrder)); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index 38890f8c34..5d663df50e 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -399,6 +399,8 @@ typedef struct SOptrBasicInfo { SResultRowInfo resultRowInfo; SSDataBlock* pRes; bool mergeResultBlock; + int32_t inputTsOrder; + int32_t outputTsOrder; } SOptrBasicInfo; typedef struct SIntervalAggOperatorInfo { @@ -411,8 +413,6 @@ typedef struct SIntervalAggOperatorInfo { STimeWindow win; // query time range bool timeWindowInterpo; // interpolation needed or not SArray* pInterpCols; // interpolation columns - int32_t resultTsOrder; // result timestamp order - int32_t inputOrder; // input data ts order EOPTR_EXEC_MODEL execModel; // operator execution model [batch model|stream model] STimeWindowAggSupp twAggSup; SArray* pPrevValues; // SArray used to keep the previous not null value for interpolation. diff --git a/source/libs/executor/inc/tsort.h b/source/libs/executor/inc/tsort.h index d51a24bb43..e0718a0c0a 100644 --- a/source/libs/executor/inc/tsort.h +++ b/source/libs/executor/inc/tsort.h @@ -146,7 +146,7 @@ void* tsortGetValue(STupleHandle* pVHandle, int32_t colId); * @return */ uint64_t tsortGetGroupId(STupleHandle* pVHandle); - +void* tsortGetBlockInfo(STupleHandle* pVHandle); /** * * @param pSortHandle diff --git a/source/libs/executor/src/aggregateoperator.c b/source/libs/executor/src/aggregateoperator.c index b34c6f4b82..d6a34bc7ba 100644 --- a/source/libs/executor/src/aggregateoperator.c +++ b/source/libs/executor/src/aggregateoperator.c @@ -108,6 +108,8 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SAggPhysiN pInfo->binfo.mergeResultBlock = pAggNode->mergeDataBlock; pInfo->groupKeyOptimized = pAggNode->groupKeyOptimized; pInfo->groupId = UINT64_MAX; + pInfo->binfo.inputTsOrder = pAggNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pAggNode->node.outputTsOrder; setOperatorInfo(pOperator, "TableAggregate", QUERY_NODE_PHYSICAL_PLAN_HASH_AGG, true, OP_NOT_OPENED, pInfo, pTaskInfo); @@ -164,10 +166,8 @@ int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { SOperatorInfo* downstream = pOperator->pDownstream[0]; int64_t st = taosGetTimestampUs(); - - int32_t order = TSDB_ORDER_ASC; - int32_t scanFlag = MAIN_SCAN; - + int32_t code = TSDB_CODE_SUCCESS; + int32_t order = pAggInfo->binfo.inputTsOrder; bool hasValidBlock = false; while (1) { @@ -185,12 +185,7 @@ int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { } } hasValidBlock = true; - - int32_t code = getTableScanInfo(pOperator, &order, &scanFlag, false); - if (code != TSDB_CODE_SUCCESS) { - destroyDataBlockForEmptyInput(blockAllocated, &pBlock); - T_LONG_JMP(pTaskInfo->env, code); - } + pAggInfo->binfo.pRes->info.scanFlag = pBlock->info.scanFlag; // there is an scalar expression that needs to be calculated before apply the group aggregation. if (pAggInfo->scalarExprSup.pExprInfo != NULL && !blockAllocated) { @@ -204,7 +199,7 @@ int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { // the pDataBlock are always the same one, no need to call this again setExecutionContext(pOperator, pOperator->exprSupp.numOfExprs, pBlock->info.id.groupId); - setInputDataBlock(pSup, pBlock, order, scanFlag, true); + setInputDataBlock(pSup, pBlock, order, pBlock->info.scanFlag, true); code = doAggregateImpl(pOperator, pSup->pCtx); if (code != 0) { destroyDataBlockForEmptyInput(blockAllocated, &pBlock); diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 48003b277b..ce39ebab59 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -208,6 +208,7 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) { pRes->info.id.uid = *(tb_uid_t*)taosArrayGet(pInfo->pUidList, pInfo->indexOfBufferedRes); pRes->info.rows = 1; + pRes->info.scanFlag = MAIN_SCAN; SExprSupp* pSup = &pInfo->pseudoExprSup; int32_t code = addTagPseudoColumnData(&pInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pRes, diff --git a/source/libs/executor/src/eventwindowoperator.c b/source/libs/executor/src/eventwindowoperator.c index b5dea6d94d..addf9e9c6b 100644 --- a/source/libs/executor/src/eventwindowoperator.c +++ b/source/libs/executor/src/eventwindowoperator.c @@ -120,6 +120,8 @@ SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNo initBasicInfo(&pInfo->binfo, pResBlock); initResultRowInfo(&pInfo->binfo.resultRowInfo); + pInfo->binfo.inputTsOrder = physiNode->inputTsOrder; + pInfo->binfo.outputTsOrder = physiNode->outputTsOrder; pInfo->twAggSup = (STimeWindowAggSupp){.waterMark = pEventWindowNode->window.watermark, .calTrigger = pEventWindowNode->window.triggerType}; @@ -182,11 +184,12 @@ static SSDataBlock* eventWindowAggregate(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExprSupp* pSup = &pOperator->exprSupp; - int32_t order = TSDB_ORDER_ASC; + int32_t order = pInfo->binfo.inputTsOrder; SSDataBlock* pRes = pInfo->binfo.pRes; blockDataCleanup(pRes); + pRes->info.scanFlag = MAIN_SCAN; SOperatorInfo* downstream = pOperator->pDownstream[0]; while (1) { diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index 94041140d4..4fbe6785a3 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -520,6 +520,7 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, SArray* pCo // data from mnode pRes->info.dataLoad = 1; pRes->info.rows = pBlock->info.rows; + pRes->info.scanFlag = MAIN_SCAN; relocateColumnData(pRes, pColList, pBlock->pDataBlock, false); blockDataDestroy(pBlock); } diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c index f9e8a32520..1106c6e29f 100644 --- a/source/libs/executor/src/filloperator.c +++ b/source/libs/executor/src/filloperator.c @@ -178,16 +178,15 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); - int32_t order = TSDB_ORDER_ASC; - int32_t scanFlag = MAIN_SCAN; - getTableScanInfo(pOperator, &order, &scanFlag, false); + int32_t order = pInfo->pFillInfo->order; SOperatorInfo* pDownstream = pOperator->pDownstream[0]; - +#if 0 // the scan order may be different from the output result order for agg interval operator. if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL) { order = ((SIntervalAggOperatorInfo*) pDownstream->info)->resultTsOrder; } +#endif doHandleRemainBlockFromNewGroup(pOperator, pInfo, pResultInfo, order); if (pResBlock->info.rows > 0) { @@ -206,13 +205,14 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey); } else { + pResBlock->info.scanFlag = pBlock->info.scanFlag; pBlock->info.dataLoad = 1; blockDataUpdateTsWindow(pBlock, pInfo->primarySrcSlotId); blockDataCleanup(pInfo->pRes); blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows); blockDataEnsureCapacity(pInfo->pFinalRes, pBlock->info.rows); - doApplyScalarCalculation(pOperator, pBlock, order, scanFlag); + doApplyScalarCalculation(pOperator, pBlock, order, pBlock->info.scanFlag); if (pInfo->curGroupId == 0 || (pInfo->curGroupId == pInfo->pRes->info.id.groupId)) { if (pInfo->curGroupId == 0 && taosFillNotStarted(pInfo->pFillInfo)) { @@ -405,7 +405,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* ? &((SMergeAlignedIntervalAggOperatorInfo*)downstream->info)->intervalAggOperatorInfo->interval : &((SIntervalAggOperatorInfo*)downstream->info)->interval; - int32_t order = (pPhyFillNode->inputTsOrder == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; + int32_t order = (pPhyFillNode->node.inputTsOrder == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; int32_t type = convertFillType(pPhyFillNode->mode); SResultInfo* pResultInfo = &pOperator->resultInfo; diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index c448ea0160..4eaf778901 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -378,9 +378,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) { return buildGroupResultDataBlock(pOperator); } - int32_t order = TSDB_ORDER_ASC; - int32_t scanFlag = MAIN_SCAN; - + int32_t order = pInfo->binfo.inputTsOrder; int64_t st = taosGetTimestampUs(); SOperatorInfo* downstream = pOperator->pDownstream[0]; @@ -390,13 +388,10 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) { break; } - int32_t code = getTableScanInfo(pOperator, &order, &scanFlag, false); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, code); - } + pInfo->binfo.pRes->info.scanFlag = pBlock->info.scanFlag; // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(&pOperator->exprSupp, pBlock, order, scanFlag, true); + setInputDataBlock(&pOperator->exprSupp, pBlock, order, pBlock->info.scanFlag, true); // there is an scalar expression that needs to be calculated right before apply the group aggregation. if (pInfo->scalarSup.pExprInfo != NULL) { @@ -481,6 +476,8 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SAggPhysiNode* setOperatorInfo(pOperator, "GroupbyAggOperator", 0, true, OP_NOT_OPENED, pInfo, pTaskInfo); pInfo->binfo.mergeResultBlock = pAggNode->mergeDataBlock; + pInfo->binfo.inputTsOrder = pAggNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pAggNode->node.outputTsOrder; pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, hashGroupbyAggregate, NULL, destroyGroupOperatorInfo, optrDefaultBufFn, NULL); @@ -762,6 +759,7 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator) { break; } + pInfo->binfo.pRes->info.scanFlag = pBlock->info.scanFlag; // there is an scalar expression that needs to be calculated right before apply the group aggregation. if (pInfo->scalarSup.pExprInfo != NULL) { pTaskInfo->code = projectApplyFunctions(pInfo->scalarSup.pExprInfo, pBlock, pBlock, pInfo->scalarSup.pCtx, diff --git a/source/libs/executor/src/joinoperator.c b/source/libs/executor/src/joinoperator.c index 73143fdba7..13ab5d05a5 100644 --- a/source/libs/executor/src/joinoperator.c +++ b/source/libs/executor/src/joinoperator.c @@ -253,9 +253,9 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t } pInfo->inputOrder = TSDB_ORDER_ASC; - if (pJoinNode->inputTsOrder == ORDER_ASC) { + if (pJoinNode->node.inputTsOrder == ORDER_ASC) { pInfo->inputOrder = TSDB_ORDER_ASC; - } else if (pJoinNode->inputTsOrder == ORDER_DESC) { + } else if (pJoinNode->node.inputTsOrder == ORDER_DESC) { pInfo->inputOrder = TSDB_ORDER_DESC; } @@ -684,6 +684,7 @@ static void doMergeJoinImpl(struct SOperatorInfo* pOperator, SSDataBlock* pRes) // the pDataBlock are always the same one, no need to call this again pRes->info.rows = nrows; pRes->info.dataLoad = 1; + pRes->info.scanFlag = MAIN_SCAN; if (pRes->info.rows >= pOperator->resultInfo.threshold) { break; } diff --git a/source/libs/executor/src/projectoperator.c b/source/libs/executor/src/projectoperator.c index e7de826d4b..cd450c5bb7 100644 --- a/source/libs/executor/src/projectoperator.c +++ b/source/libs/executor/src/projectoperator.c @@ -93,6 +93,8 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhys pInfo->binfo.pRes = pResBlock; pInfo->pFinalRes = createOneDataBlock(pResBlock, false); + pInfo->binfo.inputTsOrder = pProjPhyNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pProjPhyNode->node.outputTsOrder; if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) { pInfo->mergeDataBlocks = false; @@ -238,8 +240,9 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { } int64_t st = 0; - int32_t order = 0; + int32_t order = pInfo->inputTsOrder; int32_t scanFlag = 0; + int32_t code = TSDB_CODE_SUCCESS; if (pOperator->cost.openCost == 0) { st = taosGetTimestampUs(); @@ -284,10 +287,10 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { break; } - // the pDataBlock are always the same one, no need to call this again - int32_t code = getTableScanInfo(downstream, &order, &scanFlag, false); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, code); + if (pProjectInfo->mergeDataBlocks) { + pFinalRes->info.scanFlag = scanFlag = pBlock->info.scanFlag; + } else { + pRes->info.scanFlag = scanFlag = pBlock->info.scanFlag; } setInputDataBlock(pSup, pBlock, order, scanFlag, false); @@ -406,6 +409,8 @@ SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhy } pInfo->binfo.pRes = pResBlock; + pInfo->binfo.inputTsOrder = pNode->inputTsOrder; + pInfo->binfo.outputTsOrder = pNode->outputTsOrder; pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pSup->pCtx, numOfExpr); setOperatorInfo(pOperator, "IndefinitOperator", QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC, false, OP_NOT_OPENED, pInfo, @@ -429,18 +434,13 @@ _error: static void doHandleDataBlock(SOperatorInfo* pOperator, SSDataBlock* pBlock, SOperatorInfo* downstream, SExecTaskInfo* pTaskInfo) { - int32_t order = 0; - int32_t scanFlag = 0; - SIndefOperatorInfo* pIndefInfo = pOperator->info; SOptrBasicInfo* pInfo = &pIndefInfo->binfo; SExprSupp* pSup = &pOperator->exprSupp; - // the pDataBlock are always the same one, no need to call this again - int32_t code = getTableScanInfo(downstream, &order, &scanFlag, false); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, code); - } + int32_t order = pInfo->inputTsOrder; + int32_t scanFlag = pBlock->info.scanFlag; + int32_t code = TSDB_CODE_SUCCESS; // there is an scalar expression that needs to be calculated before apply the group aggregation. SExprSupp* pScalarSup = &pIndefInfo->scalarSup; @@ -506,6 +506,7 @@ SSDataBlock* doApplyIndefinitFunction(SOperatorInfo* pOperator) { setOperatorCompleted(pOperator); break; } + pInfo->pRes->info.scanFlag = pBlock->info.scanFlag; if (pIndefInfo->groupId == 0 && pBlock->info.id.groupId != 0) { pIndefInfo->groupId = pBlock->info.id.groupId; // this is the initial group result diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 2702cf6861..2f108c83b0 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -712,6 +712,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) { pTableScanInfo->base.readRecorder.elapsedTime += (taosGetTimestampUs() - st) / 1000.0; pOperator->cost.totalCost = pTableScanInfo->base.readRecorder.elapsedTime; + pBlock->info.scanFlag = pTableScanInfo->base.scanFlag; return pBlock; } return NULL; diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index 0395b9ec08..8f287946f0 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -69,6 +69,8 @@ SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode); pInfo->pSortInfo = createSortInfo(pSortNode->pSortKeys); + pInfo->binfo.inputTsOrder = pSortNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pSortNode->node.outputTsOrder; initLimitInfo(pSortNode->node.pLimit, pSortNode->node.pSlimit, &pInfo->limitInfo); setOperatorInfo(pOperator, "SortOperator", QUERY_NODE_PHYSICAL_PLAN_SORT, true, OP_NOT_OPENED, pInfo, pTaskInfo); @@ -114,6 +116,7 @@ void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle) { } pBlock->info.dataLoad = 1; + pBlock->info.scanFlag = ((SDataBlockInfo*)tsortGetBlockInfo(pTupleHandle))->scanFlag; pBlock->info.rows += 1; } @@ -155,6 +158,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i pDataBlock->info.dataLoad = 1; pDataBlock->info.rows = p->info.rows; + pDataBlock->info.scanFlag = p->info.scanFlag; } blockDataDestroy(p); @@ -331,6 +335,7 @@ SSDataBlock* getGroupSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlo pDataBlock->info.rows = p->info.rows; pDataBlock->info.capacity = p->info.rows; + pDataBlock->info.scanFlag = p->info.scanFlag; } blockDataDestroy(p); @@ -505,6 +510,8 @@ SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSort pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + pInfo->binfo.inputTsOrder = pSortPhyNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pSortPhyNode->node.outputTsOrder; int32_t numOfOutputCols = 0; int32_t code = extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, COL_MATCH_FROM_SLOT_ID, @@ -698,6 +705,7 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData } pDataBlock->info.rows = p->info.rows; + pDataBlock->info.scanFlag = p->info.scanFlag; if (pInfo->ignoreGroupId) { pDataBlock->info.id.groupId = 0; } else { @@ -799,6 +807,8 @@ SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock); pInfo->bufPageSize = getProperSortPageSize(rowSize, numOfCols); pInfo->sortBufSize = pInfo->bufPageSize * (numStreams + 1); // one additional is reserved for merged result. + pInfo->binfo.inputTsOrder = pMergePhyNode->node.inputTsOrder; + pInfo->binfo.outputTsOrder = pMergePhyNode->node.outputTsOrder; setOperatorInfo(pOperator, "MultiwayMergeOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE, false, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->fpSet = createOperatorFpSet(openMultiwayMergeOperator, doMultiwayMerge, NULL, diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 2421343bd7..770e0d4fbd 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -798,6 +798,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SOperatorInfo* downstream = pOperator->pDownstream[0]; blockDataCleanup(pResBlock); + pResBlock->info.scanFlag = MAIN_SCAN; while (1) { if (pSliceInfo->pNextGroupRes != NULL) { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 2676e097f9..5e90d78642 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -355,7 +355,7 @@ static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, in static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, int32_t pos, SSDataBlock* pBlock, const TSKEY* tsCols, STimeWindow* win, SExprSupp* pSup) { - bool ascQuery = (pInfo->inputOrder == TSDB_ORDER_ASC); + bool ascQuery = (pInfo->binfo.inputTsOrder == TSDB_ORDER_ASC); TSKEY curTs = tsCols[pos]; @@ -385,7 +385,7 @@ static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, i static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SExprSupp* pSup, int32_t endRowIndex, SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, STimeWindow* win) { - int32_t order = pInfo->inputOrder; + int32_t order = pInfo->binfo.inputTsOrder; TSKEY actualEndKey = tsCols[endRowIndex]; TSKEY key = (order == TSDB_ORDER_ASC) ? win->ekey : win->skey; @@ -547,7 +547,7 @@ static void doWindowBorderInterpolation(SIntervalAggOperatorInfo* pInfo, SSDataB if (!done) { int32_t endRowIndex = startPos + forwardRows - 1; - TSKEY endKey = (pInfo->inputOrder == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey; + TSKEY endKey = (pInfo->binfo.inputTsOrder == TSDB_ORDER_ASC) ? pBlock->info.window.ekey : pBlock->info.window.skey; bool interp = setTimeWindowInterpolationEndTs(pInfo, pSup, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win); if (interp) { setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); @@ -885,12 +885,12 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul int32_t numOfOutput = pSup->numOfExprs; int64_t* tsCols = extractTsCol(pBlock, pInfo); uint64_t tableGroupId = pBlock->info.id.groupId; - bool ascScan = (pInfo->inputOrder == TSDB_ORDER_ASC); + bool ascScan = (pInfo->binfo.inputTsOrder == TSDB_ORDER_ASC); TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols); SResultRow* pResult = NULL; STimeWindow win = - getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, pInfo->inputOrder); + getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, pInfo->binfo.inputTsOrder); int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { @@ -899,7 +899,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul TSKEY ekey = ascScan ? win.ekey : win.skey; int32_t forwardRows = - getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->inputOrder); + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->binfo.inputTsOrder); // prev time window not interpolation yet. if (pInfo->timeWindowInterpo) { @@ -926,7 +926,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul STimeWindow nextWin = win; while (1) { int32_t prevEndPos = forwardRows - 1 + startPos; - startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, pInfo->inputOrder); + startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, pInfo->binfo.inputTsOrder); if (startPos < 0) { break; } @@ -939,7 +939,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul ekey = ascScan ? nextWin.ekey : nextWin.skey; forwardRows = - getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->inputOrder); + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, pInfo->binfo.inputTsOrder); // window start(end) key interpolation doWindowBorderInterpolation(pInfo, pBlock, pResult, &nextWin, startPos, forwardRows, pSup); // TODO: add to open window? how to close the open windows after input blocks exhausted? @@ -1032,7 +1032,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { break; } - getTableScanInfo(pOperator, &pInfo->inputOrder, &scanFlag, true); + pInfo->binfo.pRes->info.scanFlag = scanFlag = pBlock->info.scanFlag; if (pInfo->scalarSupp.pExprInfo != NULL) { SExprSupp* pExprSup = &pInfo->scalarSupp; @@ -1040,11 +1040,11 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, pInfo->inputOrder, scanFlag, true); + setInputDataBlock(pSup, pBlock, pInfo->binfo.inputTsOrder, scanFlag, true); hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, scanFlag); } - initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, pInfo->resultTsOrder); + initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, pInfo->binfo.outputTsOrder); OPTR_SET_OPENED(pOperator); pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0; @@ -1158,10 +1158,11 @@ static int32_t openStateWindowAggOptr(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExprSupp* pSup = &pOperator->exprSupp; - int32_t order = TSDB_ORDER_ASC; + int32_t order = pInfo->binfo.inputTsOrder; int64_t st = taosGetTimestampUs(); SOperatorInfo* downstream = pOperator->pDownstream[0]; + pInfo->binfo.pRes->info.scanFlag = MAIN_SCAN; while (1) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { @@ -1650,8 +1651,8 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SIntervalPh }; pInfo->win = pTaskInfo->window; - pInfo->inputOrder = (pPhyNode->window.inputTsOrder == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; - pInfo->resultTsOrder = (pPhyNode->window.outputTsOrder == ORDER_ASC) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; + pInfo->binfo.inputTsOrder = pPhyNode->window.node.inputTsOrder; + pInfo->binfo.outputTsOrder = pPhyNode->window.node.outputTsOrder; pInfo->interval = interval; pInfo->twAggSup = as; pInfo->binfo.mergeResultBlock = pPhyNode->window.mergeDataBlock; @@ -1802,7 +1803,8 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { } int64_t st = taosGetTimestampUs(); - int32_t order = TSDB_ORDER_ASC; + int32_t order = pInfo->binfo.inputTsOrder; + pBInfo->pRes->info.scanFlag = MAIN_SCAN; SOperatorInfo* downstream = pOperator->pDownstream[0]; @@ -1872,6 +1874,8 @@ SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SStateWi if (pInfo->stateKey.pData == NULL) { goto _error; } + pInfo->binfo.inputTsOrder = pStateNode->window.node.inputTsOrder; + pInfo->binfo.outputTsOrder = pStateNode->window.node.outputTsOrder; int32_t code = filterInitFromNode((SNode*)pStateNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0); if (code != TSDB_CODE_SUCCESS) { @@ -1970,6 +1974,8 @@ SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SSessionW pInfo->binfo.pRes = pResBlock; pInfo->winSup.prevTs = INT64_MIN; pInfo->reptScan = false; + pInfo->binfo.inputTsOrder = pSessionNode->window.node.inputTsOrder; + pInfo->binfo.outputTsOrder = pSessionNode->window.node.outputTsOrder; code = filterInitFromNode((SNode*)pSessionNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0); if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -4318,7 +4324,6 @@ static void doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) { SSDataBlock* pRes = pIaInfo->binfo.pRes; SResultRowInfo* pResultRowInfo = &pIaInfo->binfo.resultRowInfo; SOperatorInfo* downstream = pOperator->pDownstream[0]; - int32_t scanFlag = MAIN_SCAN; while (1) { SSDataBlock* pBlock = NULL; @@ -4365,8 +4370,8 @@ static void doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) { } } - getTableScanInfo(pOperator, &pIaInfo->inputOrder, &scanFlag, false); - setInputDataBlock(pSup, pBlock, pIaInfo->inputOrder, scanFlag, true); + pRes->info.scanFlag = pBlock->info.scanFlag; + setInputDataBlock(pSup, pBlock, pIaInfo->binfo.inputTsOrder, pBlock->info.scanFlag, true); doMergeAlignedIntervalAggImpl(pOperator, &pIaInfo->binfo.resultRowInfo, pBlock, pRes); doFilter(pRes, pOperator->exprSupp.pFilterInfo, NULL); @@ -4439,7 +4444,8 @@ SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, miaInfo->curTs = INT64_MIN; iaInfo->win = pTaskInfo->window; - iaInfo->inputOrder = TSDB_ORDER_ASC; + iaInfo->binfo.inputTsOrder = pNode->window.node.inputTsOrder; + iaInfo->binfo.outputTsOrder = pNode->window.node.outputTsOrder; iaInfo->interval = interval; iaInfo->primaryTsIndex = ((SColumnNode*)pNode->window.pTspk)->slotId; iaInfo->binfo.mergeResultBlock = pNode->window.mergeDataBlock; @@ -4516,7 +4522,7 @@ static int32_t outputPrevIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t t STimeWindow* newWin) { SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; - bool ascScan = (iaInfo->inputOrder == TSDB_ORDER_ASC); + bool ascScan = (iaInfo->binfo.inputTsOrder == TSDB_ORDER_ASC); SGroupTimeWindow groupTimeWindow = {.groupId = tableGroupId, .window = *newWin}; tdListAppend(miaInfo->groupIntervals, &groupTimeWindow); @@ -4551,12 +4557,12 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* int32_t numOfOutput = pExprSup->numOfExprs; int64_t* tsCols = extractTsCol(pBlock, iaInfo); uint64_t tableGroupId = pBlock->info.id.groupId; - bool ascScan = (iaInfo->inputOrder == TSDB_ORDER_ASC); + bool ascScan = (iaInfo->binfo.inputTsOrder == TSDB_ORDER_ASC); TSKEY blockStartTs = getStartTsKey(&pBlock->info.window, tsCols); SResultRow* pResult = NULL; STimeWindow win = getActiveTimeWindow(iaInfo->aggSup.pResultBuf, pResultRowInfo, blockStartTs, &iaInfo->interval, - iaInfo->inputOrder); + iaInfo->binfo.inputTsOrder); int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pExprSup->pCtx, @@ -4567,7 +4573,7 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* TSKEY ekey = ascScan ? win.ekey : win.skey; int32_t forwardRows = - getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->inputOrder); + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->binfo.inputTsOrder); ASSERT(forwardRows > 0); // prev time window not interpolation yet. @@ -4598,7 +4604,7 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* while (1) { int32_t prevEndPos = forwardRows - 1 + startPos; startPos = - getNextQualifiedWindow(&iaInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, iaInfo->inputOrder); + getNextQualifiedWindow(&iaInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, iaInfo->binfo.inputTsOrder); if (startPos < 0) { break; } @@ -4613,7 +4619,7 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* ekey = ascScan ? nextWin.ekey : nextWin.skey; forwardRows = - getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->inputOrder); + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->binfo.inputTsOrder); // window start(end) key interpolation doWindowBorderInterpolation(iaInfo, pBlock, pResult, &nextWin, startPos, forwardRows, pExprSup); @@ -4649,7 +4655,6 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { if (!miaInfo->inputBlocksFinished) { SOperatorInfo* downstream = pOperator->pDownstream[0]; - int32_t scanFlag = MAIN_SCAN; while (1) { SSDataBlock* pBlock = NULL; if (miaInfo->prefetchedBlock == NULL) { @@ -4674,9 +4679,9 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { break; } - getTableScanInfo(pOperator, &iaInfo->inputOrder, &scanFlag, false); - setInputDataBlock(pExpSupp, pBlock, iaInfo->inputOrder, scanFlag, true); - doMergeIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes); + pRes->info.scanFlag = pBlock->info.scanFlag; + setInputDataBlock(pExpSupp, pBlock, iaInfo->binfo.inputTsOrder, pBlock->info.scanFlag, true); + doMergeIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, pBlock->info.scanFlag, pRes); if (pRes->info.rows >= pOperator->resultInfo.threshold) { break; @@ -4726,10 +4731,11 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SMerge SIntervalAggOperatorInfo* pIntervalInfo = &pMergeIntervalInfo->intervalAggOperatorInfo; pIntervalInfo->win = pTaskInfo->window; - pIntervalInfo->inputOrder = TSDB_ORDER_ASC; + pIntervalInfo->binfo.inputTsOrder = pIntervalPhyNode->window.node.inputTsOrder; pIntervalInfo->interval = interval; pIntervalInfo->binfo.mergeResultBlock = pIntervalPhyNode->window.mergeDataBlock; pIntervalInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + pIntervalInfo->binfo.outputTsOrder = pIntervalPhyNode->window.node.outputTsOrder; SExprSupp* pExprSupp = &pOperator->exprSupp; diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 3033441aad..f26aa8a97c 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -887,6 +887,7 @@ void* tsortGetValue(STupleHandle* pVHandle, int32_t colIndex) { } uint64_t tsortGetGroupId(STupleHandle* pVHandle) { return pVHandle->pBlock->info.id.groupId; } +void* tsortGetBlockInfo(STupleHandle* pVHandle) { return &pVHandle->pBlock->info; } SSortExecInfo tsortGetSortExecInfo(SSortHandle* pHandle) { SSortExecInfo info = {0}; diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index a8e4f692ab..6e4dde4ec1 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -110,6 +110,7 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) { COPY_SCALAR_FIELD(tableId); COPY_SCALAR_FIELD(tableType); COPY_SCALAR_FIELD(colId); + COPY_SCALAR_FIELD(projIdx); COPY_SCALAR_FIELD(colType); COPY_SCALAR_FIELD(hasIndex); COPY_CHAR_ARRAY_FIELD(dbName); @@ -358,6 +359,8 @@ static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) { COPY_SCALAR_FIELD(requireDataOrder); COPY_SCALAR_FIELD(resultDataOrder); COPY_SCALAR_FIELD(groupAction); + COPY_SCALAR_FIELD(inputTsOrder); + COPY_SCALAR_FIELD(outputTsOrder); return TSDB_CODE_SUCCESS; } @@ -404,7 +407,6 @@ static int32_t logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) { CLONE_NODE_FIELD(pOnConditions); CLONE_NODE_FIELD(pColEqualOnConditions); COPY_SCALAR_FIELD(isSingleTableJoin); - COPY_SCALAR_FIELD(inputTsOrder); return TSDB_CODE_SUCCESS; } @@ -482,8 +484,6 @@ static int32_t logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* p COPY_SCALAR_FIELD(igExpired); COPY_SCALAR_FIELD(igCheckUpdate); COPY_SCALAR_FIELD(windowAlgo); - COPY_SCALAR_FIELD(inputTsOrder); - COPY_SCALAR_FIELD(outputTsOrder); return TSDB_CODE_SUCCESS; } @@ -495,7 +495,6 @@ static int32_t logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) { CLONE_NODE_FIELD(pWStartTs); CLONE_NODE_FIELD(pValues); COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow)); - COPY_SCALAR_FIELD(inputTsOrder); return TSDB_CODE_SUCCESS; } @@ -544,6 +543,8 @@ static int32_t physiNodeCopy(const SPhysiNode* pSrc, SPhysiNode* pDst) { CLONE_NODE_FIELD_EX(pOutputDataBlockDesc, SDataBlockDescNode*); CLONE_NODE_FIELD(pConditions); CLONE_NODE_LIST_FIELD(pChildren); + COPY_SCALAR_FIELD(inputTsOrder); + COPY_SCALAR_FIELD(outputTsOrder); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 6bf1ad01a8..0b449c5bfe 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -1904,9 +1904,6 @@ static int32_t physiJoinNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddIntegerToObject(pJson, jkJoinPhysiPlanJoinType, pNode->joinType); } - if (TSDB_CODE_SUCCESS == code) { - code = tjsonAddIntegerToObject(pJson, jkJoinPhysiPlanInputTsOrder, pNode->inputTsOrder); - } if (TSDB_CODE_SUCCESS == code) { code = tjsonAddObject(pJson, jkJoinPhysiPlanMergeCondition, nodeToJson, pNode->pMergeCondition); } @@ -1929,9 +1926,6 @@ static int32_t jsonToPhysiJoinNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { tjsonGetNumberValue(pJson, jkJoinPhysiPlanJoinType, pNode->joinType, code); } - if (TSDB_CODE_SUCCESS == code) { - tjsonGetNumberValue(pJson, jkJoinPhysiPlanInputTsOrder, pNode->inputTsOrder, code); - } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkJoinPhysiPlanOnConditions, &pNode->pOnConditions); } @@ -2150,7 +2144,6 @@ static const char* jkWindowPhysiPlanWatermark = "Watermark"; static const char* jkWindowPhysiPlanDeleteMark = "DeleteMark"; static const char* jkWindowPhysiPlanIgnoreExpired = "IgnoreExpired"; static const char* jkWindowPhysiPlanInputTsOrder = "InputTsOrder"; -static const char* jkWindowPhysiPlanOutputTsOrder = "outputTsOrder"; static const char* jkWindowPhysiPlanMergeDataBlock = "MergeDataBlock"; static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) { @@ -2181,12 +2174,6 @@ static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanIgnoreExpired, pNode->igExpired); } - if (TSDB_CODE_SUCCESS == code) { - code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanInputTsOrder, pNode->inputTsOrder); - } - if (TSDB_CODE_SUCCESS == code) { - code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanOutputTsOrder, pNode->outputTsOrder); - } if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkWindowPhysiPlanMergeDataBlock, pNode->mergeDataBlock); } @@ -2222,12 +2209,6 @@ static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetTinyIntValue(pJson, jkWindowPhysiPlanIgnoreExpired, &pNode->igExpired); } - if (TSDB_CODE_SUCCESS == code) { - tjsonGetNumberValue(pJson, jkWindowPhysiPlanInputTsOrder, pNode->inputTsOrder, code); - } - if (TSDB_CODE_SUCCESS == code) { - tjsonGetNumberValue(pJson, jkWindowPhysiPlanOutputTsOrder, pNode->outputTsOrder, code); - } if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkWindowPhysiPlanMergeDataBlock, &pNode->mergeDataBlock); } @@ -2294,7 +2275,6 @@ static const char* jkFillPhysiPlanWStartTs = "WStartTs"; static const char* jkFillPhysiPlanValues = "Values"; static const char* jkFillPhysiPlanStartTime = "StartTime"; static const char* jkFillPhysiPlanEndTime = "EndTime"; -static const char* jkFillPhysiPlanInputTsOrder = "inputTsOrder"; static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) { const SFillPhysiNode* pNode = (const SFillPhysiNode*)pObj; @@ -2321,9 +2301,6 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanEndTime, pNode->timeRange.ekey); } - if (TSDB_CODE_SUCCESS == code) { - code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanInputTsOrder, pNode->inputTsOrder); - } return code; } @@ -2353,9 +2330,6 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanEndTime, &pNode->timeRange.ekey); } - if (TSDB_CODE_SUCCESS == code) { - tjsonGetNumberValue(pJson, jkFillPhysiPlanInputTsOrder, pNode->inputTsOrder, code); - } return code; } @@ -3053,6 +3027,7 @@ static const char* jkColumnTableId = "TableId"; static const char* jkColumnTableType = "TableType"; static const char* jkColumnColId = "ColId"; static const char* jkColumnColType = "ColType"; +static const char* jkColumnProjId = "ProjId"; static const char* jkColumnDbName = "DbName"; static const char* jkColumnTableName = "TableName"; static const char* jkColumnTableAlias = "TableAlias"; @@ -3073,6 +3048,9 @@ static int32_t columnNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddIntegerToObject(pJson, jkColumnColId, pNode->colId); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkColumnProjId, pNode->projIdx); + } if (TSDB_CODE_SUCCESS == code) { code = tjsonAddIntegerToObject(pJson, jkColumnColType, pNode->colType); } @@ -3111,6 +3089,9 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetSmallIntValue(pJson, jkColumnColId, &pNode->colId); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetSmallIntValue(pJson, jkColumnProjId, &pNode->projIdx); + } if (TSDB_CODE_SUCCESS == code) { tjsonGetNumberValue(pJson, jkColumnColType, pNode->colType, code); } diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 0631b91323..1ca37defa4 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -1851,7 +1851,9 @@ enum { PHY_NODE_CODE_CONDITIONS, PHY_NODE_CODE_CHILDREN, PHY_NODE_CODE_LIMIT, - PHY_NODE_CODE_SLIMIT + PHY_NODE_CODE_SLIMIT, + PHY_NODE_CODE_INPUT_TS_ORDER, + PHY_NODE_CODE_OUTPUT_TS_ORDER }; static int32_t physiNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { @@ -1870,6 +1872,12 @@ static int32_t physiNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeObj(pEncoder, PHY_NODE_CODE_SLIMIT, nodeToMsg, pNode->pSlimit); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeEnum(pEncoder, PHY_NODE_CODE_INPUT_TS_ORDER, pNode->inputTsOrder); + } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeEnum(pEncoder, PHY_NODE_CODE_OUTPUT_TS_ORDER, pNode->outputTsOrder); + } return code; } @@ -1896,6 +1904,12 @@ static int32_t msgToPhysiNode(STlvDecoder* pDecoder, void* pObj) { case PHY_NODE_CODE_SLIMIT: code = msgToNodeFromTlv(pTlv, (void**)&pNode->pSlimit); break; + case PHY_NODE_CODE_INPUT_TS_ORDER: + code = tlvDecodeEnum(pTlv, &pNode->inputTsOrder, sizeof(pNode->inputTsOrder)); + break; + case PHY_NODE_CODE_OUTPUT_TS_ORDER: + code = tlvDecodeEnum(pTlv, &pNode->outputTsOrder, sizeof(pNode->outputTsOrder)); + break; default: break; } @@ -2339,9 +2353,6 @@ static int32_t physiJoinNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_TARGETS, nodeListToMsg, pNode->pTargets); } - if (TSDB_CODE_SUCCESS == code) { - code = tlvEncodeEnum(pEncoder, PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER, pNode->inputTsOrder); - } if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_TAG_EQUAL_CONDITIONS, nodeToMsg, pNode->pColEqualOnConditions); } @@ -2370,9 +2381,6 @@ static int32_t msgToPhysiJoinNode(STlvDecoder* pDecoder, void* pObj) { case PHY_SORT_MERGE_JOIN_CODE_TARGETS: code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets); break; - case PHY_SORT_MERGE_JOIN_CODE_INPUT_TS_ORDER: - code = tlvDecodeEnum(pTlv, &pNode->inputTsOrder, sizeof(pNode->inputTsOrder)); - break; case PHY_SORT_MERGE_JOIN_CODE_TAG_EQUAL_CONDITIONS: code = msgToNodeFromTlv(pTlv, (void**)&pNode->pColEqualOnConditions); break; @@ -2675,12 +2683,6 @@ static int32_t physiWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeI8(pEncoder, PHY_WINDOW_CODE_IG_EXPIRED, pNode->igExpired); } - if (TSDB_CODE_SUCCESS == code) { - code = tlvEncodeEnum(pEncoder, PHY_WINDOW_CODE_INPUT_TS_ORDER, pNode->inputTsOrder); - } - if (TSDB_CODE_SUCCESS == code) { - code = tlvEncodeEnum(pEncoder, PHY_WINDOW_CODE_OUTPUT_TS_ORDER, pNode->outputTsOrder); - } if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeBool(pEncoder, PHY_WINDOW_CODE_MERGE_DATA_BLOCK, pNode->mergeDataBlock); } @@ -2722,12 +2724,6 @@ static int32_t msgToPhysiWindowNode(STlvDecoder* pDecoder, void* pObj) { case PHY_WINDOW_CODE_IG_EXPIRED: code = tlvDecodeI8(pTlv, &pNode->igExpired); break; - case PHY_WINDOW_CODE_INPUT_TS_ORDER: - code = tlvDecodeEnum(pTlv, &pNode->inputTsOrder, sizeof(pNode->inputTsOrder)); - break; - case PHY_WINDOW_CODE_OUTPUT_TS_ORDER: - code = tlvDecodeEnum(pTlv, &pNode->outputTsOrder, sizeof(pNode->outputTsOrder)); - break; case PHY_WINDOW_CODE_MERGE_DATA_BLOCK: code = tlvDecodeBool(pTlv, &pNode->mergeDataBlock); break; @@ -2846,9 +2842,6 @@ static int32_t physiFillNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeObj(pEncoder, PHY_FILL_CODE_TIME_RANGE, timeWindowToMsg, &pNode->timeRange); } - if (TSDB_CODE_SUCCESS == code) { - code = tlvEncodeEnum(pEncoder, PHY_FILL_CODE_INPUT_TS_ORDER, pNode->inputTsOrder); - } return code; } @@ -2881,9 +2874,6 @@ static int32_t msgToPhysiFillNode(STlvDecoder* pDecoder, void* pObj) { case PHY_FILL_CODE_TIME_RANGE: code = tlvDecodeObjFromTlv(pTlv, msgToTimeWindow, (void**)&pNode->timeRange); break; - case PHY_FILL_CODE_INPUT_TS_ORDER: - code = tlvDecodeEnum(pTlv, &pNode->inputTsOrder, sizeof(pNode->inputTsOrder)); - break; default: break; } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 5bbc9acdad..c41a80d5aa 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -436,7 +436,7 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect pJoin->joinType = pJoinTable->joinType; pJoin->isSingleTableJoin = pJoinTable->table.singleTable; - pJoin->inputTsOrder = ORDER_ASC; + pJoin->node.inputTsOrder = ORDER_ASC; pJoin->node.groupAction = GROUP_ACTION_CLEAR; pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL; pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL; @@ -741,8 +741,8 @@ static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStm pWindow->igExpired = pCxt->pPlanCxt->igExpired; pWindow->igCheckUpdate = pCxt->pPlanCxt->igCheckUpdate; } - pWindow->inputTsOrder = ORDER_ASC; - pWindow->outputTsOrder = ORDER_ASC; + pWindow->node.inputTsOrder = ORDER_ASC; + pWindow->node.outputTsOrder = ORDER_ASC; int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs); if (TSDB_CODE_SUCCESS == code) { @@ -972,7 +972,7 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect pFill->node.groupAction = getGroupAction(pCxt, pSelect); pFill->node.requireDataOrder = getRequireDataOrder(true, pSelect); pFill->node.resultDataOrder = pFill->node.requireDataOrder; - pFill->inputTsOrder = ORDER_ASC; + pFill->node.inputTsOrder = 0; int32_t code = partFillExprs(pSelect, &pFill->pFillExprs, &pFill->pNotFillExprs); if (TSDB_CODE_SUCCESS == code) { @@ -1045,6 +1045,20 @@ static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect if (NULL == pSort->pSortKeys) { code = TSDB_CODE_OUT_OF_MEMORY; } + SNode* pNode = NULL; + SOrderByExprNode* firstSortKey = (SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0); + if (firstSortKey->pExpr->type == QUERY_NODE_COLUMN) { + SColumnNode* pCol = (SColumnNode*)firstSortKey->pExpr; + int16_t projIdx = 1; + FOREACH(pNode, pSelect->pProjectionList) { + SExprNode* pExpr = (SExprNode*)pNode; + if (0 == strcmp(pCol->node.aliasName, pExpr->aliasName)) { + pCol->projIdx = projIdx; break; + } + projIdx++; + } + } + pSort->node.outputTsOrder = firstSortKey->order; } if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 8b75fe6b33..c83af7afa0 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -116,25 +116,33 @@ static EDealRes optRebuildTbanme(SNode** pNode, void* pContext) { return DEAL_RES_CONTINUE; } -static void optSetParentOrder(SLogicNode* pNode, EOrder order) { +static void optSetParentOrder(SLogicNode* pNode, EOrder order, SLogicNode* pNodeForcePropagate) { if (NULL == pNode) { return; } + pNode->inputTsOrder = order; switch (nodeType(pNode)) { - case QUERY_NODE_LOGIC_PLAN_WINDOW: - ((SWindowLogicNode*)pNode)->inputTsOrder = order; - // window has a sorting function, and the operator behind it uses its output order - return; + // for those nodes that will change the order, stop propagating + //case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_JOIN: - ((SJoinLogicNode*)pNode)->inputTsOrder = order; - break; - case QUERY_NODE_LOGIC_PLAN_FILL: - ((SFillLogicNode*)pNode)->inputTsOrder = order; + case QUERY_NODE_LOGIC_PLAN_AGG: + case QUERY_NODE_LOGIC_PLAN_SORT: + if (pNode == pNodeForcePropagate) { + pNode->outputTsOrder = order; + break; + } else + return; + case QUERY_NODE_LOGIC_PLAN_WINDOW: + // Window output ts order default to be asc, and changed when doing sort by primary key optimization. + // We stop propagate the original order to parents. + // Use window output ts order instead. + order = pNode->outputTsOrder; break; default: + pNode->outputTsOrder = order; break; } - optSetParentOrder(pNode->pParent, order); + optSetParentOrder(pNode->pParent, order, pNodeForcePropagate); } EDealRes scanPathOptHaveNormalColImpl(SNode* pNode, void* pContext) { @@ -339,12 +347,12 @@ static void scanPathOptSetScanOrder(EScanOrder scanOrder, SScanLogicNode* pScan) case SCAN_ORDER_ASC: pScan->scanSeq[0] = 1; pScan->scanSeq[1] = 0; - optSetParentOrder(pScan->node.pParent, ORDER_ASC); + optSetParentOrder(pScan->node.pParent, ORDER_ASC, NULL); break; case SCAN_ORDER_DESC: pScan->scanSeq[0] = 0; pScan->scanSeq[1] = 1; - optSetParentOrder(pScan->node.pParent, ORDER_DESC); + optSetParentOrder(pScan->node.pParent, ORDER_DESC, NULL); break; case SCAN_ORDER_BOTH: pScan->scanSeq[0] = 1; @@ -1239,6 +1247,7 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS if ((ORDER_DESC == order && pScan->scanSeq[0] > 0) || (ORDER_ASC == order && pScan->scanSeq[1] > 0)) { TSWAP(pScan->scanSeq[0], pScan->scanSeq[1]); } + pScan->node.outputTsOrder = order; if (TSDB_SUPER_TABLE == pScan->tableType) { pScan->scanType = SCAN_TYPE_TABLE_MERGE; pScan->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL; @@ -1246,9 +1255,9 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS } pScan->sortPrimaryKey = true; } else if (QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pSequencingNode)) { - ((SWindowLogicNode*)pSequencingNode)->outputTsOrder = order; + ((SLogicNode*)pSequencingNode)->outputTsOrder = order; } - optSetParentOrder(((SLogicNode*)pSequencingNode)->pParent, order); + optSetParentOrder(((SLogicNode*)pSequencingNode)->pParent, order, (SLogicNode*)pSort); } SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSort->node.pChildren, 0); @@ -2881,10 +2890,51 @@ static int32_t tableCountScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo return code; } +static SSortLogicNode* sortNonPriKeySatisfied(SLogicNode* pNode) { + if (QUERY_NODE_LOGIC_PLAN_SORT != nodeType(pNode)) { + return NULL; + } + SSortLogicNode* pSort = (SSortLogicNode*)pNode; + if (sortPriKeyOptIsPriKeyOrderBy(pSort->pSortKeys) || 1 != LIST_LENGTH(pSort->node.pChildren)) { + return NULL; + } + + SNode* pSortKeyNode = ((SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0))->pExpr; + if (nodeType(pSortKeyNode) != QUERY_NODE_COLUMN || ((SColumnNode*)pSortKeyNode)->projIdx != 1 || + ((SColumnNode*)pSortKeyNode)->node.resType.type != TSDB_DATA_TYPE_TIMESTAMP) { + return NULL; + } + return pSort; +} + +static bool sortNonPriKeyShouldOptimize(SLogicNode* pNode, void* pInfo) { + SSortLogicNode* pSort = sortNonPriKeySatisfied(pNode); + if (!pSort) return false; + SNodeList* pSortNodeList = pInfo; + nodesListAppend(pSortNodeList, (SNode*)pSort); + return false; +} + +static int32_t sortNonPriKeyOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { + SNodeList* pNodeList = nodesMakeList(); + optFindEligibleNode(pLogicSubplan->pNode, sortNonPriKeyShouldOptimize, pNodeList); + SNode* pNode = NULL; + FOREACH(pNode, pNodeList) { + SSortLogicNode* pSort = (SSortLogicNode*)pNode; + SOrderByExprNode* pOrderByExpr = (SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0); + pSort->node.outputTsOrder = pOrderByExpr->order; + optSetParentOrder(pSort->node.pParent, pOrderByExpr->order, NULL); + } + pCxt->optimized = false; + nodesClearList(pNodeList); + return TSDB_CODE_SUCCESS; +} + // clang-format off static const SOptimizeRule optimizeRuleSet[] = { {.pName = "ScanPath", .optimizeFunc = scanPathOptimize}, {.pName = "PushDownCondition", .optimizeFunc = pushDownCondOptimize}, + {.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize}, {.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize}, {.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize}, {.pName = "PartitionTags", .optimizeFunc = partTagsOptimize}, diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 4f57193856..9ae96bdf8b 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -366,6 +366,8 @@ static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode TSWAP(pPhysiNode->pLimit, pLogicNode->pLimit); TSWAP(pPhysiNode->pSlimit, pLogicNode->pSlimit); + pPhysiNode->inputTsOrder = pLogicNode->inputTsOrder; + pPhysiNode->outputTsOrder = pLogicNode->outputTsOrder; int32_t code = createDataBlockDesc(pCxt, pLogicNode->pTargets, &pPhysiNode->pOutputDataBlockDesc); if (TSDB_CODE_SUCCESS != code) { @@ -676,7 +678,7 @@ static int32_t createJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren int32_t code = TSDB_CODE_SUCCESS; pJoin->joinType = pJoinLogicNode->joinType; - pJoin->inputTsOrder = pJoinLogicNode->inputTsOrder; + pJoin->node.inputTsOrder = pJoinLogicNode->node.inputTsOrder; setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->pMergeCondition, &pJoin->pMergeCondition); if (TSDB_CODE_SUCCESS == code) { @@ -939,6 +941,11 @@ static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList* SNodeList* pFuncs = NULL; int32_t code = rewritePrecalcExprs(pCxt, pFuncLogicNode->pFuncs, &pPrecalcExprs, &pFuncs); + if (pIdfRowsFunc->node.inputTsOrder == 0) { + // default to asc + pIdfRowsFunc->node.inputTsOrder = TSDB_ORDER_ASC; + } + SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc); // push down expression to pOutputDataBlockDesc of child node if (TSDB_CODE_SUCCESS == code && NULL != pPrecalcExprs) { @@ -1156,9 +1163,12 @@ static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList* pWindow->watermark = pWindowLogicNode->watermark; pWindow->deleteMark = pWindowLogicNode->deleteMark; pWindow->igExpired = pWindowLogicNode->igExpired; - pWindow->inputTsOrder = pWindowLogicNode->inputTsOrder; - pWindow->outputTsOrder = pWindowLogicNode->outputTsOrder; pWindow->mergeDataBlock = (GROUP_ACTION_KEEP == pWindowLogicNode->node.groupAction ? false : true); + pWindow->node.inputTsOrder = pWindowLogicNode->node.inputTsOrder; + pWindow->node.outputTsOrder = pWindowLogicNode->node.outputTsOrder; + if (nodeType(pWindow) == QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL) { + pWindow->node.inputTsOrder = pWindowLogicNode->node.outputTsOrder; + } SNodeList* pPrecalcExprs = NULL; SNodeList* pFuncs = NULL; @@ -1492,7 +1502,7 @@ static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren pFill->mode = pFillNode->mode; pFill->timeRange = pFillNode->timeRange; - pFill->inputTsOrder = pFillNode->inputTsOrder; + pFill->node.inputTsOrder = pFillNode->node.inputTsOrder; SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc); int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->pFillExprs, &pFill->pFillExprs); @@ -1563,6 +1573,7 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SMergeLogicNode* pM pMerge->srcGroupId = pMergeLogicNode->srcGroupId; pMerge->groupSort = pMergeLogicNode->groupSort; pMerge->ignoreGroupId = pMergeLogicNode->ignoreGroupId; + pMerge->node.inputTsOrder = pMergeLogicNode->node.outputTsOrder; int32_t code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 504db0d07b..bb129e1fa5 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -534,7 +534,9 @@ static int32_t stbSplGetNumOfVgroups(SLogicNode* pNode) { static int32_t stbSplRewriteFromMergeNode(SMergeLogicNode* pMerge, SLogicNode* pNode) { int32_t code = TSDB_CODE_SUCCESS; - + pMerge->node.inputTsOrder = pNode->inputTsOrder; + pMerge->node.outputTsOrder = pNode->outputTsOrder; + switch (nodeType(pNode)) { case QUERY_NODE_LOGIC_PLAN_PROJECT: { SProjectLogicNode *pLogicNode = (SProjectLogicNode*)pNode; @@ -631,7 +633,7 @@ static int32_t stbSplSplitIntervalForBatch(SSplitContext* pCxt, SStableSplitInfo ((SWindowLogicNode*)pInfo->pSplitNode)->windowAlgo = INTERVAL_ALGO_MERGE; SNodeList* pMergeKeys = NULL; code = stbSplCreateMergeKeysByPrimaryKey(((SWindowLogicNode*)pInfo->pSplitNode)->pTspk, - ((SWindowLogicNode*)pInfo->pSplitNode)->outputTsOrder, &pMergeKeys); + ((SWindowLogicNode*)pInfo->pSplitNode)->node.outputTsOrder, &pMergeKeys); if (TSDB_CODE_SUCCESS == code) { code = stbSplCreateMergeNode(pCxt, NULL, pInfo->pSplitNode, pMergeKeys, pPartWindow, true); } @@ -721,7 +723,7 @@ static int32_t stbSplSplitSessionOrStateForBatch(SSplitContext* pCxt, SStableSpl SNodeList* pMergeKeys = NULL; int32_t code = stbSplCreateMergeKeysByPrimaryKey(((SWindowLogicNode*)pWindow)->pTspk, - ((SWindowLogicNode*)pWindow)->inputTsOrder, &pMergeKeys); + ((SWindowLogicNode*)pWindow)->node.inputTsOrder, &pMergeKeys); if (TSDB_CODE_SUCCESS == code) { code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pChild, pMergeKeys, (SLogicNode*)pChild, true); diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 801e6aa1bd..52b4a46d59 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -184,6 +184,7 @@ ,,y,script,./test.sh -f tsim/query/forceFill.sim ,,y,script,./test.sh -f tsim/query/emptyTsRange.sim ,,y,script,./test.sh -f tsim/query/partitionby.sim +,,y,script,./test.sh -f tsim/query/explain_tsorder.sim ,,y,script,./test.sh -f tsim/qnode/basic1.sim ,,y,script,./test.sh -f tsim/snode/basic1.sim ,,y,script,./test.sh -f tsim/mnode/basic1.sim diff --git a/tests/script/tsim/query/explain_tsorder.sim b/tests/script/tsim/query/explain_tsorder.sim new file mode 100644 index 0000000000..202f85bcf0 --- /dev/null +++ b/tests/script/tsim/query/explain_tsorder.sim @@ -0,0 +1,37 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +sql create database test +sql use test +sql CREATE STABLE `meters` (`ts` TIMESTAMP, `c2` INT) TAGS (`cc` VARCHAR(3)) + + +sql insert into d1 using meters tags("MY") values("2022-05-15 00:01:08.000 ",234) +sql insert into d1 using meters tags("MY") values("2022-05-16 00:01:08.000 ",136) +sql insert into d1 using meters tags("MY") values("2022-05-17 00:01:08.000 ", 59) +sql insert into d1 using meters tags("MY") values("2022-05-18 00:01:08.000 ", 58) +sql insert into d1 using meters tags("MY") values("2022-05-19 00:01:08.000 ",243) +sql insert into d1 using meters tags("MY") values("2022-05-20 00:01:08.000 ",120) +sql insert into d1 using meters tags("MY") values("2022-05-21 00:01:08.000 ", 11) +sql insert into d1 using meters tags("MY") values("2022-05-22 00:01:08.000 ",196) +sql insert into d1 using meters tags("MY") values("2022-05-23 00:01:08.000 ",116) +sql insert into d1 using meters tags("MY") values("2022-05-24 00:01:08.000 ",210) + +sql insert into d2 using meters tags("HT") values("2022-05-15 00:01:08.000", 234) +sql insert into d2 using meters tags("HT") values("2022-05-16 00:01:08.000", 136) +sql insert into d2 using meters tags("HT") values("2022-05-17 00:01:08.000", 59) +sql insert into d2 using meters tags("HT") values("2022-05-18 00:01:08.000", 58) +sql insert into d2 using meters tags("HT") values("2022-05-19 00:01:08.000", 243) +sql insert into d2 using meters tags("HT") values("2022-05-20 00:01:08.000", 120) +sql insert into d2 using meters tags("HT") values("2022-05-21 00:01:08.000", 11) +sql insert into d2 using meters tags("HT") values("2022-05-22 00:01:08.000", 196) +sql insert into d2 using meters tags("HT") values("2022-05-23 00:01:08.000", 116) +sql insert into d2 using meters tags("HT") values("2022-05-24 00:01:08.000", 210) + +#sleep 10000000 +system taos -P7100 -s 'source tsim/query/t/explain_tsorder.sql' | grep -v 'Query OK' | grep -v 'Client Version' > /tmp/explain_tsorder.result +system echo ----------------------diff start----------------------- +system git diff --exit-code --color tsim/query/r/explain_tsorder.result /tmp/explain_tsorder.result +system echo ----------------------diff succeed----------------------- diff --git a/tests/script/tsim/query/r/explain_tsorder.result b/tests/script/tsim/query/r/explain_tsorder.result new file mode 100644 index 0000000000..deaa09015f --- /dev/null +++ b/tests/script/tsim/query/r/explain_tsorder.result @@ -0,0 +1,2560 @@ +Copyright (c) 2022 by TDengine, all rights reserved. + +taos> source tsim/query/t/explain_tsorder.sql +taos> use test; +Database changed. + +taos> explain verbose true select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 7.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 8.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 9.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 10.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 11.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 12.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 13.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 14.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 15.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 16.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 17.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart asc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 7.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 8.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 9.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 10.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 11.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 12.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 13.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 14.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 15.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 16.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 17.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart asc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 7.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 8.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 9.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 10.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 11.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=asc output_order=asc ) +*************************** 12.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 13.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 14.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 15.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 16.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 17.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=asc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 7.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 8.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 9.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 10.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 11.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=asc output_order=desc ) +*************************** 12.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 13.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 14.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 15.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 16.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 17.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=asc output_order=desc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=desc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=desc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=desc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=desc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 14.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 16.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 17.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 20.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 23.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 24.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 25.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 26.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 27.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 32.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 33.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=8 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=16 groups=1 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=16 groups=1 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=16 groups=1 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Aggragate (functions=1 width=16 groups=1 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 5.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 6.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 8.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 10.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 14.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 15.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 16.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 18.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 19.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 20.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 22.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 24.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 29.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 31.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 33.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 34.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 35.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) where a > 10000 and a < 20000 interval(10s) fill(NULL) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=null width=24 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [10001, 19999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column a (functions=2 width=16 input_order=asc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=unknown ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 16.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 18.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 19.row *************************** +QUERY_PLAN: Filter: ((a > 10000) AND (a < 20000)) +*************************** 20.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 21.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 22.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 23.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 24.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 25.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 30.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 31.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 33.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 34.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 37.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 38.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 39.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 40.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 41.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 42.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > 10000 and a < 20000 interval(10s) fill(NULL) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=null width=24 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [10001, 19999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column a (functions=2 width=16 input_order=desc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=desc ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 16.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 17.row *************************** +QUERY_PLAN: Filter: ((a > 10000) AND (a < 20000)) +*************************** 18.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 19.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 21.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 22.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 23.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 24.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 25.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 28.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 29.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 31.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 32.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 33.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 34.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 37.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 38.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 39.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 40.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > 10000 and b < 20000 interval(10s) fill(NULL) order by d\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=null width=24 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [10001, 19999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column b (functions=2 width=16 input_order=desc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=2 width=16 input_order=desc ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=2 width=16) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 16.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=2 width=16 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 18.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 19.row *************************** +QUERY_PLAN: Filter: ((b > 10000) AND (b < 20000)) +*************************** 20.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 21.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 22.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 23.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 24.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 25.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 30.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 31.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 33.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 34.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 37.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 38.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 39.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 40.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 41.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 42.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > 10000 and b < 20000 interval(10s) fill(NULL) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=1 width=8) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=1 width=8 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=null width=24 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [10001, 19999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column b (functions=2 width=16 input_order=desc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=2 width=16 input_order=desc ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=2 width=16) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 16.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=2 width=16 input_order=asc output_order=asc) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=2 width=16 +*************************** 18.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 19.row *************************** +QUERY_PLAN: Filter: ((b > 10000) AND (b < 20000)) +*************************** 20.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 21.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 22.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 23.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 24.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 25.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 28.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 29.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 30.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 31.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 33.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 34.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 37.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 38.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 39.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 40.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 41.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 42.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart desc; + _wstart | last(ts) | avg(c2) | +================================================================================ + 2022-05-24 00:01:00.000 | 2022-05-24 00:01:08.000 | 210.000000000 | + 2022-05-23 00:01:00.000 | 2022-05-23 00:01:08.000 | 116.000000000 | + 2022-05-22 00:01:00.000 | 2022-05-22 00:01:08.000 | 196.000000000 | + 2022-05-21 00:01:00.000 | 2022-05-21 00:01:08.000 | 11.000000000 | + 2022-05-20 00:01:00.000 | 2022-05-20 00:01:08.000 | 120.000000000 | + 2022-05-19 00:01:00.000 | 2022-05-19 00:01:08.000 | 243.000000000 | + 2022-05-18 00:01:00.000 | 2022-05-18 00:01:08.000 | 58.000000000 | + 2022-05-17 00:01:00.000 | 2022-05-17 00:01:08.000 | 59.000000000 | + 2022-05-16 00:01:00.000 | 2022-05-16 00:01:08.000 | 136.000000000 | + 2022-05-15 00:01:00.000 | 2022-05-15 00:01:08.000 | 234.000000000 | + +taos> select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart asc; + _wstart | last(ts) | avg(c2) | +================================================================================ + 2022-05-15 00:01:00.000 | 2022-05-15 00:01:08.000 | 234.000000000 | + 2022-05-16 00:01:00.000 | 2022-05-16 00:01:08.000 | 136.000000000 | + 2022-05-17 00:01:00.000 | 2022-05-17 00:01:08.000 | 59.000000000 | + 2022-05-18 00:01:00.000 | 2022-05-18 00:01:08.000 | 58.000000000 | + 2022-05-19 00:01:00.000 | 2022-05-19 00:01:08.000 | 243.000000000 | + 2022-05-20 00:01:00.000 | 2022-05-20 00:01:08.000 | 120.000000000 | + 2022-05-21 00:01:00.000 | 2022-05-21 00:01:08.000 | 11.000000000 | + 2022-05-22 00:01:00.000 | 2022-05-22 00:01:08.000 | 196.000000000 | + 2022-05-23 00:01:00.000 | 2022-05-23 00:01:08.000 | 116.000000000 | + 2022-05-24 00:01:00.000 | 2022-05-24 00:01:08.000 | 210.000000000 | + +taos> select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart asc; + _wstart | first(ts) | avg(c2) | +================================================================================ + 2022-05-15 00:01:00.000 | 2022-05-15 00:01:08.000 | 234.000000000 | + 2022-05-16 00:01:00.000 | 2022-05-16 00:01:08.000 | 136.000000000 | + 2022-05-17 00:01:00.000 | 2022-05-17 00:01:08.000 | 59.000000000 | + 2022-05-18 00:01:00.000 | 2022-05-18 00:01:08.000 | 58.000000000 | + 2022-05-19 00:01:00.000 | 2022-05-19 00:01:08.000 | 243.000000000 | + 2022-05-20 00:01:00.000 | 2022-05-20 00:01:08.000 | 120.000000000 | + 2022-05-21 00:01:00.000 | 2022-05-21 00:01:08.000 | 11.000000000 | + 2022-05-22 00:01:00.000 | 2022-05-22 00:01:08.000 | 196.000000000 | + 2022-05-23 00:01:00.000 | 2022-05-23 00:01:08.000 | 116.000000000 | + 2022-05-24 00:01:00.000 | 2022-05-24 00:01:08.000 | 210.000000000 | + +taos> select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart desc; + _wstart | first(ts) | avg(c2) | +================================================================================ + 2022-05-24 00:01:00.000 | 2022-05-24 00:01:08.000 | 210.000000000 | + 2022-05-23 00:01:00.000 | 2022-05-23 00:01:08.000 | 116.000000000 | + 2022-05-22 00:01:00.000 | 2022-05-22 00:01:08.000 | 196.000000000 | + 2022-05-21 00:01:00.000 | 2022-05-21 00:01:08.000 | 11.000000000 | + 2022-05-20 00:01:00.000 | 2022-05-20 00:01:08.000 | 120.000000000 | + 2022-05-19 00:01:00.000 | 2022-05-19 00:01:08.000 | 243.000000000 | + 2022-05-18 00:01:00.000 | 2022-05-18 00:01:08.000 | 58.000000000 | + 2022-05-17 00:01:00.000 | 2022-05-17 00:01:08.000 | 59.000000000 | + 2022-05-16 00:01:00.000 | 2022-05-16 00:01:08.000 | 136.000000000 | + 2022-05-15 00:01:00.000 | 2022-05-15 00:01:08.000 | 234.000000000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d + d | +========================== + 2022-05-15 00:01:00.000 | + 2022-05-16 00:01:00.000 | + 2022-05-17 00:01:00.000 | + 2022-05-18 00:01:00.000 | + 2022-05-19 00:01:00.000 | + 2022-05-20 00:01:00.000 | + 2022-05-21 00:01:00.000 | + 2022-05-22 00:01:00.000 | + 2022-05-23 00:01:00.000 | + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d; + d | +========================== + 2022-05-15 00:01:00.000 | + 2022-05-16 00:01:00.000 | + 2022-05-17 00:01:00.000 | + 2022-05-18 00:01:00.000 | + 2022-05-19 00:01:00.000 | + 2022-05-20 00:01:00.000 | + 2022-05-21 00:01:00.000 | + 2022-05-22 00:01:00.000 | + 2022-05-23 00:01:00.000 | + 2022-05-24 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + 2022-05-23 00:01:00.000 | + 2022-05-22 00:01:00.000 | + 2022-05-21 00:01:00.000 | + 2022-05-20 00:01:00.000 | + 2022-05-19 00:01:00.000 | + 2022-05-18 00:01:00.000 | + 2022-05-17 00:01:00.000 | + 2022-05-16 00:01:00.000 | + 2022-05-15 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d desc; + d | +========================== + 2022-05-24 00:01:00.000 | + 2022-05-23 00:01:00.000 | + 2022-05-22 00:01:00.000 | + 2022-05-21 00:01:00.000 | + 2022-05-20 00:01:00.000 | + 2022-05-19 00:01:00.000 | + 2022-05-18 00:01:00.000 | + 2022-05-17 00:01:00.000 | + 2022-05-16 00:01:00.000 | + 2022-05-15 00:01:00.000 | + +taos> select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-19 00:01:08.000' interval(10s) order by d; + d | +========================== + 2022-05-15 00:01:00.000 | + 2022-05-16 00:01:00.000 | + 2022-05-17 00:01:00.000 | + 2022-05-18 00:01:00.000 | + 2022-05-19 00:01:00.000 | + +taos> select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > '2022-05-15 00:01:00.000' and b < '2022-05-19 00:01:08.000' interval(10s) order by d; + d | +========================== + 2022-05-15 00:01:08.000 | + 2022-05-16 00:01:08.000 | + 2022-05-17 00:01:08.000 | + 2022-05-18 00:01:08.000 | + 2022-05-24 00:01:08.000 | + +taos> select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > '2022-05-15 00:01:00.000' and b < '2022-05-19 00:01:08.000' interval(10s) order by d desc; + d | +========================== + 2022-05-24 00:01:08.000 | + 2022-05-18 00:01:08.000 | + 2022-05-17 00:01:08.000 | + 2022-05-16 00:01:08.000 | + 2022-05-15 00:01:08.000 | + +taos> select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc; + _wstart | d | avg(c) | +================================================================================ + 2022-05-20 20:00:00.000 | 2022-05-21 00:01:00.000 | 11.000000000 | + 2022-05-20 15:00:00.000 | 2022-05-20 18:01:00.000 | 38.250000000 | + 2022-05-20 10:00:00.000 | 2022-05-20 12:01:00.000 | 65.500000000 | + 2022-05-20 05:00:00.000 | 2022-05-20 06:01:00.000 | 92.750000000 | + 2022-05-20 00:00:00.000 | 2022-05-20 00:01:00.000 | 120.000000000 | + 2022-05-19 19:00:00.000 | 2022-05-19 19:13:00.000 | 144.600000000 | + 2022-05-19 14:00:00.000 | 2022-05-19 14:25:00.000 | 169.200000000 | + 2022-05-19 09:00:00.000 | 2022-05-19 09:37:00.000 | 193.800000000 | + 2022-05-19 04:00:00.000 | 2022-05-19 04:49:00.000 | 218.400000000 | + 2022-05-18 23:00:00.000 | 2022-05-19 00:01:00.000 | 243.000000000 | + 2022-05-18 18:00:00.000 | 2022-05-18 19:13:00.000 | 206.000000000 | + 2022-05-18 13:00:00.000 | 2022-05-18 14:25:00.000 | 169.000000000 | + 2022-05-18 08:00:00.000 | 2022-05-18 09:37:00.000 | 132.000000000 | + 2022-05-18 03:00:00.000 | 2022-05-18 04:49:00.000 | 95.000000000 | + 2022-05-17 22:00:00.000 | 2022-05-18 00:01:00.000 | 58.000000000 | + 2022-05-17 17:00:00.000 | 2022-05-17 19:13:00.000 | 58.200000000 | + 2022-05-17 12:00:00.000 | 2022-05-17 14:25:00.000 | 58.400000000 | + 2022-05-17 07:00:00.000 | 2022-05-17 09:37:00.000 | 58.600000000 | + 2022-05-17 02:00:00.000 | 2022-05-17 04:49:00.000 | 58.800000000 | + 2022-05-16 21:00:00.000 | 2022-05-17 00:01:00.000 | 59.000000000 | + 2022-05-16 16:00:00.000 | 2022-05-16 19:13:00.000 | 74.400000000 | + 2022-05-16 11:00:00.000 | 2022-05-16 14:25:00.000 | 89.800000000 | + 2022-05-16 06:00:00.000 | 2022-05-16 09:37:00.000 | 105.200000000 | + 2022-05-16 01:00:00.000 | 2022-05-16 04:49:00.000 | 120.600000000 | + 2022-05-15 20:00:00.000 | 2022-05-16 00:01:00.000 | 136.000000000 | + 2022-05-15 15:00:00.000 | 2022-05-15 18:01:00.000 | 160.500000000 | + 2022-05-15 10:00:00.000 | 2022-05-15 12:01:00.000 | 185.000000000 | + 2022-05-15 05:00:00.000 | 2022-05-15 06:01:00.000 | 209.500000000 | + 2022-05-15 00:00:00.000 | 2022-05-15 00:01:00.000 | 234.000000000 | + +taos> explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=linear width=32 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=4 width=32 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [1652544060001, 1653062467999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column a (functions=4 width=32 input_order=desc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=4 width=32 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=5h offset=0a sliding=5h +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=desc ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=desc output_order=desc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 16.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 17.row *************************** +QUERY_PLAN: Filter: ((a > 1652544060000) AND (a < 1653062468000)) +*************************** 18.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 19.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=desc output_order=desc) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 21.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 22.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, desc +*************************** 23.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 24.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 25.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 28.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 29.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 31.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 32.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 33.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 34.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=desc ) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 37.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 38.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 39.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 40.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a asc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 3.row *************************** +QUERY_PLAN: -> Fill (mode=linear width=32 input_order=asc ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=4 width=32 +*************************** 5.row *************************** +QUERY_PLAN: Time Range: [1652544060001, 1653062467999] +*************************** 6.row *************************** +QUERY_PLAN: -> Interval on Column a (functions=4 width=32 input_order=asc output_order=asc ) +*************************** 7.row *************************** +QUERY_PLAN: Output: columns=4 width=32 +*************************** 8.row *************************** +QUERY_PLAN: Time Window: interval=5h offset=0a sliding=5h +*************************** 9.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 10.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=24 input_order=asc ) +*************************** 11.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 12.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 13.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 14.row *************************** +QUERY_PLAN: -> Merge Aligned Interval on Column (functions=3 width=24 input_order=asc output_order=asc) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=3 width=24 +*************************** 16.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 17.row *************************** +QUERY_PLAN: Filter: ((a > 1652544060000) AND (a < 1653062468000)) +*************************** 18.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 19.row *************************** +QUERY_PLAN: -> SortMerge (columns=3 width=108 input_order=asc output_order=asc) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 21.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 22.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, asc +*************************** 23.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 24.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 25.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 26.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 27.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 28.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 29.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 30.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 31.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 32.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=108) +*************************** 33.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 34.row *************************** +QUERY_PLAN: -> Interval on Column ts (functions=3 width=108 input_order=desc output_order=asc ) +*************************** 35.row *************************** +QUERY_PLAN: Output: columns=3 width=108 +*************************** 36.row *************************** +QUERY_PLAN: Time Window: interval=10s offset=0a sliding=10s +*************************** 37.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 38.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 39.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 40.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select * from (select ts as a, c2 as b from meters order by c2 desc)\G; +*************************** 1.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 3.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 4.row *************************** +QUERY_PLAN: Merge Key: b desc +*************************** 5.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 7.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +*************************** 8.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 9.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 10.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 11.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 12.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 14.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 16.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 17.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 18.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> select * from (select ts as a, c2 as b from meters order by c2 desc); + a | b | +======================================== + 2022-05-19 00:01:08.000 | 243 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-21 00:01:08.000 | 11 | + +taos> explain verbose true select * from (select ts as a, c2 as b from meters order by c2 desc) order by a desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 3.row *************************** +QUERY_PLAN: -> Projection (columns=2 width=12 input_order=unknown ) +*************************** 4.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 5.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 6.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 7.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +*************************** 8.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 9.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 10.row *************************** +QUERY_PLAN: Merge Key: b desc +*************************** 11.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 12.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 13.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +*************************** 14.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 15.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 16.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 17.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 18.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 19.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 20.row *************************** +QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +*************************** 21.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 22.row *************************** +QUERY_PLAN: -> Table Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 24.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> select * from (select ts as a, c2 as b from meters order by c2 desc) order by a desc; + a | b | +======================================== + 2022-05-24 00:01:08.000 | 210 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-15 00:01:08.000 | 234 | + +taos> explain verbose true select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=16 input_order=unknown ) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=16 +*************************** 3.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> Inner join (columns=4 width=24 input_order=asc ) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=4 width=24 +*************************** 7.row *************************** +QUERY_PLAN: Join Cond: (`test`.`a`.`ts` = `test`.`b`.`ts`) +*************************** 8.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=unknown output_order=unknown) +*************************** 9.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 10.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 11.row *************************** +QUERY_PLAN: Merge Key: ts asc +*************************** 12.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 14.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 16.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 17.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 18.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 19.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 21.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 22.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=unknown output_order=unknown) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 24.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 25.row *************************** +QUERY_PLAN: Merge Key: ts asc +*************************** 26.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 29.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 30.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 31.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 33.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts order by a.ts\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=16 input_order=unknown ) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=16 +*************************** 3.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> Inner join (columns=4 width=24 input_order=asc ) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=4 width=24 +*************************** 7.row *************************** +QUERY_PLAN: Join Cond: (`test`.`a`.`ts` = `test`.`b`.`ts`) +*************************** 8.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=asc output_order=asc) +*************************** 9.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 10.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 11.row *************************** +QUERY_PLAN: Merge Key: ts asc +*************************** 12.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 14.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 16.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 17.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 18.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 19.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 21.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 22.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=asc output_order=asc) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 24.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 25.row *************************** +QUERY_PLAN: Merge Key: ts asc +*************************** 26.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 29.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 30.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 31.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 32.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 33.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 34.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 35.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts; + ts | c2 | c2 | +====================================================== + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + +taos> select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts order by a.ts desc; + ts | c2 | c2 | +====================================================== + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + +taos> explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts desc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=16 input_order=unknown ) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=16 +*************************** 3.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> Inner join (columns=4 width=24 input_order=desc ) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=4 width=24 +*************************** 7.row *************************** +QUERY_PLAN: Join Cond: (`test`.`a`.`ts` = `b`.`ts`) +*************************** 8.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +*************************** 9.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 10.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 11.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, ts desc +*************************** 12.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 14.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 16.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 17.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 18.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 19.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 21.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 22.row *************************** +QUERY_PLAN: -> Projection (columns=2 width=12 input_order=desc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 24.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 29.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, ts desc +*************************** 30.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 31.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 32.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 33.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 34.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 35.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|0 desc|1]) +*************************** 38.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 39.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts asc\G; +*************************** 1.row *************************** +QUERY_PLAN: -> Projection (columns=3 width=16 input_order=unknown ) +*************************** 2.row *************************** +QUERY_PLAN: Output: columns=3 width=16 +*************************** 3.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 4.row *************************** +QUERY_PLAN: Merge ResBlocks: True +*************************** 5.row *************************** +QUERY_PLAN: -> Inner join (columns=4 width=24 input_order=asc ) +*************************** 6.row *************************** +QUERY_PLAN: Output: columns=4 width=24 +*************************** 7.row *************************** +QUERY_PLAN: Join Cond: (`test`.`a`.`ts` = `b`.`ts`) +*************************** 8.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=asc output_order=asc) +*************************** 9.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 10.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 11.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, ts asc +*************************** 12.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 13.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 14.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 15.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 16.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 17.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 18.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 19.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 20.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 21.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 22.row *************************** +QUERY_PLAN: -> Projection (columns=2 width=12 input_order=asc ) +*************************** 23.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 24.row *************************** +QUERY_PLAN: Output: Ignore Group Id: true +*************************** 25.row *************************** +QUERY_PLAN: Merge ResBlocks: False +*************************** 26.row *************************** +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=asc output_order=asc) +*************************** 27.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 28.row *************************** +QUERY_PLAN: Output: Ignore Group Id: false +*************************** 29.row *************************** +QUERY_PLAN: Merge Key: _group_id asc, ts asc +*************************** 30.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 31.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 32.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 33.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 34.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] +*************************** 35.row *************************** +QUERY_PLAN: -> Data Exchange 1:1 (width=12) +*************************** 36.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 37.row *************************** +QUERY_PLAN: -> Table Merge Scan on meters (columns=2 width=12 order=[asc|1 desc|0]) +*************************** 38.row *************************** +QUERY_PLAN: Output: columns=2 width=12 +*************************** 39.row *************************** +QUERY_PLAN: Time Range: [-9223372036854775808, 9223372036854775807] + +taos> select a.ts, a.c2, b.c2 from meters as a join (select * from meters order by ts desc) b on a.ts = b.ts order by a.ts asc; + ts | c2 | c2 | +====================================================== + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-15 00:01:08.000 | 234 | 234 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-16 00:01:08.000 | 136 | 136 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-17 00:01:08.000 | 59 | 59 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-18 00:01:08.000 | 58 | 58 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-19 00:01:08.000 | 243 | 243 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-20 00:01:08.000 | 120 | 120 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-21 00:01:08.000 | 11 | 11 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-22 00:01:08.000 | 196 | 196 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-23 00:01:08.000 | 116 | 116 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + 2022-05-24 00:01:08.000 | 210 | 210 | + diff --git a/tests/script/tsim/query/t/explain_tsorder.sql b/tests/script/tsim/query/t/explain_tsorder.sql new file mode 100644 index 0000000000..d3264d8895 --- /dev/null +++ b/tests/script/tsim/query/t/explain_tsorder.sql @@ -0,0 +1,73 @@ +use test; +explain verbose true select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart desc\G; +explain verbose true select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart asc\G; +explain verbose true select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart asc\G; +explain verbose true select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart desc\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d desc\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d desc\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d desc\G; + + +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d desc\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d desc\G; + +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d desc\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d desc\G; + + +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) where a > 10000 and a < 20000 interval(10s) fill(NULL) order by d\G; +explain verbose true select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > 10000 and a < 20000 interval(10s) fill(NULL) order by d\G; +explain verbose true select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > 10000 and b < 20000 interval(10s) fill(NULL) order by d\G; +explain verbose true select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > 10000 and b < 20000 interval(10s) fill(NULL) order by d desc\G; + + +select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart desc; +select _wstart, last(ts), avg(c2) from meters interval(10s) order by _wstart asc; +select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart asc; +select _wstart, first(ts), avg(c2) from meters interval(10s) order by _wstart desc; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s)) order by d desc; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a) order by d desc; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) order by d desc; + + +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) order by d desc; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) order by d desc; + +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b) group by c order by d desc; +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) group by c order by d desc; + +select last(a) as d from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-19 00:01:08.000' interval(10s) order by d; +select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > '2022-05-15 00:01:00.000' and b < '2022-05-19 00:01:08.000' interval(10s) order by d; +select last(b) as d from (select last(ts) as b, avg(c2) as c from meters interval(10s) order by b desc) where b > '2022-05-15 00:01:00.000' and b < '2022-05-19 00:01:08.000' interval(10s) order by d desc; +select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc; + +explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; +explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a asc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; + +explain verbose true select * from (select ts as a, c2 as b from meters order by c2 desc)\G; +select * from (select ts as a, c2 as b from meters order by c2 desc); + +explain verbose true select * from (select ts as a, c2 as b from meters order by c2 desc) order by a desc\G; +select * from (select ts as a, c2 as b from meters order by c2 desc) order by a desc; + +explain verbose true select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts\G; +explain verbose true select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts order by a.ts\G; +select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts; +select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts order by a.ts desc; +explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts desc\G; +explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts asc\G; +select a.ts, a.c2, b.c2 from meters as a join (select * from meters order by ts desc) b on a.ts = b.ts order by a.ts asc; diff --git a/utils/tsim/src/simExe.c b/utils/tsim/src/simExe.c index c1f0f502f3..9a0a156717 100644 --- a/utils/tsim/src/simExe.c +++ b/utils/tsim/src/simExe.c @@ -434,7 +434,7 @@ bool simExecuteSystemCmd(SScript *script, char *option) { simLogSql(buf, true); int32_t code = system(buf); int32_t repeatTimes = 0; - while (code < 0) { + while (code != 0) { simError("script:%s, failed to execute %s , code %d, errno:%d %s, repeatTimes:%d", script->fileName, buf, code, errno, strerror(errno), repeatTimes); taosMsleep(1000); From e74c0ac987432bc7b5786df51bce768b70dcaedb Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 16 Jun 2023 14:11:19 +0800 Subject: [PATCH 08/21] save index instead of ts --- source/libs/executor/src/timesliceoperator.c | 29 ++++++++------------ 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 25cb94f7e1..415fefe75f 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -45,7 +45,7 @@ typedef struct STimeSliceOperatorInfo { SGroupKeys* pPrevGroupKey; SSDataBlock* pNextGroupRes; SSDataBlock* pRemainRes; // save block unfinished processing - int64_t remainTs; // the remaining timestamp in the block to be processed + int32_t remainIndex; // the remaining index in the block to be processed } STimeSliceOperatorInfo; static void destroyTimeSliceOperatorInfo(void* param); @@ -669,8 +669,13 @@ static void saveBlockStatus(STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBl SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); if (curIndex < pBlock->info.rows - 1) { pSliceInfo->pRemainRes = pBlock; - pSliceInfo->remainTs = *(int64_t*)colDataGetData(pTsCol, curIndex + 1); + pSliceInfo->remainIndex = curIndex + 1; + return; } + + // all data in remaining block processed + pSliceInfo->pRemainRes = NULL; + } static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, @@ -679,14 +684,10 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS SInterval* pInterval = &pSliceInfo->interval; SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); - for (int32_t i = 0; i < pBlock->info.rows; ++i) { - int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); - // check if need to resume from the position of last unfinished block - if (pSliceInfo->pRemainRes != NULL && ts < pSliceInfo->remainTs && - pSliceInfo->current <= pSliceInfo->remainTs) { - continue; - } + int32_t i = (pSliceInfo->pRemainRes == NULL) ? 0 : pSliceInfo->remainIndex; + for (; i < pBlock->info.rows; ++i) { + int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); // check for duplicate timestamps if (checkDuplicateTimestamps(pSliceInfo, pTsCol, i, pBlock->info.rows)) { @@ -696,13 +697,6 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS if (checkNullRow(&pOperator->exprSupp, pBlock, i, ignoreNull)) { continue; } - if (checkWindowBoundReached(pSliceInfo)) { - break; - } - if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { - saveBlockStatus(pSliceInfo, pBlock, i); - return; - } if (ts == pSliceInfo->current) { addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); @@ -984,7 +978,8 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->pPrevGroupKey = NULL; pInfo->pNextGroupRes = NULL; pInfo->pRemainRes = NULL; - pInfo->remainTs = 0; + pInfo->remainIndex = 0; + pOperator->resultInfo.threshold = 1; if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; From e4c9a7474e6eee6d65d56633eedd60da1d76734d Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 16 Jun 2023 14:58:23 +0800 Subject: [PATCH 09/21] remove test code --- source/libs/executor/src/timesliceoperator.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 415fefe75f..b0c08ee0b8 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -870,7 +870,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { while (1) { if (pSliceInfo->pNextGroupRes != NULL) { doHandleTimeslice(pOperator, pSliceInfo->pNextGroupRes); - if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + if (checkWindowBoundReached(pSliceInfo) || checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); if (pSliceInfo->pRemainRes == NULL) { pSliceInfo->pNextGroupRes = NULL; @@ -898,7 +898,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } doHandleTimeslice(pOperator, pBlock); - if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { + if (checkWindowBoundReached(pSliceInfo) || checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); goto _finished; } @@ -979,7 +979,6 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->pNextGroupRes = NULL; pInfo->pRemainRes = NULL; pInfo->remainIndex = 0; - pOperator->resultInfo.threshold = 1; if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; From 495ae49752cef5ad41e1afb10de526f82f616343 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 16 Jun 2023 15:41:37 +0800 Subject: [PATCH 10/21] fix: refreshMeta on invalid schema of tb epSet in doAsyncQuery --- include/libs/qcom/query.h | 3 ++- source/client/src/clientMain.c | 1 + source/libs/scheduler/src/schTask.c | 2 +- source/util/src/terror.c | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index de3eba599d..6a1091e658 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -281,7 +281,8 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t (_code) == TSDB_CODE_PAR_INVALID_DROP_COL || ((_code) == TSDB_CODE_TDB_INVALID_TABLE_ID)) #define NEED_CLIENT_REFRESH_VG_ERROR(_code) \ ((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID) -#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) ((_code) == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER) +#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) \ + ((_code) == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || (_code) == TSDB_CODE_MND_INVALID_SCHEMA_VER) #define NEED_CLIENT_HANDLE_ERROR(_code) \ (NEED_CLIENT_RM_TBLMETA_ERROR(_code) || NEED_CLIENT_REFRESH_VG_ERROR(_code) || \ NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code)) diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 7573fd5968..63b16a30c5 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -1120,6 +1120,7 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) { if (NEED_CLIENT_HANDLE_ERROR(code)) { tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId); + refreshMeta(pRequest->pTscObj, pRequest); pRequest->prevCode = code; doAsyncQuery(pRequest, true); return; diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index 207753ae25..78e28bce49 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -765,7 +765,7 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { if (SCH_IS_DATA_BIND_TASK(pTask)) { SCH_TASK_ELOG("no execNode specifed for data src task, numOfEps:%d", pTask->plan->execNode.epSet.numOfEps); - SCH_ERR_RET(TSDB_CODE_APP_ERROR); + SCH_ERR_RET(TSDB_CODE_MND_INVALID_SCHEMA_VER); } SCH_ERR_RET(schSetAddrsFromNodeList(pJob, pTask)); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index a66af6e732..d7571b9283 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -261,8 +261,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STB_ALTER_OPTION, "Invalid stable alter TAOS_DEFINE_ERROR(TSDB_CODE_MND_STB_OPTION_UNCHNAGED, "STable option unchanged") TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_CONFLICT_WITH_TOPIC,"Field used by topic") TAOS_DEFINE_ERROR(TSDB_CODE_MND_SINGLE_STB_MODE_DB, "Database is single stable mode") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SCHEMA_VER, "Invalid schema version while alter stb") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_STABLE_UID_NOT_MATCH, "Invalid stable uid while alter stb") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SCHEMA_VER, "Invalid schema version") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_STABLE_UID_NOT_MATCH, "Invalid stable uid") TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_CONFLICT_WITH_TSMA, "Field used by tsma") TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_IN_CREATING, "Dnode in creating status") TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_IN_DROPPING, "Dnode in dropping status") From 9cddf06053bc5c74a4e63d2f577c4d04a6c6736e Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Fri, 16 Jun 2023 16:11:56 +0800 Subject: [PATCH 11/21] handle 0 result case for groups --- source/libs/executor/src/timesliceoperator.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index b0c08ee0b8..5c01775a17 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -875,7 +875,13 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (pSliceInfo->pRemainRes == NULL) { pSliceInfo->pNextGroupRes = NULL; } - goto _finished; + if (pResBlock->info.rows != 0) { + goto _finished; + } else { + // after fillter if result block has 0 rows, go back to + // process pNextGroupRes again for unfinished data + continue; + } } pSliceInfo->pNextGroupRes = NULL; } @@ -900,7 +906,9 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { doHandleTimeslice(pOperator, pBlock); if (checkWindowBoundReached(pSliceInfo) || checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); - goto _finished; + if (pResBlock->info.rows != 0) { + goto _finished; + } } } // post work for a specific group @@ -916,8 +924,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { // restore initial value for next group resetTimesliceInfo(pSliceInfo); - if (checkThresholdReached(pSliceInfo, pOperator->resultInfo.threshold)) { - goto _finished; + if (pResBlock->info.rows != 0) { + break; } } From a9fcebbdafd47d453448ff3b9d41ea61ef677fae Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 16 Jun 2023 17:12:05 +0800 Subject: [PATCH 12/21] more code --- source/dnode/vnode/src/tsdb/tsdbSnapshot.c | 1147 +++++++++++--------- 1 file changed, 638 insertions(+), 509 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index b5ca716701..f45858ae8d 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -14,6 +14,10 @@ */ #include "tsdb.h" +#include "tsdbDataFileRW.h" +#include "tsdbFS2.h" +#include "tsdbIter.h" +#include "tsdbSttFileRW.h" extern int32_t tsdbUpdateTableSchema(SMeta* pMeta, int64_t suid, int64_t uid, SSkmInfo* pSkmInfo); extern int32_t tsdbWriteDataBlock(SDataFWriter* pWriter, SBlockData* pBlockData, SMapData* mDataBlk, int8_t cmprAlg); @@ -21,546 +25,483 @@ extern int32_t tsdbWriteSttBlock(SDataFWriter* pWriter, SBlockData* pBlockData, // STsdbSnapReader ======================================== struct STsdbSnapReader { - STsdb* pTsdb; - int64_t sver; - int64_t ever; - int8_t type; + STsdb* tsdb; + int64_t sver; + int64_t ever; + int8_t type; + uint8_t* aBuf[5]; + SSkmInfo skmTb[1]; - STsdbFS fs; - TABLEID tbid; - SSkmInfo skmTable; + TFileSetArray* fsetArr; - // timeseries data - int8_t dataDone; - int32_t fid; + // context + struct { + int32_t fsetArrIdx; + STFileSet* fset; + bool isDataDone; + bool isTombDone; + } ctx[1]; - SDataFReader* pDataFReader; - STsdbDataIter2* iterList; - STsdbDataIter2* pIter; - SRBTree rbt; - SBlockData bData; + // reader + SDataFileReader* dataReader; + TSttFileReaderArray sttReaderArr[1]; - // tombstone data - int8_t delDone; - SDelFReader* pDelFReader; - STsdbDataIter2* pTIter; - SArray* aDelData; + // iter + TTsdbIterArray dataIterArr[1]; + SIterMerger* dataIterMerger; + TTsdbIterArray tombIterArr[1]; + SIterMerger* tombIterMerger; + + // data + SBlockData blockData[1]; + STombBlock tombBlock[1]; }; -static int32_t tsdbSnapReadFileDataStart(STsdbSnapReader* pReader) { +static int32_t tsdbSnapReadFileSetOpenReader(STsdbSnapReader* reader) { int32_t code = 0; int32_t lino = 0; - SDFileSet* pSet = taosArraySearch(pReader->fs.aDFileSet, &(SDFileSet){.fid = pReader->fid}, tDFileSetCmprFn, TD_GT); - if (pSet == NULL) { - pReader->fid = INT32_MAX; - goto _exit; - } + ASSERT(reader->dataReader == NULL); + ASSERT(TARRAY2_SIZE(reader->sttReaderArr) == 0); - pReader->fid = pSet->fid; - - tRBTreeCreate(&pReader->rbt, tsdbDataIterCmprFn); - - code = tsdbDataFReaderOpen(&pReader->pDataFReader, pReader->pTsdb, pSet); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbOpenDataFileDataIter(pReader->pDataFReader, &pReader->pIter); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pReader->pIter) { - // iter to next with filter info (sver, ever) - code = tsdbDataIterNext2( - pReader->pIter, - &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE, // flag - .sver = pReader->sver, - .ever = pReader->ever}); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pReader->pIter->rowInfo.suid || pReader->pIter->rowInfo.uid) { - // add to rbtree - tRBTreePut(&pReader->rbt, &pReader->pIter->rbtn); - - // add to iterList - pReader->pIter->next = pReader->iterList; - pReader->iterList = pReader->pIter; - } else { - tsdbCloseDataIter2(pReader->pIter); + // data + SDataFileReaderConfig config = { + .tsdb = reader->tsdb, + .szPage = reader->tsdb->pVnode->config.tsdbPageSize, + .bufArr = reader->aBuf, + }; + bool hasDataFile = false; + for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ftype++) { + if (reader->ctx->fset->farr[ftype] != NULL) { + hasDataFile = true; + config.files[ftype].exist = true; + config.files[ftype].file = reader->ctx->fset->farr[ftype]->f[0]; } } - for (int32_t iStt = 0; iStt < pSet->nSttF; ++iStt) { - code = tsdbOpenSttFileDataIter(pReader->pDataFReader, iStt, &pReader->pIter); + if (hasDataFile) { + code = tsdbDataFileReaderOpen(NULL, &config, &reader->dataReader); TSDB_CHECK_CODE(code, lino, _exit); + } - if (pReader->pIter) { - // iter to valid row - code = tsdbDataIterNext2( - pReader->pIter, - &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE, // flag - .sver = pReader->sver, - .ever = pReader->ever}); + // stt + SSttLvl* lvl; + TARRAY2_FOREACH(reader->ctx->fset->lvlArr, lvl) { + STFileObj* fobj; + TARRAY2_FOREACH(lvl->fobjArr, fobj) { + SSttFileReader* sttReader; + SSttFileReaderConfig config = { + .tsdb = reader->tsdb, + .szPage = reader->tsdb->pVnode->config.tsdbPageSize, + .file = fobj->f[0], + .bufArr = reader->aBuf, + }; + + code = tsdbSttFileReaderOpen(fobj->fname, &config, &sttReader); TSDB_CHECK_CODE(code, lino, _exit); - if (pReader->pIter->rowInfo.suid || pReader->pIter->rowInfo.uid) { - // add to rbtree - tRBTreePut(&pReader->rbt, &pReader->pIter->rbtn); - - // add to iterList - pReader->pIter->next = pReader->iterList; - pReader->iterList = pReader->pIter; - } else { - tsdbCloseDataIter2(pReader->pIter); - } + code = TARRAY2_APPEND(reader->sttReaderArr, sttReader); + TSDB_CHECK_CODE(code, lino, _exit); } } - pReader->pIter = NULL; - _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbInfo("vgId:%d %s done, fid:%d", TD_VID(pReader->pTsdb->pVnode), __func__, pReader->fid); + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); } return code; } -static void tsdbSnapReadFileDataEnd(STsdbSnapReader* pReader) { - while (pReader->iterList) { - STsdbDataIter2* pIter = pReader->iterList; - pReader->iterList = pIter->next; - tsdbCloseDataIter2(pIter); - } - - tsdbDataFReaderClose(&pReader->pDataFReader); -} - -static int32_t tsdbSnapReadNextRow(STsdbSnapReader* pReader, SRowInfo** ppRowInfo) { +static int32_t tsdbSnapReadFileSetCloseReader(STsdbSnapReader* reader) { int32_t code = 0; int32_t lino = 0; - if (pReader->pIter) { - code = tsdbDataIterNext2(pReader->pIter, &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | - TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE, // flag - .sver = pReader->sver, - .ever = pReader->ever}); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pReader->pIter->rowInfo.suid == 0 && pReader->pIter->rowInfo.uid == 0) { - pReader->pIter = NULL; - } else { - SRBTreeNode* pNode = tRBTreeMin(&pReader->rbt); - if (pNode) { - int32_t c = tsdbDataIterCmprFn(&pReader->pIter->rbtn, pNode); - if (c > 0) { - tRBTreePut(&pReader->rbt, &pReader->pIter->rbtn); - pReader->pIter = NULL; - } else if (c == 0) { - ASSERT(0); - } - } - } - } - - if (pReader->pIter == NULL) { - SRBTreeNode* pNode = tRBTreeMin(&pReader->rbt); - if (pNode) { - tRBTreeDrop(&pReader->rbt, pNode); - pReader->pIter = TSDB_RBTN_TO_DATA_ITER(pNode); - } - } - - if (ppRowInfo) { - if (pReader->pIter) { - *ppRowInfo = &pReader->pIter->rowInfo; - } else { - *ppRowInfo = NULL; - } - } + TARRAY2_CLEAR(reader->sttReaderArr, tsdbSttFileReaderClose); + tsdbDataFileReaderClose(&reader->dataReader); _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code)); + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); } return code; } -static int32_t tsdbSnapReadGetRow(STsdbSnapReader* pReader, SRowInfo** ppRowInfo) { - if (pReader->pIter) { - *ppRowInfo = &pReader->pIter->rowInfo; - return 0; +static int32_t tsdbSnapReadFileSetOpenIter(STsdbSnapReader* reader) { + int32_t code = 0; + int32_t lino = 0; + + ASSERT(reader->dataIterMerger == NULL); + ASSERT(reader->tombIterMerger == NULL); + ASSERT(TARRAY2_SIZE(reader->dataIterArr) == 0); + ASSERT(TARRAY2_SIZE(reader->tombIterArr) == 0); + + STsdbIter* iter; + STsdbIterConfig config = { + .filterByVersion = true, + .verRange[0] = reader->sver, + .verRange[1] = reader->ever, + }; + + // data file + if (reader->dataReader) { + // data + config.type = TSDB_ITER_TYPE_DATA; + config.dataReader = reader->dataReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(reader->dataIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + + // tomb + config.type = TSDB_ITER_TYPE_DATA_TOMB; + config.dataReader = reader->dataReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(reader->tombIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); } - return tsdbSnapReadNextRow(pReader, ppRowInfo); + // stt file + SSttFileReader* sttReader; + TARRAY2_FOREACH(reader->sttReaderArr, sttReader) { + // data + config.type = TSDB_ITER_TYPE_STT; + config.sttReader = sttReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(reader->dataIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + + // tomb + config.type = TSDB_ITER_TYPE_STT_TOMB; + config.sttReader = sttReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(reader->tombIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // merger + code = tsdbIterMergerOpen(reader->dataIterArr, &reader->dataIterMerger, false); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbIterMergerOpen(reader->tombIterArr, &reader->dataIterMerger, true); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); + } + return code; } -static int32_t tsdbSnapCmprData(STsdbSnapReader* pReader, uint8_t** ppData) { - int32_t code = 0; +static int32_t tsdbSnapReadFileSetCloseIter(STsdbSnapReader* reader) { + tsdbIterMergerClose(&reader->dataIterMerger); + tsdbIterMergerClose(&reader->tombIterMerger); + TARRAY2_CLEAR(reader->dataIterArr, tsdbIterClose); + TARRAY2_CLEAR(reader->tombIterArr, tsdbIterClose); + return 0; +} - ASSERT(pReader->bData.nRow); +static int32_t tsdbSnapReadFileSetBegin(STsdbSnapReader* reader) { + int32_t code = 0; + int32_t lino = 0; + + if (reader->ctx->fsetArrIdx < TARRAY2_SIZE(reader->fsetArr)) { + reader->ctx->fset = TARRAY2_GET(reader->fsetArr, reader->ctx->fsetArrIdx++); + reader->ctx->isDataDone = false; + reader->ctx->isTombDone = false; + + code = tsdbSnapReadFileSetOpenReader(reader); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbSnapReadFileSetOpenIter(reader); + TSDB_CHECK_CODE(code, lino, _exit); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); + } + return code; +} + +static int32_t tsdbSnapReadFileSetEnd(STsdbSnapReader* reader) { + tsdbSnapReadFileSetCloseIter(reader); + tsdbSnapReadFileSetCloseReader(reader); + reader->ctx->fset = NULL; + return 0; +} + +static int32_t tsdbSnapCmprData(STsdbSnapReader* reader, uint8_t** data) { + int32_t code = 0; + int32_t lino = 0; int32_t aBufN[5] = {0}; - code = tCmprBlockData(&pReader->bData, NO_COMPRESSION, NULL, NULL, pReader->aBuf, aBufN); - if (code) goto _exit; - - int32_t size = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3]; - *ppData = taosMemoryMalloc(sizeof(SSnapDataHdr) + size); - if (*ppData == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _exit; - } - - SSnapDataHdr* pHdr = (SSnapDataHdr*)*ppData; - pHdr->type = pReader->type; - pHdr->size = size; - - memcpy(pHdr->data, pReader->aBuf[3], aBufN[3]); - memcpy(pHdr->data + aBufN[3], pReader->aBuf[2], aBufN[2]); - if (aBufN[1]) { - memcpy(pHdr->data + aBufN[3] + aBufN[2], pReader->aBuf[1], aBufN[1]); - } - if (aBufN[0]) { - memcpy(pHdr->data + aBufN[3] + aBufN[2] + aBufN[1], pReader->aBuf[0], aBufN[0]); - } - -_exit: - return code; -} - -static int32_t tsdbSnapReadTimeSeriesData(STsdbSnapReader* pReader, uint8_t** ppData) { - int32_t code = 0; - int32_t lino = 0; - - STsdb* pTsdb = pReader->pTsdb; - - tBlockDataReset(&pReader->bData); - - for (;;) { - // start a new file read if need - if (pReader->pDataFReader == NULL) { - code = tsdbSnapReadFileDataStart(pReader); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pReader->pDataFReader == NULL) break; - - SRowInfo* pRowInfo; - code = tsdbSnapReadGetRow(pReader, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pRowInfo == NULL) { - tsdbSnapReadFileDataEnd(pReader); - continue; - } - - code = tsdbUpdateTableSchema(pTsdb->pVnode->pMeta, pRowInfo->suid, pRowInfo->uid, &pReader->skmTable); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tBlockDataInit(&pReader->bData, (TABLEID*)pRowInfo, pReader->skmTable.pTSchema, NULL, 0); - TSDB_CHECK_CODE(code, lino, _exit); - - do { - if (!TABLE_SAME_SCHEMA(pReader->bData.suid, pReader->bData.uid, pRowInfo->suid, pRowInfo->uid)) break; - - if (pReader->bData.uid && pReader->bData.uid != pRowInfo->uid) { - code = tRealloc((uint8_t**)&pReader->bData.aUid, sizeof(int64_t) * (pReader->bData.nRow + 1)); - TSDB_CHECK_CODE(code, lino, _exit); - - for (int32_t iRow = 0; iRow < pReader->bData.nRow; ++iRow) { - pReader->bData.aUid[iRow] = pReader->bData.uid; - } - pReader->bData.uid = 0; - } - - code = tBlockDataAppendRow(&pReader->bData, &pRowInfo->row, NULL, pRowInfo->uid); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbSnapReadNextRow(pReader, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pReader->bData.nRow >= 81920) break; - } while (pRowInfo); - - ASSERT(pReader->bData.nRow > 0); - - break; - } - - if (pReader->bData.nRow > 0) { - ASSERT(pReader->bData.suid || pReader->bData.uid); - - code = tsdbSnapCmprData(pReader, ppData); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapCmprTombData(STsdbSnapReader* pReader, uint8_t** ppData) { - int32_t code = 0; - int32_t lino = 0; - - int64_t size = sizeof(TABLEID); - for (int32_t iDelData = 0; iDelData < taosArrayGetSize(pReader->aDelData); ++iDelData) { - size += tPutDelData(NULL, taosArrayGet(pReader->aDelData, iDelData)); - } - - uint8_t* pData = (uint8_t*)taosMemoryMalloc(sizeof(SSnapDataHdr) + size); - if (pData == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - SSnapDataHdr* pHdr = (SSnapDataHdr*)pData; - pHdr->type = SNAP_DATA_DEL; - pHdr->size = size; - - TABLEID* pId = (TABLEID*)(pData + sizeof(SSnapDataHdr)); - *pId = pReader->tbid; - - size = sizeof(SSnapDataHdr) + sizeof(TABLEID); - for (int32_t iDelData = 0; iDelData < taosArrayGetSize(pReader->aDelData); ++iDelData) { - size += tPutDelData(pData + size, taosArrayGet(pReader->aDelData, iDelData)); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code)); - } - *ppData = pData; - return code; -} - -static void tsdbSnapReadGetTombData(STsdbSnapReader* pReader, SDelInfo** ppDelInfo) { - if (pReader->pTIter == NULL || (pReader->pTIter->delInfo.suid == 0 && pReader->pTIter->delInfo.uid == 0)) { - *ppDelInfo = NULL; - } else { - *ppDelInfo = &pReader->pTIter->delInfo; - } -} - -static int32_t tsdbSnapReadNextTombData(STsdbSnapReader* pReader, SDelInfo** ppDelInfo) { - int32_t code = 0; - int32_t lino = 0; - - code = tsdbDataIterNext2( - pReader->pTIter, &(STsdbFilterInfo){.flag = TSDB_FILTER_FLAG_BY_VERSION | TSDB_FILTER_FLAG_IGNORE_DROPPED_TABLE, - .sver = pReader->sver, - .ever = pReader->ever}); + code = tCmprBlockData(reader->blockData, NO_COMPRESSION, NULL, NULL, reader->aBuf, aBufN); TSDB_CHECK_CODE(code, lino, _exit); - if (ppDelInfo) { - tsdbSnapReadGetTombData(pReader, ppDelInfo); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapReadTombData(STsdbSnapReader* pReader, uint8_t** ppData) { - int32_t code = 0; - int32_t lino = 0; - - STsdb* pTsdb = pReader->pTsdb; - - // open tombstone data iter if need - if (pReader->pDelFReader == NULL) { - if (pReader->fs.pDelFile == NULL) goto _exit; - - // open - code = tsdbDelFReaderOpen(&pReader->pDelFReader, pReader->fs.pDelFile, pTsdb); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbOpenTombFileDataIter(pReader->pDelFReader, &pReader->pTIter); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pReader->pTIter) { - code = tsdbSnapReadNextTombData(pReader, NULL); - TSDB_CHECK_CODE(code, lino, _exit); - } - } - - // loop to get tombstone data - SDelInfo* pDelInfo; - tsdbSnapReadGetTombData(pReader, &pDelInfo); - - if (pDelInfo == NULL) goto _exit; - - pReader->tbid = *(TABLEID*)pDelInfo; - - if (pReader->aDelData) { - taosArrayClear(pReader->aDelData); - } else if ((pReader->aDelData = taosArrayInit(16, sizeof(SDelData))) == NULL) { + int32_t size = aBufN[0] + aBufN[1] + aBufN[2] + aBufN[3]; + *data = taosMemoryMalloc(sizeof(SSnapDataHdr) + size); + if (*data == NULL) { code = TSDB_CODE_OUT_OF_MEMORY; TSDB_CHECK_CODE(code, lino, _exit); } - while (pDelInfo && pDelInfo->suid == pReader->tbid.suid && pDelInfo->uid == pReader->tbid.uid) { - if (taosArrayPush(pReader->aDelData, &pDelInfo->delData) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; + SSnapDataHdr* pHdr = (SSnapDataHdr*)*data; + pHdr->type = reader->type; + pHdr->size = size; + + memcpy(pHdr->data, reader->aBuf[3], aBufN[3]); + memcpy(pHdr->data + aBufN[3], reader->aBuf[2], aBufN[2]); + if (aBufN[1]) { + memcpy(pHdr->data + aBufN[3] + aBufN[2], reader->aBuf[1], aBufN[1]); + } + if (aBufN[0]) { + memcpy(pHdr->data + aBufN[3] + aBufN[2] + aBufN[1], reader->aBuf[0], aBufN[0]); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapReadTimeSeriesData(STsdbSnapReader* reader, uint8_t** data) { + int32_t code = 0; + int32_t lino = 0; + + tBlockDataReset(reader->blockData); + + for (SRowInfo* row; (row = tsdbIterMergerGetData(reader->dataIterMerger));) { + if (reader->blockData->suid == 0 && reader->blockData->uid == 0) { + code = tsdbUpdateSkmTb(reader->tsdb, (TABLEID*)row, reader->skmTb); + TSDB_CHECK_CODE(code, lino, _exit); + + TABLEID tbid = { + .suid = row->suid, + .uid = row->suid ? 0 : row->uid, + }; + code = tBlockDataInit(reader->blockData, &tbid, reader->skmTb->pTSchema, NULL, 0); TSDB_CHECK_CODE(code, lino, _exit); } - code = tsdbSnapReadNextTombData(pReader, &pDelInfo); + if (!TABLE_SAME_SCHEMA(reader->blockData->suid, reader->blockData->uid, row->suid, row->uid)) { + break; + } + + code = tBlockDataAppendRow(reader->blockData, &row->row, NULL, row->uid); TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbIterMergerNext(reader->dataIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); + + if (reader->blockData->nRow >= 81920) { + break; + } } - // encode tombstone data - if (taosArrayGetSize(pReader->aDelData) > 0) { - code = tsdbSnapCmprTombData(pReader, ppData); + if (reader->blockData->nRow > 0) { + ASSERT(reader->blockData->suid || reader->blockData->uid); + code = tsdbSnapCmprData(reader, data); TSDB_CHECK_CODE(code, lino, _exit); } _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbDebug("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); } return code; } -int32_t tsdbSnapReaderOpen(STsdb* pTsdb, int64_t sver, int64_t ever, int8_t type, STsdbSnapReader** ppReader) { +static int32_t tsdbSnapCmprTombData(STsdbSnapReader* reader, uint8_t** data) { + int32_t code = 0; + int32_t lino = 0; + + int64_t size = sizeof(SSnapDataHdr); + for (int32_t i = 0; i < ARRAY_SIZE(reader->tombBlock->dataArr); i++) { + size += TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i); + } + + data[0] = taosMemoryMalloc(size); + if (data[0] == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + TSDB_CHECK_CODE(code, lino, _exit); + } + + SSnapDataHdr* hdr = (SSnapDataHdr*)data[0]; + hdr->type = SNAP_DATA_DEL; + hdr->size = size; + + uint8_t* tdata = hdr->data; + for (int32_t i = 0; i < TARRAY_SIZE(reader->tombBlock->dataArr); i++) { + memcpy(tdata, TARRAY2_DATA(reader->tombBlock->dataArr + i), TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i)); + tdata += TARRAY2_DATA_LEN(reader->tombBlock->dataArr + i); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); + } + return code; +} + +static int32_t tsdbSnapReadTombData(STsdbSnapReader* reader, uint8_t** data) { + int32_t code = 0; + int32_t lino = 0; + + tTombBlockClear(reader->tombBlock); + + for (STombRecord* record; (record = tsdbIterMergerGetTombRecord(reader->tombIterMerger)) != NULL;) { + code = tTombBlockPut(reader->tombBlock, record); + TSDB_CHECK_CODE(code, lino, _exit); + + if (TOMB_BLOCK_SIZE(reader->tombBlock) >= 81920) { + break; + } + } + + if (TOMB_BLOCK_SIZE(reader->tombBlock) > 0) { + code = tsdbSnapCmprTombData(reader, data); + TSDB_CHECK_CODE(code, lino, _exit); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); + } + return code; +} + +int32_t tsdbSnapReaderOpen(STsdb* tsdb, int64_t sver, int64_t ever, int8_t type, STsdbSnapReader** reader) { int32_t code = 0; int32_t lino = 0; // alloc - STsdbSnapReader* pReader = (STsdbSnapReader*)taosMemoryCalloc(1, sizeof(*pReader)); - if (pReader == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - pReader->pTsdb = pTsdb; - pReader->sver = sver; - pReader->ever = ever; - pReader->type = type; + reader[0] = (STsdbSnapReader*)taosMemoryCalloc(1, sizeof(*reader[0])); + if (reader[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; - taosThreadRwlockRdlock(&pTsdb->rwLock); - code = tsdbFSRef(pTsdb, &pReader->fs); - if (code) { - taosThreadRwlockUnlock(&pTsdb->rwLock); - TSDB_CHECK_CODE(code, lino, _exit); - } - taosThreadRwlockUnlock(&pTsdb->rwLock); + reader[0]->tsdb = tsdb; + reader[0]->sver = sver; + reader[0]->ever = ever; + reader[0]->type = type; - // init - pReader->fid = INT32_MIN; - - code = tBlockDataCreate(&pReader->bData); + code = tsdbFSCreateRefSnapshot(tsdb->pFS, &reader[0]->fsetArr); TSDB_CHECK_CODE(code, lino, _exit); _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s, sver:%" PRId64 " ever:%" PRId64 " type:%d", TD_VID(pTsdb->pVnode), + tsdbError("vgId:%d %s failed at line %d since %s, sver:%" PRId64 " ever:%" PRId64 " type:%d", TD_VID(tsdb->pVnode), __func__, lino, tstrerror(code), sver, ever, type); - if (pReader) { - tBlockDataDestroy(&pReader->bData); - tsdbFSUnref(pTsdb, &pReader->fs); - taosMemoryFree(pReader); - pReader = NULL; - } + tsdbFSDestroyRefSnapshot(&reader[0]->fsetArr); + taosMemoryFree(reader[0]); + reader[0] = NULL; } else { - tsdbInfo("vgId:%d %s done, sver:%" PRId64 " ever:%" PRId64 " type:%d", TD_VID(pTsdb->pVnode), __func__, sver, ever, + tsdbInfo("vgId:%d %s done, sver:%" PRId64 " ever:%" PRId64 " type:%d", TD_VID(tsdb->pVnode), __func__, sver, ever, type); } - *ppReader = pReader; return code; } -int32_t tsdbSnapReaderClose(STsdbSnapReader** ppReader) { +int32_t tsdbSnapReaderClose(STsdbSnapReader** reader) { + if (reader[0] == NULL) return 0; + int32_t code = 0; int32_t lino = 0; - STsdbSnapReader* pReader = *ppReader; - STsdb* pTsdb = pReader->pTsdb; + STsdb* tsdb = reader[0]->tsdb; - // tombstone - if (pReader->pTIter) { - tsdbCloseDataIter2(pReader->pTIter); - pReader->pTIter = NULL; - } - if (pReader->pDelFReader) { - tsdbDelFReaderClose(&pReader->pDelFReader); - } - taosArrayDestroy(pReader->aDelData); + tTombBlockDestroy(reader[0]->tombBlock); + tBlockDataDestroy(reader[0]->blockData); - // timeseries - while (pReader->iterList) { - STsdbDataIter2* pIter = pReader->iterList; - pReader->iterList = pIter->next; - tsdbCloseDataIter2(pIter); - } - if (pReader->pDataFReader) { - tsdbDataFReaderClose(&pReader->pDataFReader); - } - tBlockDataDestroy(&pReader->bData); + tsdbIterMergerClose(&reader[0]->dataIterMerger); + tsdbIterMergerClose(&reader[0]->tombIterMerger); + TARRAY2_DESTROY(reader[0]->dataIterArr, tsdbIterClose); + TARRAY2_DESTROY(reader[0]->tombIterArr, tsdbIterClose); + TARRAY2_DESTROY(reader[0]->sttReaderArr, tsdbSttFileReaderClose); + tsdbDataFileReaderClose(&reader[0]->dataReader); - // other - tDestroyTSchema(pReader->skmTable.pTSchema); - tsdbFSUnref(pReader->pTsdb, &pReader->fs); - for (int32_t iBuf = 0; iBuf < sizeof(pReader->aBuf) / sizeof(pReader->aBuf[0]); iBuf++) { - tFree(pReader->aBuf[iBuf]); + tsdbFSDestroyRefSnapshot(&reader[0]->fsetArr); + tDestroyTSchema(reader[0]->skmTb->pTSchema); + + for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->aBuf);) { + tFree(reader[0]->aBuf[i]); } - taosMemoryFree(pReader); + + taosMemoryFree(reader[0]); + reader[0] = NULL; _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); + TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code); } else { - tsdbDebug("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); + tsdbDebug("vgId:%d %s done", TD_VID(tsdb->pVnode), __func__); } - *ppReader = NULL; return code; } -int32_t tsdbSnapRead(STsdbSnapReader* pReader, uint8_t** ppData) { +int32_t tsdbSnapRead(STsdbSnapReader* reader, uint8_t** data) { int32_t code = 0; int32_t lino = 0; - *ppData = NULL; + data[0] = NULL; - // read data file - if (!pReader->dataDone) { - code = tsdbSnapReadTimeSeriesData(pReader, ppData); - TSDB_CHECK_CODE(code, lino, _exit); - if (*ppData) { - goto _exit; - } else { - pReader->dataDone = 1; - } - } + for (;;) { + if (reader->ctx->fset == NULL) { + code = tsdbSnapReadFileSetBegin(reader); + TSDB_CHECK_CODE(code, lino, _exit); - // read del file - if (!pReader->delDone) { - code = tsdbSnapReadTombData(pReader, ppData); - TSDB_CHECK_CODE(code, lino, _exit); - if (*ppData) { - goto _exit; - } else { - pReader->delDone = 1; + if (reader->ctx->fset == NULL) { + break; + } } + + if (!reader->ctx->isDataDone) { + code = tsdbSnapReadTimeSeriesData(reader, data); + TSDB_CHECK_CODE(code, lino, _exit); + if (data[0]) { + goto _exit; + } else { + reader->ctx->isDataDone = true; + } + } + + if (!reader->ctx->isTombDone) { + code = tsdbSnapReadTombData(reader, data); + TSDB_CHECK_CODE(code, lino, _exit); + if (data[0]) { + goto _exit; + } else { + reader->ctx->isTombDone = true; + } + } + + code = tsdbSnapReadFileSetEnd(reader); + TSDB_CHECK_CODE(code, lino, _exit); } _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code)); + TSDB_ERROR_LOG(TD_VID(reader->tsdb->pVnode), code, lino); } else { - tsdbDebug("vgId:%d %s done", TD_VID(pReader->pTsdb->pVnode), __func__); + tsdbDebug("vgId:%d %s done", TD_VID(reader->tsdb->pVnode), __func__); } return code; } // STsdbSnapWriter ======================================== struct STsdbSnapWriter { - STsdb* pTsdb; + STsdb* tsdb; int64_t sver; int64_t ever; int32_t minutes; @@ -571,41 +512,37 @@ struct STsdbSnapWriter { int64_t commitID; uint8_t* aBuf[5]; - STsdbFS fs; - TABLEID tbid; + TFileSetArray* fsetArr; + TFileOpArray fopArr[1]; - // time-series data - SBlockData inData; + struct { + bool fsetWriteBegin; - int32_t fid; - SSkmInfo skmTable; + int32_t fid; + STFileSet* fset; - /* reader */ - SDataFReader* pDataFReader; - STsdbDataIter2* iterList; - STsdbDataIter2* pDIter; - STsdbDataIter2* pSIter; - SRBTree rbt; // SRBTree + bool hasData; + bool hasTomb; - /* writer */ - SDataFWriter* pDataFWriter; - SArray* aBlockIdx; - SMapData mDataBlk; // SMapData - SArray* aSttBlk; // SArray - SBlockData bData; - SBlockData sData; + // reader + SDataFileReader* dataReader; + TSttFileReaderArray sttReaderArr[1]; - // tombstone data - /* reader */ - SDelFReader* pDelFReader; - STsdbDataIter2* pTIter; + // iter/merger + TTsdbIterArray dataIterArr[1]; + SIterMerger* dataIterMerger; + TTsdbIterArray tombIterArr[1]; + SIterMerger* tombIterMerger; + } ctx[1]; - /* writer */ - SDelFWriter* pDelFWriter; - SArray* aDelIdx; - SArray* aDelData; + SDataFileWriter* dataWriter; + SSttFileWriter* sttWriter; + + SBlockData blockData[1]; + STombBlock tombBlock[1]; }; +#if 0 // SNAP_DATA_TSDB static int32_t tsdbSnapWriteTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pId) { int32_t code = 0; @@ -666,7 +603,7 @@ static int32_t tsdbSnapWriteTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pI } if (pId) { - code = tsdbUpdateTableSchema(pWriter->pTsdb->pVnode->pMeta, pId->suid, pId->uid, &pWriter->skmTable); + code = tsdbUpdateTableSchema(pWriter->tsdb->pVnode->pMeta, pId->suid, pId->uid, &pWriter->skmTable); TSDB_CHECK_CODE(code, lino, _exit); tMapDataReset(&pWriter->mDataBlk); @@ -690,9 +627,9 @@ static int32_t tsdbSnapWriteTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pI _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->pTsdb->pVnode), __func__, + tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->tsdb->pVnode), __func__, pWriter->tbid.suid, pWriter->tbid.uid); } return code; @@ -712,7 +649,7 @@ static int32_t tsdbSnapWriteTableRowImpl(STsdbSnapWriter* pWriter, TSDBROW* pRow _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -782,7 +719,7 @@ _write_row: _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -832,7 +769,7 @@ static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) { _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -843,7 +780,7 @@ static int32_t tsdbSnapWriteFileDataStart(STsdbSnapWriter* pWriter, int32_t fid) ASSERT(pWriter->pDataFWriter == NULL && pWriter->fid < fid); - STsdb* pTsdb = pWriter->pTsdb; + STsdb* pTsdb = pWriter->tsdb; pWriter->fid = fid; pWriter->tbid = (TABLEID){0}; @@ -955,7 +892,7 @@ static int32_t tsdbSnapWriteTableData(STsdbSnapWriter* pWriter, SRowInfo* pRowIn _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -1002,7 +939,7 @@ static int32_t tsdbSnapWriteNextRow(STsdbSnapWriter* pWriter, SRowInfo** ppRowIn _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -1021,7 +958,7 @@ static int32_t tsdbSnapWriteGetRow(STsdbSnapWriter* pWriter, SRowInfo** ppRowInf _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -1076,9 +1013,9 @@ static int32_t tsdbSnapWriteFileDataEnd(STsdbSnapWriter* pWriter) { _exit: if (code) { - tsdbError("vgId:%d %s failed since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, tstrerror(code)); + tsdbError("vgId:%d %s failed since %s", TD_VID(pWriter->tsdb->pVnode), __func__, tstrerror(code)); } else { - tsdbDebug("vgId:%d %s is done", TD_VID(pWriter->pTsdb->pVnode), __func__); + tsdbDebug("vgId:%d %s is done", TD_VID(pWriter->tsdb->pVnode), __func__); } return code; } @@ -1139,9 +1076,9 @@ static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* pWriter, SSnapDataHd _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbDebug("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64 " nRow:%d", TD_VID(pWriter->pTsdb->pVnode), __func__, + tsdbDebug("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64 " nRow:%d", TD_VID(pWriter->tsdb->pVnode), __func__, pWriter->inData.suid, pWriter->inData.uid, pWriter->inData.nRow); } return code; @@ -1196,9 +1133,9 @@ static int32_t tsdbSnapWriteDelTableDataStart(STsdbSnapWriter* pWriter, TABLEID* _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->pTsdb->pVnode), __func__, + tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->tsdb->pVnode), __func__, pWriter->tbid.suid, pWriter->tbid.uid); } return code; @@ -1224,9 +1161,9 @@ static int32_t tsdbSnapWriteDelTableDataEnd(STsdbSnapWriter* pWriter) { _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbTrace("vgId:%d %s done", TD_VID(pWriter->pTsdb->pVnode), __func__); + tsdbTrace("vgId:%d %s done", TD_VID(pWriter->tsdb->pVnode), __func__); } return code; } @@ -1261,7 +1198,7 @@ static int32_t tsdbSnapWriteDelTableData(STsdbSnapWriter* pWriter, TABLEID* pId, _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); } return code; } @@ -1270,7 +1207,7 @@ static int32_t tsdbSnapWriteDelDataStart(STsdbSnapWriter* pWriter) { int32_t code = 0; int32_t lino = 0; - STsdb* pTsdb = pWriter->pTsdb; + STsdb* pTsdb = pWriter->tsdb; SDelFile* pDelFile = pWriter->fs.pDelFile; pWriter->tbid = (TABLEID){0}; @@ -1310,7 +1247,7 @@ static int32_t tsdbSnapWriteDelDataEnd(STsdbSnapWriter* pWriter) { int32_t code = 0; int32_t lino = 0; - STsdb* pTsdb = pWriter->pTsdb; + STsdb* pTsdb = pWriter->tsdb; // end remaining table with NULL data code = tsdbSnapWriteDelTableData(pWriter, NULL, NULL, 0); @@ -1352,7 +1289,7 @@ static int32_t tsdbSnapWriteDelData(STsdbSnapWriter* pWriter, SSnapDataHdr* pHdr int32_t code = 0; int32_t lino = 0; - STsdb* pTsdb = pWriter->pTsdb; + STsdb* pTsdb = pWriter->tsdb; // start to write del data if need if (pWriter->pDelFWriter == NULL) { @@ -1373,19 +1310,21 @@ _exit: } return code; } +#endif // APIs int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWriter** ppWriter) { int32_t code = 0; int32_t lino = 0; +#if 0 // alloc STsdbSnapWriter* pWriter = (STsdbSnapWriter*)taosMemoryCalloc(1, sizeof(*pWriter)); if (pWriter == NULL) { code = TSDB_CODE_OUT_OF_MEMORY; TSDB_CHECK_CODE(code, lino, _exit); } - pWriter->pTsdb = pTsdb; + pWriter->tsdb = pTsdb; pWriter->sver = sver; pWriter->ever = ever; pWriter->minutes = pTsdb->keepCfg.days; @@ -1411,29 +1350,31 @@ int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWr TSDB_CHECK_CODE(code, lino, _exit); // SNAP_DATA_DEL +#endif _exit: if (code) { tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - if (pWriter) { - tBlockDataDestroy(&pWriter->sData); - tBlockDataDestroy(&pWriter->bData); - tBlockDataDestroy(&pWriter->inData); - tsdbFSDestroy(&pWriter->fs); - taosMemoryFree(pWriter); - pWriter = NULL; - } + // if (pWriter) { + // tBlockDataDestroy(&pWriter->sData); + // tBlockDataDestroy(&pWriter->bData); + // tBlockDataDestroy(&pWriter->inData); + // tsdbFSDestroy(&pWriter->fs); + // taosMemoryFree(pWriter); + // pWriter = NULL; + // } } else { tsdbInfo("vgId:%d %s done, sver:%" PRId64 " ever:%" PRId64, TD_VID(pTsdb->pVnode), __func__, sver, ever); } - *ppWriter = pWriter; + // *ppWriter = pWriter; return code; } -int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* pWriter) { +int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* writer) { int32_t code = 0; int32_t lino = 0; +#if 0 if (pWriter->pDataFWriter) { code = tsdbSnapWriteFileDataEnd(pWriter); TSDB_CHECK_CODE(code, lino, _exit); @@ -1444,32 +1385,34 @@ int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* pWriter) { TSDB_CHECK_CODE(code, lino, _exit); } - code = tsdbFSPrepareCommit(pWriter->pTsdb, &pWriter->fs); + code = tsdbFSPrepareCommit(pWriter->tsdb, &pWriter->fs); TSDB_CHECK_CODE(code, lino, _exit); +#endif _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(writer->tsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbDebug("vgId:%d %s done", TD_VID(pWriter->pTsdb->pVnode), __func__); + tsdbDebug("vgId:%d %s done", TD_VID(writer->tsdb->pVnode), __func__); } return code; } -int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback) { +int32_t tsdbSnapWriterClose(STsdbSnapWriter** writer, int8_t rollback) { int32_t code = 0; int32_t lino = 0; - STsdbSnapWriter* pWriter = *ppWriter; - STsdb* pTsdb = pWriter->pTsdb; +#if 0 + STsdbSnapWriter* pWriter = *writer; + STsdb* pTsdb = pWriter->tsdb; if (rollback) { - tsdbRollbackCommit(pWriter->pTsdb); + tsdbRollbackCommit(pWriter->tsdb); } else { // lock taosThreadRwlockWrlock(&pTsdb->rwLock); - code = tsdbFSCommit(pWriter->pTsdb); + code = tsdbFSCommit(pWriter->tsdb); if (code) { taosThreadRwlockUnlock(&pTsdb->rwLock); TSDB_CHECK_CODE(code, lino, _exit); @@ -1497,43 +1440,229 @@ int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback) { } tsdbFSDestroy(&pWriter->fs); taosMemoryFree(pWriter); - *ppWriter = NULL; + *writer = NULL; +#endif _exit: if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); + // tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); } else { - tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); + // tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); } return code; } -int32_t tsdbSnapWrite(STsdbSnapWriter* pWriter, SSnapDataHdr* pHdr) { +static int32_t tsdbSnapWriteDoWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInfo* row) { int32_t code = 0; int32_t lino = 0; - if (pHdr->type == SNAP_DATA_TSDB) { - code = tsdbSnapWriteTimeSeriesData(pWriter, pHdr); - TSDB_CHECK_CODE(code, lino, _exit); + // TODO + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInfo* row) { + int32_t code = 0; + int32_t lino = 0; + + while (writer->ctx->hasData) { + SRowInfo* row1 = tsdbIterMergerGetData(writer->ctx->dataIterMerger); + if (row1 == NULL) { + writer->ctx->hasData = false; + break; + } + + int32_t c = tRowInfoCmprFn(row1, row); + if (c <= 0) { + code = tsdbSnapWriteDoWriteTimeSeriesRow(writer, row1); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbIterMergerNext(writer->ctx->dataIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + break; + } + } + + if (row->suid == INT64_MAX) { + ASSERT(writer->ctx->hasData == false); goto _exit; - } else if (pWriter->pDataFWriter) { - code = tsdbSnapWriteFileDataEnd(pWriter); + } + + code = tsdbSnapWriteDoWriteTimeSeriesRow(writer, row); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteFileSetBegin(STsdbSnapWriter* writer, int32_t fid) { + int32_t code = 0; + int32_t lino = 0; + + // TODO + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteTombRecord(STsdbSnapWriter* writer, const STombRecord* record) { + int32_t code = 0; + int32_t lino = 0; + + // TODO + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteFileSetEnd(STsdbSnapWriter* writer) { + if (!writer->ctx->fsetWriteBegin) return 0; + + int32_t code = 0; + int32_t lino = 0; + + // TODO + SRowInfo row = { + .suid = INT64_MAX, + .uid = INT64_MAX, + }; + + code = tsdbSnapWriteTimeSeriesRow(writer, &row); + TSDB_CHECK_CODE(code, lino, _exit); + + STombRecord record = { + .suid = INT64_MAX, + .uid = INT64_MAX, + }; + + code = tsdbSnapWriteTombRecord(writer, &record); + TSDB_CHECK_CODE(code, lino, _exit); + + // close write + code = tsdbSttFileWriterClose(&writer->sttWriter, 0, writer->fopArr); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbDataFileWriterClose(&writer->dataWriter, 0, writer->fopArr); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* writer, SSnapDataHdr* hdr) { + int32_t code = 0; + int32_t lino = 0; + + SBlockData blockData[1] = {0}; + + code = tDecmprBlockData(hdr->data, hdr->size, blockData, writer->aBuf); + TSDB_CHECK_CODE(code, lino, _exit); + + int32_t fid = tsdbKeyFid(blockData->aTSKEY[0], writer->minutes, writer->precision); + if (fid != writer->ctx->fid) { + code = tsdbSnapWriteFileSetEnd(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbSnapWriteFileSetBegin(writer, fid); TSDB_CHECK_CODE(code, lino, _exit); } - if (pHdr->type == SNAP_DATA_DEL) { - code = tsdbSnapWriteDelData(pWriter, pHdr); + for (int32_t i = 0; i < blockData->nRow; ++i) { + SRowInfo rowInfo = { + .suid = blockData->suid, + .uid = blockData->uid ? blockData->uid : blockData->aUid[i], + .row = tsdbRowFromBlockData(blockData, i), + }; + + code = tsdbSnapWriteTimeSeriesRow(writer, &rowInfo); TSDB_CHECK_CODE(code, lino, _exit); - goto _exit; + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } else { + tsdbDebug("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64 " nRow:%d", TD_VID(writer->tsdb->pVnode), __func__, + blockData->suid, blockData->uid, blockData->nRow); + } + tBlockDataDestroy(blockData); + return code; +} + +static int32_t tsdbSnapWriteDecmprTombBlock(SSnapDataHdr* hdr, STombBlock* tombBlock) { + int32_t code = 0; + int32_t lino = 0; + + // TODO + +_exit: + return code; +} + +static int32_t tsdbSnapWriteTombData(STsdbSnapWriter* writer, SSnapDataHdr* hdr) { + int32_t code = 0; + int32_t lino = 0; + + STombBlock tombBlock[1] = {0}; + + code = tsdbSnapWriteDecmprTombBlock(hdr, tombBlock); + TSDB_CHECK_CODE(code, lino, _exit); + + for (int32_t i = 0; i < TOMB_BLOCK_SIZE(tombBlock); ++i) { + STombRecord record; + tTombBlockGet(tombBlock, i, &record); + + code = tsdbSnapWriteTombRecord(writer, &record); + TSDB_CHECK_CODE(code, lino, _exit); + } + + tTombBlockDestroy(tombBlock); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +int32_t tsdbSnapWrite(STsdbSnapWriter* writer, SSnapDataHdr* hdr) { + int32_t code = 0; + int32_t lino = 0; + + if (hdr->type == SNAP_DATA_TSDB) { + code = tsdbSnapWriteTimeSeriesData(writer, hdr); + TSDB_CHECK_CODE(code, lino, _exit); + } else if (hdr->type == SNAP_DATA_DEL) { + code = tsdbSnapWriteTombData(writer, hdr); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + ASSERT(0); } _exit: if (code) { tsdbError("vgId:%d %s failed at line %d since %s, type:%d index:%" PRId64 " size:%" PRId64, - TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code), pHdr->type, pHdr->index, pHdr->size); + TD_VID(writer->tsdb->pVnode), __func__, lino, tstrerror(code), hdr->type, hdr->index, hdr->size); } else { - tsdbDebug("vgId:%d %s done, type:%d index:%" PRId64 " size:%" PRId64, TD_VID(pWriter->pTsdb->pVnode), __func__, - pHdr->type, pHdr->index, pHdr->size); + tsdbDebug("vgId:%d %s done, type:%d index:%" PRId64 " size:%" PRId64, TD_VID(writer->tsdb->pVnode), __func__, + hdr->type, hdr->index, hdr->size); } return code; } From 61309862c2383e334ec9ffcc105f991b3e8ab54e Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Fri, 16 Jun 2023 17:59:00 +0800 Subject: [PATCH 13/21] fix comments of TD-24656 --- .../libs/executor/src/eventwindowoperator.c | 2 +- source/libs/executor/src/timesliceoperator.c | 2 +- source/libs/executor/src/timewindowoperator.c | 4 +-- source/libs/planner/src/planLogicCreater.c | 1 - source/libs/planner/src/planOptimizer.c | 19 ++++++++--- source/libs/planner/src/planPhysiCreater.c | 1 - source/libs/planner/src/planSpliter.c | 2 +- .../tsim/query/r/explain_tsorder.result | 34 +++++++++---------- 8 files changed, 37 insertions(+), 28 deletions(-) diff --git a/source/libs/executor/src/eventwindowoperator.c b/source/libs/executor/src/eventwindowoperator.c index addf9e9c6b..b95df32715 100644 --- a/source/libs/executor/src/eventwindowoperator.c +++ b/source/libs/executor/src/eventwindowoperator.c @@ -189,7 +189,6 @@ static SSDataBlock* eventWindowAggregate(SOperatorInfo* pOperator) { SSDataBlock* pRes = pInfo->binfo.pRes; blockDataCleanup(pRes); - pRes->info.scanFlag = MAIN_SCAN; SOperatorInfo* downstream = pOperator->pDownstream[0]; while (1) { @@ -198,6 +197,7 @@ static SSDataBlock* eventWindowAggregate(SOperatorInfo* pOperator) { break; } + pRes->info.scanFlag = pBlock->info.scanFlag; setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId); diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 770e0d4fbd..d48d5cf3f5 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -798,7 +798,6 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SOperatorInfo* downstream = pOperator->pDownstream[0]; blockDataCleanup(pResBlock); - pResBlock->info.scanFlag = MAIN_SCAN; while (1) { if (pSliceInfo->pNextGroupRes != NULL) { @@ -815,6 +814,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { break; } + pResBlock->info.scanFlag = pBlock->info.scanFlag; if (pSliceInfo->groupId == 0 && pBlock->info.id.groupId != 0) { pSliceInfo->groupId = pBlock->info.id.groupId; } else { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 5e90d78642..f29ea5057e 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1162,13 +1162,13 @@ static int32_t openStateWindowAggOptr(SOperatorInfo* pOperator) { int64_t st = taosGetTimestampUs(); SOperatorInfo* downstream = pOperator->pDownstream[0]; - pInfo->binfo.pRes->info.scanFlag = MAIN_SCAN; while (1) { SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); if (pBlock == NULL) { break; } + pInfo->binfo.pRes->info.scanFlag = pBlock->info.scanFlag; setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId); @@ -1804,7 +1804,6 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { int64_t st = taosGetTimestampUs(); int32_t order = pInfo->binfo.inputTsOrder; - pBInfo->pRes->info.scanFlag = MAIN_SCAN; SOperatorInfo* downstream = pOperator->pDownstream[0]; @@ -1814,6 +1813,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { break; } + pBInfo->pRes->info.scanFlag = pBlock->info.scanFlag; // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId); diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index c41a80d5aa..713f12e229 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -1058,7 +1058,6 @@ static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect projIdx++; } } - pSort->node.outputTsOrder = firstSortKey->order; } if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index c83af7afa0..2371731467 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2895,13 +2895,24 @@ static SSortLogicNode* sortNonPriKeySatisfied(SLogicNode* pNode) { return NULL; } SSortLogicNode* pSort = (SSortLogicNode*)pNode; - if (sortPriKeyOptIsPriKeyOrderBy(pSort->pSortKeys) || 1 != LIST_LENGTH(pSort->node.pChildren)) { + if (sortPriKeyOptIsPriKeyOrderBy(pSort->pSortKeys)) { return NULL; } + SNode* pSortKeyNode = NULL, *pSortKeyExpr = NULL; + FOREACH(pSortKeyNode, pSort->pSortKeys) { + pSortKeyExpr = ((SOrderByExprNode*)pSortKeyNode)->pExpr; + switch (nodeType(pSortKeyExpr)) { + case QUERY_NODE_COLUMN: + break; + case QUERY_NODE_VALUE: + continue; + default: + return NULL; + } + } - SNode* pSortKeyNode = ((SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0))->pExpr; - if (nodeType(pSortKeyNode) != QUERY_NODE_COLUMN || ((SColumnNode*)pSortKeyNode)->projIdx != 1 || - ((SColumnNode*)pSortKeyNode)->node.resType.type != TSDB_DATA_TYPE_TIMESTAMP) { + if (!pSortKeyExpr || ((SColumnNode*)pSortKeyExpr)->projIdx != 1 || + ((SColumnNode*)pSortKeyExpr)->node.resType.type != TSDB_DATA_TYPE_TIMESTAMP) { return NULL; } return pSort; diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 9ae96bdf8b..b3d94a5e47 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1573,7 +1573,6 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SMergeLogicNode* pM pMerge->srcGroupId = pMergeLogicNode->srcGroupId; pMerge->groupSort = pMergeLogicNode->groupSort; pMerge->ignoreGroupId = pMergeLogicNode->ignoreGroupId; - pMerge->node.inputTsOrder = pMergeLogicNode->node.outputTsOrder; int32_t code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index bb129e1fa5..246ee13fb0 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -534,7 +534,7 @@ static int32_t stbSplGetNumOfVgroups(SLogicNode* pNode) { static int32_t stbSplRewriteFromMergeNode(SMergeLogicNode* pMerge, SLogicNode* pNode) { int32_t code = TSDB_CODE_SUCCESS; - pMerge->node.inputTsOrder = pNode->inputTsOrder; + pMerge->node.inputTsOrder = pNode->outputTsOrder; pMerge->node.outputTsOrder = pNode->outputTsOrder; switch (nodeType(pNode)) { diff --git a/tests/script/tsim/query/r/explain_tsorder.result b/tests/script/tsim/query/r/explain_tsorder.result index deaa09015f..a31a05e66f 100644 --- a/tests/script/tsim/query/r/explain_tsorder.result +++ b/tests/script/tsim/query/r/explain_tsorder.result @@ -672,7 +672,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -748,7 +748,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -824,7 +824,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -900,7 +900,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -976,7 +976,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -1052,7 +1052,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -1128,7 +1128,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -1204,7 +1204,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 9.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 10.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 11.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 12.row *************************** @@ -1288,7 +1288,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 13.row *************************** QUERY_PLAN: Merge ResBlocks: False *************************** 14.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=asc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 15.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 16.row *************************** @@ -1824,7 +1824,7 @@ taos> select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) taos> explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; *************************** 1.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 2.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 3.row *************************** @@ -1906,7 +1906,7 @@ QUERY_PLAN: Time Range: [-9223372036854775808, 922 taos> explain verbose true select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a asc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by d desc\G; *************************** 1.row *************************** -QUERY_PLAN: -> Sort input_order=asc output_order=desc (columns=3 width=24) +QUERY_PLAN: -> Sort input_order=asc output_order=unknown (columns=3 width=24) *************************** 2.row *************************** QUERY_PLAN: Output: columns=3 width=24 *************************** 3.row *************************** @@ -1988,7 +1988,7 @@ QUERY_PLAN: Time Range: [-9223372036854775808, 922 taos> explain verbose true select * from (select ts as a, c2 as b from meters order by c2 desc)\G; *************************** 1.row *************************** -QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=unknown output_order=unknown) *************************** 2.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 3.row *************************** @@ -2000,7 +2000,7 @@ QUERY_PLAN: -> Data Exchange 1:1 (width=12) *************************** 6.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 7.row *************************** -QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +QUERY_PLAN: -> Sort input_order=unknown output_order=unknown (columns=2 width=12) *************************** 8.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 9.row *************************** @@ -2014,7 +2014,7 @@ QUERY_PLAN: -> Data Exchange 1:1 (width=12) *************************** 13.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 14.row *************************** -QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +QUERY_PLAN: -> Sort input_order=unknown output_order=unknown (columns=2 width=12) *************************** 15.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 16.row *************************** @@ -2062,7 +2062,7 @@ QUERY_PLAN: Output: Ignore Group Id: true *************************** 6.row *************************** QUERY_PLAN: Merge ResBlocks: True *************************** 7.row *************************** -QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=desc output_order=desc) +QUERY_PLAN: -> SortMerge (columns=2 width=12 input_order=unknown output_order=unknown) *************************** 8.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 9.row *************************** @@ -2074,7 +2074,7 @@ QUERY_PLAN: -> Data Exchange 1:1 (width=12) *************************** 12.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 13.row *************************** -QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +QUERY_PLAN: -> Sort input_order=unknown output_order=unknown (columns=2 width=12) *************************** 14.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 15.row *************************** @@ -2088,7 +2088,7 @@ QUERY_PLAN: -> Data Exchange 1:1 (width=12) *************************** 19.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 20.row *************************** -QUERY_PLAN: -> Sort input_order=unknown output_order=desc (columns=2 width=12) +QUERY_PLAN: -> Sort input_order=unknown output_order=unknown (columns=2 width=12) *************************** 21.row *************************** QUERY_PLAN: Output: columns=2 width=12 *************************** 22.row *************************** From 4097b860d31e870d4c1acf6a4c8d49cb945e5a1c Mon Sep 17 00:00:00 2001 From: kailixu Date: Fri, 16 Jun 2023 19:04:12 +0800 Subject: [PATCH 14/21] enh: support delete tsma interval --- source/dnode/vnode/src/sma/smaTimeRange.c | 46 +++++++++++++++++-- source/dnode/vnode/src/vnd/vnodeSvr.c | 2 - .../script/tsim/sma/tsmaCreateInsertQuery.sim | 17 ++++++- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/source/dnode/vnode/src/sma/smaTimeRange.c b/source/dnode/vnode/src/sma/smaTimeRange.c index 3542ea9ffb..ed1a451931 100644 --- a/source/dnode/vnode/src/sma/smaTimeRange.c +++ b/source/dnode/vnode/src/sma/smaTimeRange.c @@ -29,7 +29,7 @@ int32_t tdProcessTSmaInsert(SSma *pSma, int64_t indexUid, const char *msg) { int32_t code = TSDB_CODE_SUCCESS; if ((code = tdProcessTSmaInsertImpl(pSma, indexUid, msg)) < 0) { - smaWarn("vgId:%d, insert tsma data failed since %s", SMA_VID(pSma), tstrerror(terrno)); + smaError("vgId:%d, insert tsma data failed since %s", SMA_VID(pSma), tstrerror(terrno)); } return code; @@ -346,6 +346,43 @@ _end: return TSDB_CODE_SUCCESS; } +static int32_t tsmaProcessDelReq(SSma *pSma, int64_t indexUid, SBatchDeleteReq *pDelReq) { + int32_t code = 0; + int32_t lino = 0; + + if (taosArrayGetSize(pDelReq->deleteReqs) > 0) { + int32_t len = 0; + tEncodeSize(tEncodeSBatchDeleteReq, pDelReq, len, code); + TSDB_CHECK_CODE(code, lino, _exit); + + void *pBuf = rpcMallocCont(len + sizeof(SMsgHead)); + if (!pBuf) { + code = terrno; + TSDB_CHECK_CODE(code, lino, _exit); + } + + SEncoder encoder; + tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SMsgHead)), len); + tEncodeSBatchDeleteReq(&encoder, pDelReq); + tEncoderClear(&encoder); + + ((SMsgHead *)pBuf)->vgId = TD_VID(pSma->pVnode); + + SRpcMsg delMsg = {.msgType = TDMT_VND_BATCH_DEL, .pCont = pBuf, .contLen = len + sizeof(SMsgHead)}; + code = tmsgPutToQueue(&pSma->pVnode->msgCb, WRITE_QUEUE, &delMsg); + TSDB_CHECK_CODE(code, lino, _exit); + } + +_exit: + taosArrayDestroy(pDelReq->deleteReqs); + if (code) { + smaError("vgId:%d, failed to process delete req for smaIndex %" PRIi64 " since %s", SMA_VID(pSma), indexUid, + tstrerror(code)); + } + + return code; +} + /** * @brief Insert/Update Time-range-wise SMA data. * @@ -355,7 +392,6 @@ _end: */ static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) { const SArray *pDataBlocks = (const SArray *)msg; - // TODO: destroy SSDataBlocks(msg) if (!pDataBlocks) { terrno = TSDB_CODE_TSMA_INVALID_PTR; smaWarn("vgId:%d, insert tsma data failed since pDataBlocks is NULL", SMA_VID(pSma)); @@ -419,8 +455,10 @@ static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char goto _err; } - // TODO deleteReq - taosArrayDestroy(deleteReq.deleteReqs); + if ((terrno = tsmaProcessDelReq(pSma, indexUid, &deleteReq)) != 0) { + goto _err; + } + #if 0 if (!strncasecmp("td.tsma.rst.tb", pTsmaStat->pTSma->dstTbName, 14)) { terrno = TSDB_CODE_APP_ERROR; diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index c2e577848b..5f866dee69 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -593,9 +593,7 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { } } -// TODO: remove the function void smaHandleRes(void *pVnode, int64_t smaId, const SArray *data) { - // TODO // blockDebugShowDataBlocks(data, __func__); tdProcessTSmaInsert(((SVnode *)pVnode)->pSma, smaId, (const char *)data); } diff --git a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim index 60f769d2ae..692212d511 100644 --- a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim +++ b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim @@ -414,6 +414,21 @@ if $data05 != 30.000000000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT +sql delete from stb; +print =============== query after delete in common vgroups +sql select _wstart, _wend, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m) order by _wstart; +if $rows != 0 then + print rows $rows != 0 + return -1 +endi +sleep 2000 +print =============== query after delete in designated vgroups +sql select _wend, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m) order by _wstart; +if $rows != 0 then + print rows $rows != 0 + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file From aba73614df565675582a6683456bed5cf4240c5a Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Sat, 17 Jun 2023 00:12:11 +0800 Subject: [PATCH 15/21] more code --- source/dnode/vnode/src/tsdb/tsdbCommit2.c | 11 +- source/dnode/vnode/src/tsdb/tsdbFSetRW.c | 292 ++++++++++++++++++++ source/dnode/vnode/src/tsdb/tsdbFSetRW.h | 56 ++++ source/dnode/vnode/src/tsdb/tsdbMerge.c | 15 +- source/dnode/vnode/src/tsdb/tsdbSttFileRW.c | 19 +- source/dnode/vnode/src/tsdb/tsdbSttFileRW.h | 5 +- 6 files changed, 373 insertions(+), 25 deletions(-) create mode 100644 source/dnode/vnode/src/tsdb/tsdbFSetRW.c create mode 100644 source/dnode/vnode/src/tsdb/tsdbFSetRW.h diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c index 6d9e670598..ce88aa55d3 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c @@ -73,13 +73,10 @@ static int32_t tsdbCommitOpenWriter(SCommitter2 *committer) { .szPage = committer->szPage, .cmprAlg = committer->cmprAlg, .compactVersion = committer->compactVersion, - .file = - { - .type = TSDB_FTYPE_STT, - .did = committer->ctx->did, - .fid = committer->ctx->fid, - .cid = committer->ctx->cid, - }, + .did = committer->ctx->did, + .fid = committer->ctx->fid, + .cid = committer->ctx->cid, + .level = 0, }}; code = tsdbSttFileWriterOpen(config, &committer->sttWriter); diff --git a/source/dnode/vnode/src/tsdb/tsdbFSetRW.c b/source/dnode/vnode/src/tsdb/tsdbFSetRW.c new file mode 100644 index 0000000000..949de99a4b --- /dev/null +++ b/source/dnode/vnode/src/tsdb/tsdbFSetRW.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tsdbFSetRW.h" + +// SFSetWriter ================================================== +struct SFSetWriter { + SFSetWriterConfig config[1]; + + SSkmInfo skmTb[1]; + SSkmInfo skmRow[1]; + uint8_t *bufArr[10]; + + struct { + TABLEID tbid[1]; + } ctx[1]; + + // writer + SBlockData blockData[2]; + int32_t blockDataIdx; + SDataFileWriter *dataWriter; + SSttFileWriter *sttWriter; +}; + +static int32_t tsdbFSetWriteTableDataBegin(SFSetWriter *writer, const TABLEID *tbid) { + int32_t code = 0; + int32_t lino = 0; + + writer->ctx->tbid->suid = tbid->suid; + writer->ctx->tbid->uid = tbid->uid; + + code = tsdbUpdateSkmTb(writer->config->tsdb, writer->ctx->tbid, writer->skmTb); + TSDB_CHECK_CODE(code, lino, _exit); + + writer->blockDataIdx = 0; + for (int32_t i = 0; i < ARRAY_SIZE(writer->blockData); i++) { + code = tBlockDataInit(&writer->blockData[i], writer->ctx->tbid, writer->skmTb->pTSchema, NULL, 0); + TSDB_CHECK_CODE(code, lino, _exit); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->config->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbFSetWriteTableDataEnd(SFSetWriter *writer) { + if (writer->ctx->tbid->uid == 0) return 0; + + int32_t code = 0; + int32_t lino = 0; + + int32_t cidx = writer->blockDataIdx; + int32_t pidx = ((cidx + 1) & 1); + int32_t numRow = ((writer->blockData[pidx].nRow + writer->blockData[cidx].nRow) >> 1); + + if (writer->blockData[pidx].nRow > 0 && numRow >= writer->config->minRow) { + ASSERT(writer->blockData[pidx].nRow == writer->config->maxRow); + + SRowInfo row = { + .suid = writer->ctx->tbid->suid, + .uid = writer->ctx->tbid->uid, + .row = tsdbRowFromBlockData(writer->blockData + pidx, 0), + }; + + for (int32_t i = 0; i < numRow; i++) { + row.row.iRow = i; + + code = tsdbDataFileWriteRow(writer->dataWriter, &row); + TSDB_CHECK_CODE(code, lino, _exit); + } + + code = tsdbDataFileFlush(writer->dataWriter); + TSDB_CHECK_CODE(code, lino, _exit); + + for (int32_t i = numRow; i < writer->blockData[pidx].nRow; i++) { + row.row.iRow = i; + code = tsdbDataFileWriteRow(writer->dataWriter, &row); + TSDB_CHECK_CODE(code, lino, _exit); + } + + row.row = tsdbRowFromBlockData(writer->blockData + cidx, 0); + for (int32_t i = 0; i < writer->blockData[cidx].nRow; i++) { + row.row.iRow = i; + code = tsdbDataFileWriteRow(writer->dataWriter, &row); + TSDB_CHECK_CODE(code, lino, _exit); + } + } else { + // pidx + if (writer->blockData[pidx].nRow > 0) { + code = tsdbDataFileWriteBlockData(writer->dataWriter, &writer->blockData[pidx]); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // cidx + if (writer->blockData[cidx].nRow < writer->config->minRow) { + code = tsdbSttFileWriteBlockData(writer->sttWriter, &writer->blockData[cidx]); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + code = tsdbDataFileWriteBlockData(writer->dataWriter, &writer->blockData[cidx]); + TSDB_CHECK_CODE(code, lino, _exit); + } + } + + for (int32_t i = 0; i < ARRAY_SIZE(writer->blockData); i++) { + tBlockDataReset(&writer->blockData[i]); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->config->tsdb->pVnode), lino, code); + } + return code; +} + +int32_t tsdbFSetWriterOpen(SFSetWriterConfig *config, SFSetWriter **writer) { + int32_t code = 0; + int32_t lino = 0; + + writer[0] = taosMemoryCalloc(1, sizeof(*writer[0])); + if (writer[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; + + writer[0]->config[0] = config[0]; + + // data writer + if (!config->toSttOnly) { + SDataFileWriterConfig dataWriterConfig = { + .tsdb = config->tsdb, + .cmprAlg = config->cmprAlg, + .maxRow = config->maxRow, + .szPage = config->szPage, + .fid = config->fid, + .cid = config->cid, + .did = config->did, + .compactVersion = config->compactVersion, + .skmTb = writer[0]->skmTb, + .skmRow = writer[0]->skmRow, + .bufArr = writer[0]->bufArr, + }; + for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ++ftype) { + dataWriterConfig.files[ftype].exist = config->files[ftype].exist; + dataWriterConfig.files[ftype].file = config->files[ftype].file; + } + + code = tsdbDataFileWriterOpen(&dataWriterConfig, &writer[0]->dataWriter); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // stt writer + SSttFileWriterConfig sttWriterConfig = { + .tsdb = config->tsdb, + .maxRow = config->maxRow, + .szPage = config->szPage, + .cmprAlg = config->cmprAlg, + .compactVersion = config->compactVersion, + .did = config->did, + .fid = config->fid, + .cid = config->cid, + .level = config->level, + .skmTb = writer[0]->skmTb, + .skmRow = writer[0]->skmRow, + .bufArr = writer[0]->bufArr, + }; + code = tsdbSttFileWriterOpen(&sttWriterConfig, &writer[0]->sttWriter); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(config->tsdb->pVnode), lino, code); + } + return code; +} + +int32_t tsdbFSetWriterClose(SFSetWriter **writer, bool abort, TFileOpArray *fopArr) { + if (writer[0] == NULL) return 0; + + int32_t code = 0; + int32_t lino = 0; + + STsdb *tsdb = writer[0]->config->tsdb; + + // end + if (!writer[0]->config->toSttOnly) { + code = tsdbDataFileWriterClose(&writer[0]->dataWriter, abort, fopArr); + TSDB_CHECK_CODE(code, lino, _exit); + } + + code = tsdbSttFileWriterClose(&writer[0]->sttWriter, abort, fopArr); + TSDB_CHECK_CODE(code, lino, _exit); + + // free + for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->blockData); i++) { + tBlockDataDestroy(&writer[0]->blockData[i]); + } + for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->bufArr); i++) { + tFree(writer[0]->bufArr[i]); + } + tDestroyTSchema(writer[0]->skmRow->pTSchema); + tDestroyTSchema(writer[0]->skmTb->pTSchema); + taosMemoryFree(writer[0]); + writer[0] = NULL; + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code); + } + return code; +} + +int32_t tsdbFSetWriteRow(SFSetWriter *writer, SRowInfo *row) { + int32_t code = 0; + int32_t lino = 0; + + if (writer->config->toSttOnly) { + code = tsdbSttFileWriteRow(writer->sttWriter, row); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + if (writer->ctx->tbid->uid != row->uid) { + code = tsdbFSetWriteTableDataEnd(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbFSetWriteTableDataBegin(writer, (TABLEID *)row); + TSDB_CHECK_CODE(code, lino, _exit); + } + + if (row->row.type == TSDBROW_ROW_FMT) { + code = tsdbUpdateSkmRow(writer->config->tsdb, writer->ctx->tbid, TSDBROW_SVERSION(&row->row), writer->skmRow); + TSDB_CHECK_CODE(code, lino, _exit); + } + + TSDBKEY key = TSDBROW_KEY(&row->row); + if (key.version <= writer->config->compactVersion // + && writer->blockData[writer->blockDataIdx].nRow > 0 // + && key.ts == writer->blockData[writer->blockDataIdx].aTSKEY[writer->blockData[writer->blockDataIdx].nRow - 1]) { + code = tBlockDataUpdateRow(&writer->blockData[writer->blockDataIdx], &row->row, writer->skmRow->pTSchema); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + if (writer->blockData[writer->blockDataIdx].nRow >= writer->config->maxRow) { + int32_t idx = ((writer->blockDataIdx + 1) & 1); + if (writer->blockData[idx].nRow >= writer->config->maxRow) { + code = tsdbDataFileWriteBlockData(writer->dataWriter, &writer->blockData[idx]); + TSDB_CHECK_CODE(code, lino, _exit); + + tBlockDataClear(&writer->blockData[idx]); + } + writer->blockDataIdx = idx; + } + + code = + tBlockDataAppendRow(&writer->blockData[writer->blockDataIdx], &row->row, writer->skmRow->pTSchema, row->uid); + TSDB_CHECK_CODE(code, lino, _exit); + } + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->config->tsdb->pVnode), lino, code); + } + return code; +} + +int32_t tsdbFSetWriteTombRecord(SFSetWriter *writer, const STombRecord *tombRecord) { + int32_t code = 0; + int32_t lino = 0; + + if (writer->config->toSttOnly || tsdbSttFileWriterIsOpened(writer->sttWriter)) { + code = tsdbSttFileWriteTombRecord(writer->sttWriter, tombRecord); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + code = tsdbDataFileWriteTombRecord(writer->dataWriter, tombRecord); + TSDB_CHECK_CODE(code, lino, _exit); + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->config->tsdb->pVnode), lino, code); + } + return code; +} \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbFSetRW.h b/source/dnode/vnode/src/tsdb/tsdbFSetRW.h new file mode 100644 index 0000000000..76f734c16f --- /dev/null +++ b/source/dnode/vnode/src/tsdb/tsdbFSetRW.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "tsdbDataFileRW.h" +#include "tsdbSttFileRW.h" + +#ifndef _TSDB_FSET_RW_H +#define _TSDB_FSET_RW_H + +#ifdef __cplusplus +extern "C" { +#endif + +// +typedef struct SFSetWriter SFSetWriter; +typedef struct { + STsdb *tsdb; + bool toSttOnly; + int64_t compactVersion; + int32_t minRow; + int32_t maxRow; + int32_t szPage; + int8_t cmprAlg; + int32_t fid; + int64_t cid; + SDiskID did; + int32_t level; + struct { + bool exist; + STFile file; + } files[TSDB_FTYPE_MAX]; + STFile sttFile; +} SFSetWriterConfig; + +int32_t tsdbFSetWriterOpen(SFSetWriterConfig *config, SFSetWriter **writer); +int32_t tsdbFSetWriterClose(SFSetWriter **writer, bool abort, TFileOpArray *fopArr); +int32_t tsdbFSetWriteRow(SFSetWriter *writer, SRowInfo *row); +int32_t tsdbFSetWriteTombRecord(SFSetWriter *writer, const STombRecord *tombRecord); + +#ifdef __cplusplus +} +#endif + +#endif /*_TSDB_FSET_RW_H*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.c b/source/dnode/vnode/src/tsdb/tsdbMerge.c index f3a599b7a0..358d735b1d 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMerge.c +++ b/source/dnode/vnode/src/tsdb/tsdbMerge.c @@ -422,17 +422,10 @@ static int32_t tsdbMergeFileSetBeginOpenWriter(SMerger *merger) { .szPage = merger->szPage, .cmprAlg = merger->cmprAlg, .compactVersion = merger->compactVersion, - .file = - { - .type = TSDB_FTYPE_STT, - .did = did, - .fid = merger->ctx->fset->fid, - .cid = merger->cid, - .size = 0, - .stt = {{ - .level = merger->ctx->level, - }}, - }, + .did = did, + .fid = merger->ctx->fset->fid, + .cid = merger->cid, + .level = merger->ctx->level, }}; code = tsdbSttFileWriterOpen(config, &merger->sttWriter); TSDB_CHECK_CODE(code, lino, _exit); diff --git a/source/dnode/vnode/src/tsdb/tsdbSttFileRW.c b/source/dnode/vnode/src/tsdb/tsdbSttFileRW.c index 3ff0191ce6..97a2a8b478 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSttFileRW.c +++ b/source/dnode/vnode/src/tsdb/tsdbSttFileRW.c @@ -654,7 +654,17 @@ static int32_t tsdbSttFWriterDoOpen(SSttFileWriter *writer) { if (!writer->config->skmRow) writer->config->skmRow = writer->skmRow; if (!writer->config->bufArr) writer->config->bufArr = writer->bufArr; - writer->file[0] = writer->config->file; + writer->file[0] = (STFile){ + .type = TSDB_FTYPE_STT, + .did = writer->config->did, + .fid = writer->config->fid, + .cid = writer->config->cid, + .size = 0, + .stt[0] = + { + .level = writer->config->level, + }, + }; // open file int32_t flag = TD_FILE_READ | TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC; @@ -735,7 +745,7 @@ static int32_t tsdbSttFWriterCloseCommit(SSttFileWriter *writer, TFileOpArray *o ASSERT(writer->file->size > 0); STFileOp op = (STFileOp){ .optype = TSDB_FOP_CREATE, - .fid = writer->config->file.fid, + .fid = writer->config->fid, .nf = writer->file[0], }; @@ -751,16 +761,13 @@ _exit: static int32_t tsdbSttFWriterCloseAbort(SSttFileWriter *writer) { char fname[TSDB_FILENAME_LEN]; - tsdbTFileName(writer->config->tsdb, &writer->config->file, fname); + tsdbTFileName(writer->config->tsdb, writer->file, fname); tsdbCloseFile(&writer->fd); taosRemoveFile(fname); return 0; } int32_t tsdbSttFileWriterOpen(const SSttFileWriterConfig *config, SSttFileWriter **writer) { - ASSERT(config->file.type == TSDB_FTYPE_STT); - ASSERT(config->file.size == 0); - writer[0] = taosMemoryCalloc(1, sizeof(*writer[0])); if (writer[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; diff --git a/source/dnode/vnode/src/tsdb/tsdbSttFileRW.h b/source/dnode/vnode/src/tsdb/tsdbSttFileRW.h index f3b2e66ab2..b26d2f743a 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSttFileRW.h +++ b/source/dnode/vnode/src/tsdb/tsdbSttFileRW.h @@ -71,7 +71,10 @@ struct SSttFileWriterConfig { int32_t szPage; int8_t cmprAlg; int64_t compactVersion; - STFile file; + SDiskID did; + int32_t fid; + int64_t cid; + int32_t level; SSkmInfo *skmTb; SSkmInfo *skmRow; uint8_t **bufArr; From b40069c0e12e21219ef2abed5ff8b42e31b58ebd Mon Sep 17 00:00:00 2001 From: kailixu Date: Sat, 17 Jun 2023 05:05:43 +0800 Subject: [PATCH 16/21] chore: log optimization --- source/dnode/vnode/src/sma/smaTimeRange.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/sma/smaTimeRange.c b/source/dnode/vnode/src/sma/smaTimeRange.c index ed1a451931..84cd44e837 100644 --- a/source/dnode/vnode/src/sma/smaTimeRange.c +++ b/source/dnode/vnode/src/sma/smaTimeRange.c @@ -376,8 +376,8 @@ static int32_t tsmaProcessDelReq(SSma *pSma, int64_t indexUid, SBatchDeleteReq * _exit: taosArrayDestroy(pDelReq->deleteReqs); if (code) { - smaError("vgId:%d, failed to process delete req for smaIndex %" PRIi64 " since %s", SMA_VID(pSma), indexUid, - tstrerror(code)); + smaError("vgId:%d, failed at line %d to process delete req for smaIndex %" PRIi64 " since %s", SMA_VID(pSma), lino, + indexUid, tstrerror(code)); } return code; From fe4cf1520127d239cede54ed7c76990e062119e3 Mon Sep 17 00:00:00 2001 From: Ping Xiao Date: Sun, 18 Jun 2023 00:18:32 +0800 Subject: [PATCH 17/21] release 3.0.5.1 --- docs/en/28-releases/01-tdengine.md | 4 ++++ docs/en/28-releases/02-tools.md | 4 ++++ docs/zh/28-releases/01-tdengine.md | 4 ++++ docs/zh/28-releases/02-tools.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index a9336697f2..f4d9ba8e42 100644 --- a/docs/en/28-releases/01-tdengine.md +++ b/docs/en/28-releases/01-tdengine.md @@ -10,6 +10,10 @@ For TDengine 2.x installation packages by version, please visit [here](https://w import Release from "/components/ReleaseV3"; +## 3.0.5.1 + + + ## 3.0.5.0 diff --git a/docs/en/28-releases/02-tools.md b/docs/en/28-releases/02-tools.md index 28c2ff7a7f..f3099b13b4 100644 --- a/docs/en/28-releases/02-tools.md +++ b/docs/en/28-releases/02-tools.md @@ -10,6 +10,10 @@ For other historical version installers, please visit [here](https://www.taosdat import Release from "/components/ReleaseV3"; +## 2.5.2 + + + ## 2.5.1 diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index 3ee19de84f..ae47388566 100644 --- a/docs/zh/28-releases/01-tdengine.md +++ b/docs/zh/28-releases/01-tdengine.md @@ -10,6 +10,10 @@ TDengine 2.x 各版本安装包请访问[这里](https://www.taosdata.com/all-do import Release from "/components/ReleaseV3"; +## 3.0.5.1 + + + ## 3.0.5.0 diff --git a/docs/zh/28-releases/02-tools.md b/docs/zh/28-releases/02-tools.md index fbd12b1440..ba58ed9600 100644 --- a/docs/zh/28-releases/02-tools.md +++ b/docs/zh/28-releases/02-tools.md @@ -10,6 +10,10 @@ taosTools 各版本安装包下载链接如下: import Release from "/components/ReleaseV3"; +## 2.5.2 + + + ## 2.5.1 From 073a2b8dd3d7e8081722fa68939510f0ea1a1c45 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 19 Jun 2023 09:32:29 +0800 Subject: [PATCH 18/21] refact more code --- source/dnode/vnode/src/tsdb/tsdbCommit2.c | 111 ++++++--------- source/dnode/vnode/src/tsdb/tsdbCommit2.h | 1 + source/dnode/vnode/src/tsdb/tsdbFSetRW.h | 1 - source/dnode/vnode/src/tsdb/tsdbMerge.c | 161 +++++++++++----------- source/dnode/vnode/src/tsdb/tsdbMerge.h | 1 + 5 files changed, 121 insertions(+), 154 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c index ce88aa55d3..7e5db55eba 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c @@ -21,8 +21,8 @@ typedef struct { TFileSetArray *fsetArr; TFileOpArray fopArray[1]; - SSkmInfo skmTb[1]; - SSkmInfo skmRow[1]; + // SSkmInfo skmTb[1]; + // SSkmInfo skmRow[1]; int32_t minutes; int8_t precision; @@ -56,45 +56,29 @@ typedef struct { SIterMerger *tombIterMerger; // writer - SBlockData blockData[2]; - int32_t blockDataIdx; - SDataFileWriter *dataWriter; - SSttFileWriter *sttWriter; + SFSetWriter *writer; } SCommitter2; static int32_t tsdbCommitOpenWriter(SCommitter2 *committer) { int32_t code = 0; int32_t lino = 0; - // stt writer - SSttFileWriterConfig config[1] = {{ + SFSetWriterConfig config = { .tsdb = committer->tsdb, + .toSttOnly = true, + .compactVersion = committer->compactVersion, + .minRow = committer->minRow, .maxRow = committer->maxRow, .szPage = committer->szPage, .cmprAlg = committer->cmprAlg, - .compactVersion = committer->compactVersion, - .did = committer->ctx->did, .fid = committer->ctx->fid, .cid = committer->ctx->cid, + .did = committer->ctx->did, .level = 0, - }}; + }; - code = tsdbSttFileWriterOpen(config, &committer->sttWriter); - TSDB_CHECK_CODE(code, lino, _exit); - - // data writer if (committer->sttTrigger == 1) { - // data writer - SDataFileWriterConfig config = { - .tsdb = committer->tsdb, - .cmprAlg = committer->cmprAlg, - .maxRow = committer->maxRow, - .szPage = committer->szPage, - .fid = committer->ctx->fid, - .cid = committer->ctx->cid, - .did = committer->ctx->did, - .compactVersion = committer->compactVersion, - }; + config.toSttOnly = false; if (committer->ctx->fset) { for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ftype++) { @@ -104,11 +88,11 @@ static int32_t tsdbCommitOpenWriter(SCommitter2 *committer) { } } } - - code = tsdbDataFileWriterOpen(&config, &committer->dataWriter); - TSDB_CHECK_CODE(code, lino, _exit); } + code = tsdbFSetWriterOpen(&config, &committer->writer); + TSDB_CHECK_CODE(code, lino, _exit); + _exit: if (code) { TSDB_ERROR_LOG(TD_VID(committer->tsdb->pVnode), lino, code); @@ -117,22 +101,10 @@ _exit: } static int32_t tsdbCommitCloseWriter(SCommitter2 *committer) { - int32_t code = 0; - int32_t lino = 0; - - code = tsdbSttFileWriterClose(&committer->sttWriter, 0, committer->fopArray); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbDataFileWriterClose(&committer->dataWriter, 0, committer->fopArray); - TSDB_CHECK_CODE(code, lino, _exit); - -_exit: - if (code) { - TSDB_ERROR_LOG(TD_VID(committer->tsdb->pVnode), lino, code); - } - return code; + return tsdbFSetWriterClose(&committer->writer, 0, committer->fopArray); } +#if 0 static int32_t tsdbCommitTSDataToDataTableBegin(SCommitter2 *committer, const TABLEID *tbid) { int32_t code = 0; int32_t lino = 0; @@ -328,17 +300,30 @@ _exit: } return code; } +#endif static int32_t tsdbCommitTSData(SCommitter2 *committer) { - int32_t code = 0; - int32_t lino = 0; + int32_t code = 0; + int32_t lino = 0; + SMetaInfo info; - // loop iter - if (committer->sttTrigger == 1) { - code = tsdbCommitTSDataToData(committer); + for (SRowInfo *row; (row = tsdbIterMergerGetData(committer->dataIterMerger)) != NULL;) { + if (row->uid != committer->ctx->tbid->uid) { + // Ignore table of obsolescence + if (metaGetInfo(committer->tsdb->pVnode->pMeta, row->uid, &info, NULL) != 0) { + code = tsdbIterMergerSkipTableData(committer->dataIterMerger, (TABLEID *)row); + TSDB_CHECK_CODE(code, lino, _exit); + continue; + } + + committer->ctx->tbid->suid = row->suid; + committer->ctx->tbid->uid = row->uid; + } + + code = tsdbFSetWriteRow(committer->writer, row); TSDB_CHECK_CODE(code, lino, _exit); - } else { - code = tsdbCommitTSDataToStt(committer); + + code = tsdbIterMergerNext(committer->dataIterMerger); TSDB_CHECK_CODE(code, lino, _exit); } @@ -353,22 +338,12 @@ static int32_t tsdbCommitTombData(SCommitter2 *committer) { int32_t code = 0; int32_t lino = 0; - if (committer->dataWriter == NULL || tsdbSttFileWriterIsOpened(committer->sttWriter)) { - for (STombRecord *record; (record = tsdbIterMergerGetTombRecord(committer->tombIterMerger));) { - code = tsdbSttFileWriteTombRecord(committer->sttWriter, record); - TSDB_CHECK_CODE(code, lino, _exit); + for (STombRecord *record; (record = tsdbIterMergerGetTombRecord(committer->tombIterMerger));) { + code = tsdbFSetWriteTombRecord(committer->writer, record); + TSDB_CHECK_CODE(code, lino, _exit); - code = tsdbIterMergerNext(committer->tombIterMerger); - TSDB_CHECK_CODE(code, lino, _exit); - } - } else { - for (STombRecord *record; (record = tsdbIterMergerGetTombRecord(committer->tombIterMerger));) { - code = tsdbDataFileWriteTombRecord(committer->dataWriter, record); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbIterMergerNext(committer->tombIterMerger); - TSDB_CHECK_CODE(code, lino, _exit); - } + code = tsdbIterMergerNext(committer->tombIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); } _exit: @@ -529,8 +504,7 @@ static int32_t tsdbCommitFileSetBegin(SCommitter2 *committer) { ASSERT(TARRAY2_SIZE(committer->dataIterArray) == 0); ASSERT(committer->dataIterMerger == NULL); - ASSERT(committer->sttWriter == NULL); - ASSERT(committer->dataWriter == NULL); + ASSERT(committer->writer == NULL); code = tsdbCommitOpenReader(committer); TSDB_CHECK_CODE(code, lino, _exit); @@ -660,8 +634,7 @@ static int32_t tsdbCloseCommitter(SCommitter2 *committer, int32_t eno) { ASSERT(0); } - ASSERT(committer->dataWriter == NULL); - ASSERT(committer->sttWriter == NULL); + ASSERT(committer->writer == NULL); ASSERT(committer->dataIterMerger == NULL); ASSERT(committer->tombIterMerger == NULL); TARRAY2_DESTROY(committer->dataIterArray, NULL); diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.h b/source/dnode/vnode/src/tsdb/tsdbCommit2.h index 72d7eb48ee..41f72f345b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.h +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.h @@ -15,6 +15,7 @@ #include "tsdbDataFileRW.h" #include "tsdbFS2.h" +#include "tsdbFSetRW.h" #include "tsdbIter.h" #include "tsdbSttFileRW.h" diff --git a/source/dnode/vnode/src/tsdb/tsdbFSetRW.h b/source/dnode/vnode/src/tsdb/tsdbFSetRW.h index 76f734c16f..b5710407cf 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFSetRW.h +++ b/source/dnode/vnode/src/tsdb/tsdbFSetRW.h @@ -41,7 +41,6 @@ typedef struct { bool exist; STFile file; } files[TSDB_FTYPE_MAX]; - STFile sttFile; } SFSetWriterConfig; int32_t tsdbFSetWriterOpen(SFSetWriterConfig *config, SFSetWriter **writer); diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.c b/source/dnode/vnode/src/tsdb/tsdbMerge.c index 358d735b1d..97229714e8 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMerge.c +++ b/source/dnode/vnode/src/tsdb/tsdbMerge.c @@ -19,15 +19,13 @@ typedef struct { STsdb *tsdb; TFileSetArray *fsetArr; - int32_t sttTrigger; - int32_t maxRow; - int32_t minRow; - int32_t szPage; - int8_t cmprAlg; - int64_t compactVersion; - int64_t cid; - SSkmInfo skmTb[1]; - SSkmInfo skmRow[1]; + int32_t sttTrigger; + int32_t maxRow; + int32_t minRow; + int32_t szPage; + int8_t cmprAlg; + int64_t compactVersion; + int64_t cid; // context struct { @@ -37,10 +35,7 @@ typedef struct { bool toData; int32_t level; SSttLvl *lvl; - // STFileObj *fobj; TABLEID tbid[1]; - int32_t blockDataIdx; - SBlockData blockData[2]; } ctx[1]; TFileOpArray fopArr[1]; @@ -53,8 +48,7 @@ typedef struct { TTsdbIterArray tombIterArr[1]; SIterMerger *tombIterMerger; // writer - SSttFileWriter *sttWriter; - SDataFileWriter *dataWriter; + SFSetWriter *writer; } SMerger; static int32_t tsdbMergerOpen(SMerger *merger) { @@ -86,8 +80,7 @@ static int32_t tsdbMergerClose(SMerger *merger) { } taosThreadRwlockUnlock(&merger->tsdb->rwLock); - ASSERT(merger->dataWriter == NULL); - ASSERT(merger->sttWriter == NULL); + ASSERT(merger->writer == NULL); ASSERT(merger->dataIterMerger == NULL); ASSERT(TARRAY2_SIZE(merger->dataIterArr) == 0); ASSERT(TARRAY2_SIZE(merger->sttReaderArr) == 0); @@ -96,11 +89,6 @@ static int32_t tsdbMergerClose(SMerger *merger) { TARRAY2_DESTROY(merger->dataIterArr, NULL); TARRAY2_DESTROY(merger->sttReaderArr, NULL); TARRAY2_DESTROY(merger->fopArr, NULL); - for (int32_t i = 0; i < ARRAY_SIZE(merger->ctx->blockData); i++) { - tBlockDataDestroy(merger->ctx->blockData + i); - } - tDestroyTSchema(merger->skmTb->pTSchema); - tDestroyTSchema(merger->skmRow->pTSchema); _exit: if (code) { @@ -109,6 +97,7 @@ _exit: return code; } +#if 0 static int32_t tsdbMergeToDataTableEnd(SMerger *merger) { if (merger->ctx->blockData[0].nRow + merger->ctx->blockData[1].nRow == 0) return 0; @@ -297,6 +286,7 @@ _exit: } return code; } +#endif static int32_t tsdbMergeFileSetBeginOpenReader(SMerger *merger) { int32_t code = 0; @@ -413,49 +403,36 @@ static int32_t tsdbMergeFileSetBeginOpenWriter(SMerger *merger) { code = TSDB_CODE_FS_NO_VALID_DISK; TSDB_CHECK_CODE(code, lino, _exit); } - - { - // to new level - SSttFileWriterConfig config[1] = {{ - .tsdb = merger->tsdb, - .maxRow = merger->maxRow, - .szPage = merger->szPage, - .cmprAlg = merger->cmprAlg, - .compactVersion = merger->compactVersion, - .did = did, - .fid = merger->ctx->fset->fid, - .cid = merger->cid, - .level = merger->ctx->level, - }}; - code = tsdbSttFileWriterOpen(config, &merger->sttWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } + SFSetWriterConfig config = { + .tsdb = merger->tsdb, + .toSttOnly = true, + .compactVersion = merger->compactVersion, + .minRow = merger->minRow, + .maxRow = merger->maxRow, + .szPage = merger->szPage, + .cmprAlg = merger->cmprAlg, + .fid = merger->ctx->fset->fid, + .cid = merger->cid, + .did = did, + .level = merger->ctx->level, + }; if (merger->ctx->toData) { - SDataFileWriterConfig config[1] = {{ - .tsdb = merger->tsdb, - .cmprAlg = merger->cmprAlg, - .maxRow = merger->maxRow, - .szPage = merger->szPage, - .fid = merger->ctx->fset->fid, - .cid = merger->cid, - .did = did, - .compactVersion = merger->compactVersion, - }}; + config.toSttOnly = false; - for (int32_t i = 0; i < TSDB_FTYPE_MAX; i++) { - if (merger->ctx->fset->farr[i]) { - config->files[i].exist = true; - config->files[i].file = merger->ctx->fset->farr[i]->f[0]; + for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ++ftype) { + if (merger->ctx->fset->farr[ftype]) { + config.files[ftype].exist = true; + config.files[ftype].file = merger->ctx->fset->farr[ftype]->f[0]; } else { - config->files[i].exist = false; + config.files[ftype].exist = false; } } - - code = tsdbDataFileWriterOpen(config, &merger->dataWriter); - TSDB_CHECK_CODE(code, lino, _exit); } + code = tsdbFSetWriterOpen(&config, &merger->writer); + TSDB_CHECK_CODE(code, lino, _exit); + _exit: if (code) { TSDB_ERROR_LOG(vid, lino, code); @@ -470,15 +447,10 @@ static int32_t tsdbMergeFileSetBegin(SMerger *merger) { ASSERT(TARRAY2_SIZE(merger->sttReaderArr) == 0); ASSERT(TARRAY2_SIZE(merger->dataIterArr) == 0); ASSERT(merger->dataIterMerger == NULL); - ASSERT(merger->sttWriter == NULL); - ASSERT(merger->dataWriter == NULL); + ASSERT(merger->writer == NULL); merger->ctx->tbid->suid = 0; merger->ctx->tbid->uid = 0; - merger->ctx->blockDataIdx = 0; - for (int32_t i = 0; i < ARRAY_SIZE(merger->ctx->blockData); ++i) { - tBlockDataReset(merger->ctx->blockData + i); - } // open reader code = tsdbMergeFileSetBeginOpenReader(merger); @@ -500,23 +472,7 @@ _exit: } static int32_t tsdbMergeFileSetEndCloseWriter(SMerger *merger) { - int32_t code = 0; - int32_t lino = 0; - int32_t vid = TD_VID(merger->tsdb->pVnode); - - code = tsdbSttFileWriterClose(&merger->sttWriter, 0, merger->fopArr); - TSDB_CHECK_CODE(code, lino, _exit); - - if (merger->ctx->toData) { - code = tsdbDataFileWriterClose(&merger->dataWriter, 0, merger->fopArr); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - TSDB_ERROR_LOG(vid, lino, code); - } - return code; + return tsdbFSetWriterClose(&merger->writer, 0, merger->fopArr); } static int32_t tsdbMergeFileSetEndCloseIter(SMerger *merger) { @@ -560,12 +516,49 @@ static int32_t tsdbMergeFileSet(SMerger *merger, STFileSet *fset) { code = tsdbMergeFileSetBegin(merger); TSDB_CHECK_CODE(code, lino, _exit); - // do merge - if (merger->ctx->toData) { - code = tsdbMergeToDataLevel(merger); + // data + SMetaInfo info; + SRowInfo *row; + merger->ctx->tbid->suid = 0; + merger->ctx->tbid->uid = 0; + while ((row = tsdbIterMergerGetData(merger->dataIterMerger)) != NULL) { + if (row->uid != merger->ctx->tbid->uid) { + if (metaGetInfo(merger->tsdb->pVnode->pMeta, row->uid, &info, NULL) != 0) { + code = tsdbIterMergerSkipTableData(merger->dataIterMerger, (TABLEID *)row); + TSDB_CHECK_CODE(code, lino, _exit); + continue; + } + + merger->ctx->tbid->uid = row->uid; + merger->ctx->tbid->suid = row->suid; + } + + code = tsdbFSetWriteRow(merger->writer, row); TSDB_CHECK_CODE(code, lino, _exit); - } else { - code = tsdbMergeToUpperLevel(merger); + + code = tsdbIterMergerNext(merger->dataIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // tomb + STombRecord *record; + merger->ctx->tbid->suid = 0; + merger->ctx->tbid->uid = 0; + while ((record = tsdbIterMergerGetTombRecord(merger->tombIterMerger)) != NULL) { + if (record->uid != merger->ctx->tbid->uid) { + merger->ctx->tbid->uid = record->uid; + merger->ctx->tbid->suid = record->suid; + + if (metaGetInfo(merger->tsdb->pVnode->pMeta, record->uid, &info, NULL) != 0) { + code = tsdbIterMergerSkipTableData(merger->tombIterMerger, merger->ctx->tbid); + TSDB_CHECK_CODE(code, lino, _exit); + continue; + } + } + code = tsdbFSetWriteTombRecord(merger->writer, record); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbIterMergerNext(merger->tombIterMerger); TSDB_CHECK_CODE(code, lino, _exit); } diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.h b/source/dnode/vnode/src/tsdb/tsdbMerge.h index e4c7aef614..69d802fd27 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMerge.h +++ b/source/dnode/vnode/src/tsdb/tsdbMerge.h @@ -15,6 +15,7 @@ #include "tsdbDataFileRW.h" #include "tsdbFS2.h" +#include "tsdbFSetRW.h" #include "tsdbIter.h" #include "tsdbSttFileRW.h" #include "tsdbUtil2.h" From 9ce58a2d80548ca03f6df94add197fea9054beee Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 19 Jun 2023 11:32:19 +0800 Subject: [PATCH 19/21] refact more code --- source/dnode/vnode/src/tsdb/tsdbSnapshot.c | 1316 ++++++-------------- 1 file changed, 371 insertions(+), 945 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index f45858ae8d..5269443173 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -16,6 +16,7 @@ #include "tsdb.h" #include "tsdbDataFileRW.h" #include "tsdbFS2.h" +#include "tsdbFSetRW.h" #include "tsdbIter.h" #include "tsdbSttFileRW.h" @@ -216,6 +217,8 @@ static int32_t tsdbSnapReadFileSetBegin(STsdbSnapReader* reader) { int32_t code = 0; int32_t lino = 0; + ASSERT(reader->ctx->fset == NULL); + if (reader->ctx->fsetArrIdx < TARRAY2_SIZE(reader->fsetArr)) { reader->ctx->fset = TARRAY2_GET(reader->fsetArr, reader->ctx->fsetArrIdx++); reader->ctx->isDataDone = false; @@ -387,7 +390,6 @@ int32_t tsdbSnapReaderOpen(STsdb* tsdb, int64_t sver, int64_t ever, int8_t type, int32_t code = 0; int32_t lino = 0; - // alloc reader[0] = (STsdbSnapReader*)taosMemoryCalloc(1, sizeof(*reader[0])); if (reader[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; @@ -510,19 +512,21 @@ struct STsdbSnapWriter { int32_t maxRow; int8_t cmprAlg; int64_t commitID; + int32_t szPage; + int64_t compactVersion; + int64_t now; uint8_t* aBuf[5]; TFileSetArray* fsetArr; TFileOpArray fopArr[1]; struct { - bool fsetWriteBegin; - + bool fsetWriteBegin; int32_t fid; STFileSet* fset; - - bool hasData; - bool hasTomb; + SDiskID did; + bool hasData; + bool hasTomb; // reader SDataFileReader* dataReader; @@ -533,939 +537,14 @@ struct STsdbSnapWriter { SIterMerger* dataIterMerger; TTsdbIterArray tombIterArr[1]; SIterMerger* tombIterMerger; + + // writer + SFSetWriter* fsetWriter; } ctx[1]; - - SDataFileWriter* dataWriter; - SSttFileWriter* sttWriter; - - SBlockData blockData[1]; - STombBlock tombBlock[1]; }; -#if 0 -// SNAP_DATA_TSDB -static int32_t tsdbSnapWriteTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pId) { - int32_t code = 0; - int32_t lino = 0; - - if (pId) { - pWriter->tbid = *pId; - } else { - pWriter->tbid = (TABLEID){INT64_MAX, INT64_MAX}; - } - - if (pWriter->pDIter) { - STsdbDataIter2* pIter = pWriter->pDIter; - - // assert last table data end - ASSERT(pIter->dIter.iRow >= pIter->dIter.bData.nRow); - ASSERT(pIter->dIter.iDataBlk >= pIter->dIter.mDataBlk.nItem); - - for (;;) { - if (pIter->dIter.iBlockIdx >= taosArrayGetSize(pIter->dIter.aBlockIdx)) { - pWriter->pDIter = NULL; - break; - } - - SBlockIdx* pBlockIdx = (SBlockIdx*)taosArrayGet(pIter->dIter.aBlockIdx, pIter->dIter.iBlockIdx); - - int32_t c = tTABLEIDCmprFn(pBlockIdx, &pWriter->tbid); - if (c < 0) { - code = tsdbReadDataBlk(pIter->dIter.pReader, pBlockIdx, &pIter->dIter.mDataBlk); - TSDB_CHECK_CODE(code, lino, _exit); - - SBlockIdx* pNewBlockIdx = taosArrayReserve(pWriter->aBlockIdx, 1); - if (pNewBlockIdx == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - pNewBlockIdx->suid = pBlockIdx->suid; - pNewBlockIdx->uid = pBlockIdx->uid; - - code = tsdbWriteDataBlk(pWriter->pDataFWriter, &pIter->dIter.mDataBlk, pNewBlockIdx); - TSDB_CHECK_CODE(code, lino, _exit); - - pIter->dIter.iBlockIdx++; - } else if (c == 0) { - code = tsdbReadDataBlk(pIter->dIter.pReader, pBlockIdx, &pIter->dIter.mDataBlk); - TSDB_CHECK_CODE(code, lino, _exit); - - pIter->dIter.iDataBlk = 0; - pIter->dIter.iBlockIdx++; - - break; - } else { - pIter->dIter.iDataBlk = pIter->dIter.mDataBlk.nItem; - break; - } - } - } - - if (pId) { - code = tsdbUpdateTableSchema(pWriter->tsdb->pVnode->pMeta, pId->suid, pId->uid, &pWriter->skmTable); - TSDB_CHECK_CODE(code, lino, _exit); - - tMapDataReset(&pWriter->mDataBlk); - - code = tBlockDataInit(&pWriter->bData, pId, pWriter->skmTable.pTSchema, NULL, 0); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (!TABLE_SAME_SCHEMA(pWriter->tbid.suid, pWriter->tbid.uid, pWriter->sData.suid, pWriter->sData.uid)) { - if ((pWriter->sData.nRow > 0)) { - code = tsdbWriteSttBlock(pWriter->pDataFWriter, &pWriter->sData, pWriter->aSttBlk, pWriter->cmprAlg); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pId) { - TABLEID id = {.suid = pWriter->tbid.suid, .uid = pWriter->tbid.suid ? 0 : pWriter->tbid.uid}; - code = tBlockDataInit(&pWriter->sData, &id, pWriter->skmTable.pTSchema, NULL, 0); - TSDB_CHECK_CODE(code, lino, _exit); - } - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->tsdb->pVnode), __func__, - pWriter->tbid.suid, pWriter->tbid.uid); - } - return code; -} - -static int32_t tsdbSnapWriteTableRowImpl(STsdbSnapWriter* pWriter, TSDBROW* pRow) { - int32_t code = 0; - int32_t lino = 0; - - code = tBlockDataAppendRow(&pWriter->bData, pRow, pWriter->skmTable.pTSchema, pWriter->tbid.uid); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->bData.nRow >= pWriter->maxRow) { - code = tsdbWriteDataBlock(pWriter->pDataFWriter, &pWriter->bData, &pWriter->mDataBlk, pWriter->cmprAlg); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteTableRow(STsdbSnapWriter* pWriter, TSDBROW* pRow) { - int32_t code = 0; - int32_t lino = 0; - - TSDBKEY inKey = pRow ? TSDBROW_KEY(pRow) : TSDBKEY_MAX; - - if (pWriter->pDIter == NULL || (pWriter->pDIter->dIter.iRow >= pWriter->pDIter->dIter.bData.nRow && - pWriter->pDIter->dIter.iDataBlk >= pWriter->pDIter->dIter.mDataBlk.nItem)) { - goto _write_row; - } else { - for (;;) { - while (pWriter->pDIter->dIter.iRow < pWriter->pDIter->dIter.bData.nRow) { - TSDBROW row = tsdbRowFromBlockData(&pWriter->pDIter->dIter.bData, pWriter->pDIter->dIter.iRow); - - int32_t c = tsdbKeyCmprFn(&inKey, &TSDBROW_KEY(&row)); - if (c < 0) { - goto _write_row; - } else if (c > 0) { - code = tsdbSnapWriteTableRowImpl(pWriter, &row); - TSDB_CHECK_CODE(code, lino, _exit); - - pWriter->pDIter->dIter.iRow++; - } else { - ASSERT(0); - } - } - - for (;;) { - if (pWriter->pDIter->dIter.iDataBlk >= pWriter->pDIter->dIter.mDataBlk.nItem) goto _write_row; - - // FIXME: Here can be slow, use array instead - SDataBlk dataBlk; - tMapDataGetItemByIdx(&pWriter->pDIter->dIter.mDataBlk, pWriter->pDIter->dIter.iDataBlk, &dataBlk, tGetDataBlk); - - int32_t c = tDataBlkCmprFn(&dataBlk, &(SDataBlk){.minKey = inKey, .maxKey = inKey}); - if (c > 0) { - goto _write_row; - } else if (c < 0) { - if (pWriter->bData.nRow > 0) { - code = tsdbWriteDataBlock(pWriter->pDataFWriter, &pWriter->bData, &pWriter->mDataBlk, pWriter->cmprAlg); - TSDB_CHECK_CODE(code, lino, _exit); - } - - tMapDataPutItem(&pWriter->mDataBlk, &dataBlk, tPutDataBlk); - pWriter->pDIter->dIter.iDataBlk++; - } else { - code = tsdbReadDataBlockEx(pWriter->pDataFReader, &dataBlk, &pWriter->pDIter->dIter.bData); - TSDB_CHECK_CODE(code, lino, _exit); - - pWriter->pDIter->dIter.iRow = 0; - pWriter->pDIter->dIter.iDataBlk++; - break; - } - } - } - } - -_write_row: - if (pRow) { - code = tsdbSnapWriteTableRowImpl(pWriter, pRow); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteTableDataEnd(STsdbSnapWriter* pWriter) { - int32_t code = 0; - int32_t lino = 0; - - // write a NULL row to end current table data write - code = tsdbSnapWriteTableRow(pWriter, NULL); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->bData.nRow > 0) { - if (pWriter->bData.nRow < pWriter->minRow) { - ASSERT(TABLE_SAME_SCHEMA(pWriter->sData.suid, pWriter->sData.uid, pWriter->tbid.suid, pWriter->tbid.uid)); - for (int32_t iRow = 0; iRow < pWriter->bData.nRow; iRow++) { - code = - tBlockDataAppendRow(&pWriter->sData, &tsdbRowFromBlockData(&pWriter->bData, iRow), NULL, pWriter->tbid.uid); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->sData.nRow >= pWriter->maxRow) { - code = tsdbWriteSttBlock(pWriter->pDataFWriter, &pWriter->sData, pWriter->aSttBlk, pWriter->cmprAlg); - TSDB_CHECK_CODE(code, lino, _exit); - } - } - - tBlockDataClear(&pWriter->bData); - } else { - code = tsdbWriteDataBlock(pWriter->pDataFWriter, &pWriter->bData, &pWriter->mDataBlk, pWriter->cmprAlg); - TSDB_CHECK_CODE(code, lino, _exit); - } - } - - if (pWriter->mDataBlk.nItem) { - SBlockIdx* pBlockIdx = taosArrayReserve(pWriter->aBlockIdx, 1); - if (pBlockIdx == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - pBlockIdx->suid = pWriter->tbid.suid; - pBlockIdx->uid = pWriter->tbid.uid; - - code = tsdbWriteDataBlk(pWriter->pDataFWriter, &pWriter->mDataBlk, pBlockIdx); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteFileDataStart(STsdbSnapWriter* pWriter, int32_t fid) { - int32_t code = 0; - int32_t lino = 0; - - ASSERT(pWriter->pDataFWriter == NULL && pWriter->fid < fid); - - STsdb* pTsdb = pWriter->tsdb; - - pWriter->fid = fid; - pWriter->tbid = (TABLEID){0}; - SDFileSet* pSet = taosArraySearch(pWriter->fs.aDFileSet, &(SDFileSet){.fid = fid}, tDFileSetCmprFn, TD_EQ); - - // open reader - pWriter->pDataFReader = NULL; - pWriter->iterList = NULL; - pWriter->pDIter = NULL; - pWriter->pSIter = NULL; - tRBTreeCreate(&pWriter->rbt, tsdbDataIterCmprFn); - if (pSet) { - code = tsdbDataFReaderOpen(&pWriter->pDataFReader, pTsdb, pSet); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbOpenDataFileDataIter(pWriter->pDataFReader, &pWriter->pDIter); - TSDB_CHECK_CODE(code, lino, _exit); - if (pWriter->pDIter) { - pWriter->pDIter->next = pWriter->iterList; - pWriter->iterList = pWriter->pDIter; - } - - for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) { - code = tsdbOpenSttFileDataIter(pWriter->pDataFReader, iStt, &pWriter->pSIter); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->pSIter) { - code = tsdbDataIterNext2(pWriter->pSIter, NULL); - TSDB_CHECK_CODE(code, lino, _exit); - - // add to tree - tRBTreePut(&pWriter->rbt, &pWriter->pSIter->rbtn); - - // add to list - pWriter->pSIter->next = pWriter->iterList; - pWriter->iterList = pWriter->pSIter; - } - } - - pWriter->pSIter = NULL; - } - - // open writer - SDiskID diskId; - if (pSet) { - diskId = pSet->diskId; - } else { - tfsAllocDisk(pTsdb->pVnode->pTfs, 0 /*TODO*/, &diskId); - tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, diskId); - } - SDFileSet wSet = {.diskId = diskId, - .fid = fid, - .pHeadF = &(SHeadFile){.commitID = pWriter->commitID}, - .pDataF = (pSet) ? pSet->pDataF : &(SDataFile){.commitID = pWriter->commitID}, - .pSmaF = (pSet) ? pSet->pSmaF : &(SSmaFile){.commitID = pWriter->commitID}, - .nSttF = 1, - .aSttF = {&(SSttFile){.commitID = pWriter->commitID}}}; - code = tsdbDataFWriterOpen(&pWriter->pDataFWriter, pTsdb, &wSet); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->aBlockIdx) { - taosArrayClear(pWriter->aBlockIdx); - } else if ((pWriter->aBlockIdx = taosArrayInit(0, sizeof(SBlockIdx))) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - tMapDataReset(&pWriter->mDataBlk); - - if (pWriter->aSttBlk) { - taosArrayClear(pWriter->aSttBlk); - } else if ((pWriter->aSttBlk = taosArrayInit(0, sizeof(SSttBlk))) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - tBlockDataReset(&pWriter->bData); - tBlockDataReset(&pWriter->sData); - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s, fid:%d", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code), - fid); - } else { - tsdbDebug("vgId:%d %s done, fid:%d", TD_VID(pTsdb->pVnode), __func__, fid); - } - return code; -} - -static int32_t tsdbSnapWriteTableData(STsdbSnapWriter* pWriter, SRowInfo* pRowInfo) { - int32_t code = 0; - int32_t lino = 0; - - // switch to new table if need - if (pRowInfo == NULL || pRowInfo->uid != pWriter->tbid.uid) { - if (pWriter->tbid.uid) { - code = tsdbSnapWriteTableDataEnd(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - code = tsdbSnapWriteTableDataStart(pWriter, (TABLEID*)pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pRowInfo == NULL) goto _exit; - - code = tsdbSnapWriteTableRow(pWriter, &pRowInfo->row); - TSDB_CHECK_CODE(code, lino, _exit); - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteNextRow(STsdbSnapWriter* pWriter, SRowInfo** ppRowInfo) { - int32_t code = 0; - int32_t lino = 0; - - if (pWriter->pSIter) { - code = tsdbDataIterNext2(pWriter->pSIter, NULL); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->pSIter->rowInfo.suid == 0 && pWriter->pSIter->rowInfo.uid == 0) { - pWriter->pSIter = NULL; - } else { - SRBTreeNode* pNode = tRBTreeMin(&pWriter->rbt); - if (pNode) { - int32_t c = tsdbDataIterCmprFn(&pWriter->pSIter->rbtn, pNode); - if (c > 0) { - tRBTreePut(&pWriter->rbt, &pWriter->pSIter->rbtn); - pWriter->pSIter = NULL; - } else if (c == 0) { - ASSERT(0); - } - } - } - } - - if (pWriter->pSIter == NULL) { - SRBTreeNode* pNode = tRBTreeMin(&pWriter->rbt); - if (pNode) { - tRBTreeDrop(&pWriter->rbt, pNode); - pWriter->pSIter = TSDB_RBTN_TO_DATA_ITER(pNode); - } - } - - if (ppRowInfo) { - if (pWriter->pSIter) { - *ppRowInfo = &pWriter->pSIter->rowInfo; - } else { - *ppRowInfo = NULL; - } - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteGetRow(STsdbSnapWriter* pWriter, SRowInfo** ppRowInfo) { - int32_t code = 0; - int32_t lino = 0; - - if (pWriter->pSIter) { - *ppRowInfo = &pWriter->pSIter->rowInfo; - goto _exit; - } - - code = tsdbSnapWriteNextRow(pWriter, ppRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteFileDataEnd(STsdbSnapWriter* pWriter) { - int32_t code = 0; - int32_t lino = 0; - - ASSERT(pWriter->pDataFWriter); - - // consume remain data and end with a NULL table row - SRowInfo* pRowInfo; - code = tsdbSnapWriteGetRow(pWriter, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - for (;;) { - code = tsdbSnapWriteTableData(pWriter, pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pRowInfo == NULL) break; - - code = tsdbSnapWriteNextRow(pWriter, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // do file-level updates - code = tsdbWriteSttBlk(pWriter->pDataFWriter, pWriter->aSttBlk); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbWriteBlockIdx(pWriter->pDataFWriter, pWriter->aBlockIdx); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbUpdateDFileSetHeader(pWriter->pDataFWriter); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbFSUpsertFSet(&pWriter->fs, &pWriter->pDataFWriter->wSet); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbDataFWriterClose(&pWriter->pDataFWriter, 1); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->pDataFReader) { - code = tsdbDataFReaderClose(&pWriter->pDataFReader); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // clear sources - while (pWriter->iterList) { - STsdbDataIter2* pIter = pWriter->iterList; - pWriter->iterList = pIter->next; - tsdbCloseDataIter2(pIter); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed since %s", TD_VID(pWriter->tsdb->pVnode), __func__, tstrerror(code)); - } else { - tsdbDebug("vgId:%d %s is done", TD_VID(pWriter->tsdb->pVnode), __func__); - } - return code; -} - -static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* pWriter, SSnapDataHdr* pHdr) { - int32_t code = 0; - int32_t lino = 0; - - code = tDecmprBlockData(pHdr->data, pHdr->size, &pWriter->inData, pWriter->aBuf); - TSDB_CHECK_CODE(code, lino, _exit); - - ASSERT(pWriter->inData.nRow > 0); - - // switch to new data file if need - int32_t fid = tsdbKeyFid(pWriter->inData.aTSKEY[0], pWriter->minutes, pWriter->precision); - if (pWriter->fid != fid) { - if (pWriter->pDataFWriter) { - code = tsdbSnapWriteFileDataEnd(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - code = tsdbSnapWriteFileDataStart(pWriter, fid); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // loop write each row - SRowInfo* pRowInfo; - code = tsdbSnapWriteGetRow(pWriter, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - for (int32_t iRow = 0; iRow < pWriter->inData.nRow; ++iRow) { - SRowInfo rInfo = {.suid = pWriter->inData.suid, - .uid = pWriter->inData.uid ? pWriter->inData.uid : pWriter->inData.aUid[iRow], - .row = tsdbRowFromBlockData(&pWriter->inData, iRow)}; - - for (;;) { - if (pRowInfo == NULL) { - code = tsdbSnapWriteTableData(pWriter, &rInfo); - TSDB_CHECK_CODE(code, lino, _exit); - break; - } else { - int32_t c = tRowInfoCmprFn(&rInfo, pRowInfo); - if (c < 0) { - code = tsdbSnapWriteTableData(pWriter, &rInfo); - TSDB_CHECK_CODE(code, lino, _exit); - break; - } else if (c > 0) { - code = tsdbSnapWriteTableData(pWriter, pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbSnapWriteNextRow(pWriter, &pRowInfo); - TSDB_CHECK_CODE(code, lino, _exit); - } else { - ASSERT(0); - } - } - } - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbDebug("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64 " nRow:%d", TD_VID(pWriter->tsdb->pVnode), __func__, - pWriter->inData.suid, pWriter->inData.uid, pWriter->inData.nRow); - } - return code; -} - -// SNAP_DATA_DEL -static int32_t tsdbSnapWriteDelTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pId) { - int32_t code = 0; - int32_t lino = 0; - - if (pId) { - pWriter->tbid = *pId; - } else { - pWriter->tbid = (TABLEID){.suid = INT64_MAX, .uid = INT64_MAX}; - } - - taosArrayClear(pWriter->aDelData); - - if (pWriter->pTIter) { - while (pWriter->pTIter->tIter.iDelIdx < taosArrayGetSize(pWriter->pTIter->tIter.aDelIdx)) { - SDelIdx* pDelIdx = taosArrayGet(pWriter->pTIter->tIter.aDelIdx, pWriter->pTIter->tIter.iDelIdx); - - int32_t c = tTABLEIDCmprFn(pDelIdx, &pWriter->tbid); - if (c < 0) { - code = tsdbReadDelDatav1(pWriter->pDelFReader, pDelIdx, pWriter->pTIter->tIter.aDelData, INT64_MAX); - TSDB_CHECK_CODE(code, lino, _exit); - - SDelIdx* pDelIdxNew = taosArrayReserve(pWriter->aDelIdx, 1); - if (pDelIdxNew == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - pDelIdxNew->suid = pDelIdx->suid; - pDelIdxNew->uid = pDelIdx->uid; - - code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->pTIter->tIter.aDelData, pDelIdxNew); - TSDB_CHECK_CODE(code, lino, _exit); - - pWriter->pTIter->tIter.iDelIdx++; - } else if (c == 0) { - code = tsdbReadDelDatav1(pWriter->pDelFReader, pDelIdx, pWriter->aDelData, INT64_MAX); - TSDB_CHECK_CODE(code, lino, _exit); - - pWriter->pTIter->tIter.iDelIdx++; - break; - } else { - break; - } - } - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbTrace("vgId:%d %s done, suid:%" PRId64 " uid:%" PRId64, TD_VID(pWriter->tsdb->pVnode), __func__, - pWriter->tbid.suid, pWriter->tbid.uid); - } - return code; -} - -static int32_t tsdbSnapWriteDelTableDataEnd(STsdbSnapWriter* pWriter) { - int32_t code = 0; - int32_t lino = 0; - - if (taosArrayGetSize(pWriter->aDelData) > 0) { - SDelIdx* pDelIdx = taosArrayReserve(pWriter->aDelIdx, 1); - if (pDelIdx == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - - pDelIdx->suid = pWriter->tbid.suid; - pDelIdx->uid = pWriter->tbid.uid; - - code = tsdbWriteDelData(pWriter->pDelFWriter, pWriter->aDelData, pDelIdx); - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbTrace("vgId:%d %s done", TD_VID(pWriter->tsdb->pVnode), __func__); - } - return code; -} - -static int32_t tsdbSnapWriteDelTableData(STsdbSnapWriter* pWriter, TABLEID* pId, uint8_t* pData, int64_t size) { - int32_t code = 0; - int32_t lino = 0; - - if (pId == NULL || pId->uid != pWriter->tbid.uid) { - if (pWriter->tbid.uid) { - code = tsdbSnapWriteDelTableDataEnd(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - code = tsdbSnapWriteDelTableDataStart(pWriter, pId); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pId == NULL) goto _exit; - - int64_t n = 0; - while (n < size) { - SDelData delData; - n += tGetDelData(pData + n, &delData); - - if (taosArrayPush(pWriter->aDelData, &delData) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - } - ASSERT(n == size); - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pWriter->tsdb->pVnode), __func__, lino, tstrerror(code)); - } - return code; -} - -static int32_t tsdbSnapWriteDelDataStart(STsdbSnapWriter* pWriter) { - int32_t code = 0; - int32_t lino = 0; - - STsdb* pTsdb = pWriter->tsdb; - SDelFile* pDelFile = pWriter->fs.pDelFile; - - pWriter->tbid = (TABLEID){0}; - - // reader - if (pDelFile) { - code = tsdbDelFReaderOpen(&pWriter->pDelFReader, pDelFile, pTsdb); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbOpenTombFileDataIter(pWriter->pDelFReader, &pWriter->pTIter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // writer - code = tsdbDelFWriterOpen(&pWriter->pDelFWriter, &(SDelFile){.commitID = pWriter->commitID}, pTsdb); - TSDB_CHECK_CODE(code, lino, _exit); - - if ((pWriter->aDelIdx = taosArrayInit(0, sizeof(SDelIdx))) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - if ((pWriter->aDelData = taosArrayInit(0, sizeof(SDelData))) == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbDebug("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); - } - return code; -} - -static int32_t tsdbSnapWriteDelDataEnd(STsdbSnapWriter* pWriter) { - int32_t code = 0; - int32_t lino = 0; - - STsdb* pTsdb = pWriter->tsdb; - - // end remaining table with NULL data - code = tsdbSnapWriteDelTableData(pWriter, NULL, NULL, 0); - TSDB_CHECK_CODE(code, lino, _exit); - - // update file-level info - code = tsdbWriteDelIdx(pWriter->pDelFWriter, pWriter->aDelIdx); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbUpdateDelFileHdr(pWriter->pDelFWriter); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbFSUpsertDelFile(&pWriter->fs, &pWriter->pDelFWriter->fDel); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tsdbDelFWriterClose(&pWriter->pDelFWriter, 1); - TSDB_CHECK_CODE(code, lino, _exit); - - if (pWriter->pDelFReader) { - code = tsdbDelFReaderClose(&pWriter->pDelFReader); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pWriter->pTIter) { - tsdbCloseDataIter2(pWriter->pTIter); - pWriter->pTIter = NULL; - } - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); - } - return code; -} - -static int32_t tsdbSnapWriteDelData(STsdbSnapWriter* pWriter, SSnapDataHdr* pHdr) { - int32_t code = 0; - int32_t lino = 0; - - STsdb* pTsdb = pWriter->tsdb; - - // start to write del data if need - if (pWriter->pDelFWriter == NULL) { - code = tsdbSnapWriteDelDataStart(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // do write del data - code = tsdbSnapWriteDelTableData(pWriter, (TABLEID*)pHdr->data, pHdr->data + sizeof(TABLEID), - pHdr->size - sizeof(TABLEID)); - TSDB_CHECK_CODE(code, lino, _exit); - -_exit: - if (code) { - tsdbError("vgId:%d %s failed since %s", TD_VID(pTsdb->pVnode), __func__, tstrerror(code)); - } else { - tsdbTrace("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); - } - return code; -} -#endif - // APIs -int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWriter** ppWriter) { - int32_t code = 0; - int32_t lino = 0; - -#if 0 - // alloc - STsdbSnapWriter* pWriter = (STsdbSnapWriter*)taosMemoryCalloc(1, sizeof(*pWriter)); - if (pWriter == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - TSDB_CHECK_CODE(code, lino, _exit); - } - pWriter->tsdb = pTsdb; - pWriter->sver = sver; - pWriter->ever = ever; - pWriter->minutes = pTsdb->keepCfg.days; - pWriter->precision = pTsdb->keepCfg.precision; - pWriter->minRow = pTsdb->pVnode->config.tsdbCfg.minRows; - pWriter->maxRow = pTsdb->pVnode->config.tsdbCfg.maxRows; - pWriter->cmprAlg = pTsdb->pVnode->config.tsdbCfg.compression; - pWriter->commitID = pTsdb->pVnode->state.commitID; - - code = tsdbFSCopy(pTsdb, &pWriter->fs); - TSDB_CHECK_CODE(code, lino, _exit); - - // SNAP_DATA_TSDB - code = tBlockDataCreate(&pWriter->inData); - TSDB_CHECK_CODE(code, lino, _exit); - - pWriter->fid = INT32_MIN; - - code = tBlockDataCreate(&pWriter->bData); - TSDB_CHECK_CODE(code, lino, _exit); - - code = tBlockDataCreate(&pWriter->sData); - TSDB_CHECK_CODE(code, lino, _exit); - - // SNAP_DATA_DEL -#endif - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - // if (pWriter) { - // tBlockDataDestroy(&pWriter->sData); - // tBlockDataDestroy(&pWriter->bData); - // tBlockDataDestroy(&pWriter->inData); - // tsdbFSDestroy(&pWriter->fs); - // taosMemoryFree(pWriter); - // pWriter = NULL; - // } - } else { - tsdbInfo("vgId:%d %s done, sver:%" PRId64 " ever:%" PRId64, TD_VID(pTsdb->pVnode), __func__, sver, ever); - } - // *ppWriter = pWriter; - return code; -} - -int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* writer) { - int32_t code = 0; - int32_t lino = 0; - -#if 0 - if (pWriter->pDataFWriter) { - code = tsdbSnapWriteFileDataEnd(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - if (pWriter->pDelFWriter) { - code = tsdbSnapWriteDelDataEnd(pWriter); - TSDB_CHECK_CODE(code, lino, _exit); - } - - code = tsdbFSPrepareCommit(pWriter->tsdb, &pWriter->fs); - TSDB_CHECK_CODE(code, lino, _exit); -#endif - -_exit: - if (code) { - tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(writer->tsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - tsdbDebug("vgId:%d %s done", TD_VID(writer->tsdb->pVnode), __func__); - } - return code; -} - -int32_t tsdbSnapWriterClose(STsdbSnapWriter** writer, int8_t rollback) { - int32_t code = 0; - int32_t lino = 0; - -#if 0 - STsdbSnapWriter* pWriter = *writer; - STsdb* pTsdb = pWriter->tsdb; - - if (rollback) { - tsdbRollbackCommit(pWriter->tsdb); - } else { - // lock - taosThreadRwlockWrlock(&pTsdb->rwLock); - - code = tsdbFSCommit(pWriter->tsdb); - if (code) { - taosThreadRwlockUnlock(&pTsdb->rwLock); - TSDB_CHECK_CODE(code, lino, _exit); - } - - // unlock - taosThreadRwlockUnlock(&pTsdb->rwLock); - } - - // SNAP_DATA_DEL - taosArrayDestroy(pWriter->aDelData); - taosArrayDestroy(pWriter->aDelIdx); - - // SNAP_DATA_TSDB - tBlockDataDestroy(&pWriter->sData); - tBlockDataDestroy(&pWriter->bData); - taosArrayDestroy(pWriter->aSttBlk); - tMapDataClear(&pWriter->mDataBlk); - taosArrayDestroy(pWriter->aBlockIdx); - tDestroyTSchema(pWriter->skmTable.pTSchema); - tBlockDataDestroy(&pWriter->inData); - - for (int32_t iBuf = 0; iBuf < sizeof(pWriter->aBuf) / sizeof(uint8_t*); iBuf++) { - tFree(pWriter->aBuf[iBuf]); - } - tsdbFSDestroy(&pWriter->fs); - taosMemoryFree(pWriter); - *writer = NULL; -#endif - -_exit: - if (code) { - // tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); - } else { - // tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); - } - return code; -} - -static int32_t tsdbSnapWriteDoWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInfo* row) { - int32_t code = 0; - int32_t lino = 0; - - // TODO - -_exit: - if (code) { - TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); - } - return code; -} - -static int32_t tsdbSnapWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInfo* row) { +static int32_t tsdbSnapWriteTimeSeriesRow(STsdbSnapWriter* writer, SRowInfo* row) { int32_t code = 0; int32_t lino = 0; @@ -1478,7 +557,7 @@ static int32_t tsdbSnapWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInf int32_t c = tRowInfoCmprFn(row1, row); if (c <= 0) { - code = tsdbSnapWriteDoWriteTimeSeriesRow(writer, row1); + code = tsdbFSetWriteRow(writer->ctx->fsetWriter, row1); TSDB_CHECK_CODE(code, lino, _exit); code = tsdbIterMergerNext(writer->ctx->dataIterMerger); @@ -1493,7 +572,7 @@ static int32_t tsdbSnapWriteTimeSeriesRow(STsdbSnapWriter* writer, const SRowInf goto _exit; } - code = tsdbSnapWriteDoWriteTimeSeriesRow(writer, row); + code = tsdbFSetWriteRow(writer->ctx->fsetWriter, row); TSDB_CHECK_CODE(code, lino, _exit); _exit: @@ -1503,11 +582,209 @@ _exit: return code; } +static int32_t tsdbSnapWriteFileSetOpenReader(STsdbSnapWriter* writer) { + int32_t code = 0; + int32_t lino = 0; + + ASSERT(writer->ctx->dataReader == NULL); + ASSERT(TARRAY2_SIZE(writer->ctx->sttReaderArr) == 0); + + if (writer->ctx->fset) { + // open data reader + SDataFileReaderConfig dataFileReaderConfig = { + .tsdb = writer->tsdb, + .bufArr = writer->aBuf, + .szPage = writer->szPage, + }; + + for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX; ++ftype) { + if (writer->ctx->fset->farr[ftype] == NULL) { + continue; + } + + dataFileReaderConfig.files[ftype].exist = true; + dataFileReaderConfig.files[ftype].file = writer->ctx->fset->farr[ftype]->f[0]; + } + + code = tsdbDataFileReaderOpen(NULL, &dataFileReaderConfig, &writer->ctx->dataReader); + TSDB_CHECK_CODE(code, lino, _exit); + + // open stt reader array + SSttLvl* lvl; + TARRAY2_FOREACH(writer->ctx->fset->lvlArr, lvl) { + STFileObj* fobj; + TARRAY2_FOREACH(lvl->fobjArr, fobj) { + SSttFileReader* reader; + SSttFileReaderConfig sttFileReaderConfig = { + .tsdb = writer->tsdb, + .szPage = writer->szPage, + .bufArr = writer->aBuf, + .file = fobj->f[0], + }; + + code = tsdbSttFileReaderOpen(fobj->fname, &sttFileReaderConfig, &reader); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(writer->ctx->sttReaderArr, reader); + TSDB_CHECK_CODE(code, lino, _exit); + } + } + } + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteFileSetCloseReader(STsdbSnapWriter* writer) { + TARRAY2_CLEAR(writer->ctx->sttReaderArr, tsdbSttFileReaderClose); + tsdbDataFileReaderClose(&writer->ctx->dataReader); + return 0; +} + +static int32_t tsdbSnapWriteFileSetOpenIter(STsdbSnapWriter* writer) { + int32_t code = 0; + int32_t lino = 0; + + // data ieter + if (writer->ctx->dataReader) { + STsdbIter* iter; + STsdbIterConfig config = {0}; + + // data + config.type = TSDB_ITER_TYPE_DATA; + config.dataReader = writer->ctx->dataReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(writer->ctx->dataIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + + // tome + config.type = TSDB_ITER_TYPE_DATA_TOMB; + config.dataReader = writer->ctx->dataReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(writer->ctx->tombIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // stt iter + SSttFileReader* sttFileReader; + TARRAY2_FOREACH(writer->ctx->sttReaderArr, sttFileReader) { + STsdbIter* iter; + STsdbIterConfig config = {0}; + + // data + config.type = TSDB_ITER_TYPE_STT; + config.sttReader = sttFileReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(writer->ctx->dataIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + + // tomb + config.type = TSDB_ITER_TYPE_STT_TOMB; + config.sttReader = sttFileReader; + + code = tsdbIterOpen(&config, &iter); + TSDB_CHECK_CODE(code, lino, _exit); + + code = TARRAY2_APPEND(writer->ctx->tombIterArr, iter); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // open merger + code = tsdbIterMergerOpen(writer->ctx->dataIterArr, &writer->ctx->dataIterMerger, false); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbIterMergerOpen(writer->ctx->tombIterArr, &writer->ctx->dataIterMerger, true); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteFileSetCloseIter(STsdbSnapWriter* writer) { + tsdbIterMergerClose(&writer->ctx->dataIterMerger); + tsdbIterMergerClose(&writer->ctx->tombIterMerger); + TARRAY2_CLEAR(writer->ctx->dataIterArr, tsdbIterClose); + TARRAY2_CLEAR(writer->ctx->tombIterArr, tsdbIterClose); + return 0; +} + +static int32_t tsdbSnapWriteFileSetOpenWriter(STsdbSnapWriter* writer) { + int32_t code = 0; + int32_t lino = 0; + + SFSetWriterConfig config = { + .tsdb = writer->tsdb, + .toSttOnly = false, + .compactVersion = writer->compactVersion, + .minRow = writer->minRow, + .maxRow = writer->maxRow, + .szPage = writer->szPage, + .cmprAlg = writer->cmprAlg, + .fid = writer->ctx->fid, + .cid = writer->commitID, + .did = writer->ctx->did, + .level = 0, + }; + + code = tsdbFSetWriterOpen(&config, &writer->ctx->fsetWriter); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbSnapWriteFileSetCloseWriter(STsdbSnapWriter* writer) { + return tsdbFSetWriterClose(&writer->ctx->fsetWriter, 0, writer->fopArr); +} + static int32_t tsdbSnapWriteFileSetBegin(STsdbSnapWriter* writer, int32_t fid) { int32_t code = 0; int32_t lino = 0; - // TODO + ASSERT(writer->ctx->fsetWriteBegin == false); + + STFileSet* fset = &(STFileSet){.fid = fid}; + + writer->ctx->fid = fid; + writer->ctx->fset = TARRAY2_SEARCH_EX(writer->fsetArr, &fset, tsdbTFileSetCmprFn, TD_EQ); + + int32_t level = tsdbFidLevel(fid, &writer->tsdb->keepCfg, writer->now); + if (tfsAllocDisk(writer->tsdb->pVnode->pTfs, level, &writer->ctx->did)) { + code = TSDB_CODE_NO_AVAIL_DISK; + TSDB_CHECK_CODE(code, lino, _exit); + } + + writer->ctx->hasData = true; + writer->ctx->hasTomb = true; + + code = tsdbSnapWriteFileSetOpenReader(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbSnapWriteFileSetOpenIter(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbSnapWriteFileSetOpenWriter(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + writer->ctx->fsetWriteBegin = true; _exit: if (code) { @@ -1520,7 +797,29 @@ static int32_t tsdbSnapWriteTombRecord(STsdbSnapWriter* writer, const STombRecor int32_t code = 0; int32_t lino = 0; - // TODO + while (writer->ctx->hasTomb) { + STombRecord* record1 = tsdbIterMergerGetTombRecord(writer->ctx->tombIterMerger); + if (record1 == NULL) { + writer->ctx->hasTomb = false; + break; + } + + int32_t c = tTombRecordCompare(record1, record); + if (c <= 0) { + code = tsdbFSetWriteTombRecord(writer->ctx->fsetWriter, record1); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + break; + } + } + + if (record->suid == INT64_MAX) { + ASSERT(writer->ctx->hasTomb == false); + goto _exit; + } + + code = tsdbFSetWriteTombRecord(writer->ctx->fsetWriter, record); + TSDB_CHECK_CODE(code, lino, _exit); _exit: if (code) { @@ -1535,7 +834,6 @@ static int32_t tsdbSnapWriteFileSetEnd(STsdbSnapWriter* writer) { int32_t code = 0; int32_t lino = 0; - // TODO SRowInfo row = { .suid = INT64_MAX, .uid = INT64_MAX, @@ -1553,12 +851,17 @@ static int32_t tsdbSnapWriteFileSetEnd(STsdbSnapWriter* writer) { TSDB_CHECK_CODE(code, lino, _exit); // close write - code = tsdbSttFileWriterClose(&writer->sttWriter, 0, writer->fopArr); + code = tsdbSnapWriteFileSetCloseWriter(writer); TSDB_CHECK_CODE(code, lino, _exit); - code = tsdbDataFileWriterClose(&writer->dataWriter, 0, writer->fopArr); + code = tsdbSnapWriteFileSetCloseIter(writer); TSDB_CHECK_CODE(code, lino, _exit); + code = tsdbSnapWriteFileSetCloseReader(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + writer->ctx->fsetWriteBegin = false; + _exit: if (code) { TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); @@ -1576,7 +879,7 @@ static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* writer, SSnapDataHdr TSDB_CHECK_CODE(code, lino, _exit); int32_t fid = tsdbKeyFid(blockData->aTSKEY[0], writer->minutes, writer->precision); - if (fid != writer->ctx->fid) { + if (!writer->ctx->fsetWriteBegin || fid != writer->ctx->fid) { code = tsdbSnapWriteFileSetEnd(writer); TSDB_CHECK_CODE(code, lino, _exit); @@ -1612,6 +915,8 @@ static int32_t tsdbSnapWriteDecmprTombBlock(SSnapDataHdr* hdr, STombBlock* tombB // TODO + ASSERT(0); + _exit: return code; } @@ -1620,13 +925,35 @@ static int32_t tsdbSnapWriteTombData(STsdbSnapWriter* writer, SSnapDataHdr* hdr) int32_t code = 0; int32_t lino = 0; - STombBlock tombBlock[1] = {0}; + STombRecord record; + STombBlock tombBlock[1] = {0}; code = tsdbSnapWriteDecmprTombBlock(hdr, tombBlock); TSDB_CHECK_CODE(code, lino, _exit); + tTombBlockGet(tombBlock, 0, &record); + int32_t fid = tsdbKeyFid(record.skey, writer->minutes, writer->precision); + if (!writer->ctx->fsetWriteBegin || fid != writer->ctx->fid) { + code = tsdbSnapWriteFileSetEnd(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbSnapWriteFileSetBegin(writer, fid); + TSDB_CHECK_CODE(code, lino, _exit); + } + + if (writer->ctx->hasData) { + SRowInfo row = { + .suid = INT64_MAX, + .uid = INT64_MAX, + }; + + code = tsdbSnapWriteTimeSeriesRow(writer, &row); + TSDB_CHECK_CODE(code, lino, _exit); + } + + ASSERT(writer->ctx->hasData == false); + for (int32_t i = 0; i < TOMB_BLOCK_SIZE(tombBlock); ++i) { - STombRecord record; tTombBlockGet(tombBlock, i, &record); code = tsdbSnapWriteTombRecord(writer, &record); @@ -1642,6 +969,105 @@ _exit: return code; } +int32_t tsdbSnapWriterOpen(STsdb* pTsdb, int64_t sver, int64_t ever, STsdbSnapWriter** writer) { + int32_t code = 0; + int32_t lino = 0; + + writer[0] = taosMemoryCalloc(1, sizeof(*writer[0])); + if (writer[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; + + writer[0]->tsdb = pTsdb; + writer[0]->sver = sver; + writer[0]->ever = ever; + writer[0]->minutes = pTsdb->keepCfg.days; + writer[0]->precision = pTsdb->keepCfg.precision; + writer[0]->minRow = pTsdb->pVnode->config.tsdbCfg.minRows; + writer[0]->maxRow = pTsdb->pVnode->config.tsdbCfg.maxRows; + writer[0]->commitID = tsdbFSAllocEid(pTsdb->pFS); + writer[0]->szPage = pTsdb->pVnode->config.tsdbPageSize; + writer[0]->compactVersion = INT64_MAX; + writer[0]->now = taosGetTimestampMs(); + + code = tsdbFSCreateCopySnapshot(pTsdb->pFS, &writer[0]->fsetArr); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code)); + } else { + tsdbInfo("vgId:%d %s done, sver:%" PRId64 " ever:%" PRId64, TD_VID(pTsdb->pVnode), __func__, sver, ever); + } + return code; +} + +int32_t tsdbSnapWriterPrepareClose(STsdbSnapWriter* writer) { + int32_t code = 0; + int32_t lino = 0; + + code = tsdbSnapWriteFileSetEnd(writer); + TSDB_CHECK_CODE(code, lino, _exit); + + code = tsdbFSEditBegin(writer->tsdb->pFS, writer->fopArr, TSDB_FEDIT_COMMIT); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(writer->tsdb->pVnode), lino, code); + } else { + tsdbDebug("vgId:%d %s done", TD_VID(writer->tsdb->pVnode), __func__); + } + return code; +} + +int32_t tsdbSnapWriterClose(STsdbSnapWriter** writer, int8_t rollback) { + if (writer[0] == NULL) return 0; + + int32_t code = 0; + int32_t lino = 0; + + STsdb* tsdb = writer[0]->tsdb; + + if (rollback) { + code = tsdbFSEditAbort(writer[0]->tsdb->pFS); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + taosThreadRwlockWrlock(&writer[0]->tsdb->rwLock); + + code = tsdbFSEditCommit(writer[0]->tsdb->pFS); + if (code) { + taosThreadRwlockUnlock(&writer[0]->tsdb->rwLock); + TSDB_CHECK_CODE(code, lino, _exit); + } + + taosThreadRwlockUnlock(&writer[0]->tsdb->rwLock); + } + + tsdbIterMergerClose(&writer[0]->ctx->tombIterMerger); + tsdbIterMergerClose(&writer[0]->ctx->dataIterMerger); + TARRAY2_DESTROY(writer[0]->ctx->tombIterArr, tsdbIterClose); + TARRAY2_DESTROY(writer[0]->ctx->dataIterArr, tsdbIterClose); + TARRAY2_DESTROY(writer[0]->ctx->sttReaderArr, tsdbSttFileReaderClose); + tsdbDataFileReaderClose(&writer[0]->ctx->dataReader); + + TARRAY2_DESTROY(writer[0]->fopArr, NULL); + tsdbFSDestroyCopySnapshot(&writer[0]->fsetArr); + + for (int32_t i = 0; i < ARRAY_SIZE(writer[0]->aBuf); ++i) { + tFree(writer[0]->aBuf[i]); + } + + taosMemoryFree(writer[0]); + writer[0] = NULL; + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code); + } else { + tsdbInfo("vgId:%d %s done", TD_VID(tsdb->pVnode), __func__); + } + return code; +} + int32_t tsdbSnapWrite(STsdbSnapWriter* writer, SSnapDataHdr* hdr) { int32_t code = 0; int32_t lino = 0; From de60e688f6a9e49defdbe257a7955ce9508ec439 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 19 Jun 2023 12:52:09 +0800 Subject: [PATCH 20/21] more fix --- source/dnode/vnode/src/tsdb/tsdbSnapshot.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index 5269443173..678a1f502e 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -875,7 +875,7 @@ static int32_t tsdbSnapWriteTimeSeriesData(STsdbSnapWriter* writer, SSnapDataHdr SBlockData blockData[1] = {0}; - code = tDecmprBlockData(hdr->data, hdr->size, blockData, writer->aBuf); + code = tDecmprBlockData(hdr->data, hdr->size - sizeof(*hdr), blockData, writer->aBuf); TSDB_CHECK_CODE(code, lino, _exit); int32_t fid = tsdbKeyFid(blockData->aTSKEY[0], writer->minutes, writer->precision); @@ -913,9 +913,16 @@ static int32_t tsdbSnapWriteDecmprTombBlock(SSnapDataHdr* hdr, STombBlock* tombB int32_t code = 0; int32_t lino = 0; - // TODO + int64_t size = hdr->size - sizeof(*hdr); + ASSERT(size % TOMB_RECORD_ELEM_NUM == 0); + size = size / TOMB_RECORD_ELEM_NUM; + ASSERT(size % sizeof(int64_t) == 0); - ASSERT(0); + int64_t* data = (int64_t*)hdr->data; + for (int32_t i = 0; i < TOMB_RECORD_ELEM_NUM; ++i) { + code = TARRAY2_APPEND_BATCH(&tombBlock->dataArr[i], hdr->data + i * size, size / sizeof(int64_t)); + TSDB_CHECK_CODE(code, lino, _exit); + } _exit: return code; From 3074ab6541636adef02b6e4ee66d8d0383866cc5 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 19 Jun 2023 14:12:48 +0800 Subject: [PATCH 21/21] more code --- source/dnode/vnode/src/tsdb/tsdbRetention.c | 237 +++++++++++++++++++- 1 file changed, 236 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 7c7e1bd0f7..a6b72e38bd 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -14,6 +14,7 @@ */ #include "tsdb.h" +#include "tsdbFS2.h" static bool tsdbShouldDoRetentionImpl(STsdb *pTsdb, int64_t now) { for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) { @@ -111,4 +112,238 @@ int32_t tsdbCommitRetention(STsdb *pTsdb) { taosThreadRwlockUnlock(&pTsdb->rwLock); tsdbInfo("vgId:%d %s done", TD_VID(pTsdb->pVnode), __func__); return 0; -} \ No newline at end of file +} + +// new ============== +typedef struct { + STsdb *tsdb; + int32_t szPage; + int64_t now; + int64_t cid; + + TFileSetArray *fsetArr; + TFileOpArray *fopArr; + + struct { + int32_t fsetArrIdx; + STFileSet *fset; + } ctx[1]; +} SRTXer; + +static int32_t tsdbDoRemoveFileObject(SRTXer *rtxer, const STFileObj *fobj) { + STFileOp op = { + .optype = TSDB_FOP_REMOVE, + .fid = fobj->f->fid, + .of = fobj->f[0], + }; + + return TARRAY2_APPEND(rtxer->fopArr, op); +} + +static int32_t tsdbDoCopyFile(SRTXer *rtxer, const STFileObj *from, const STFile *to) { + int32_t code = 0; + int32_t lino = 0; + + char fname[TSDB_FILENAME_LEN]; + TdFilePtr fdFrom = NULL; + TdFilePtr fdTo = NULL; + + tsdbTFileName(rtxer->tsdb, to, fname); + + fdFrom = taosOpenFile(from->fname, TD_FILE_READ); + if (fdFrom == NULL) code = terrno; + TSDB_CHECK_CODE(code, lino, _exit); + + fdTo = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC); + if (fdTo == NULL) code = terrno; + TSDB_CHECK_CODE(code, lino, _exit); + + int64_t n = taosFSendFile(fdTo, fdFrom, 0, tsdbLogicToFileSize(from->f->size, rtxer->szPage)); + if (n < 0) { + code = TAOS_SYSTEM_ERROR(errno); + TSDB_CHECK_CODE(code, lino, _exit); + } + taosCloseFile(&fdFrom); + taosCloseFile(&fdTo); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtxer->tsdb->pVnode), lino, code); + taosCloseFile(&fdFrom); + taosCloseFile(&fdTo); + } + return code; +} + +static int32_t tsdbDoMigrateFileObj(SRTXer *rtxer, const STFileObj *fobj, const SDiskID *did) { + int32_t code = 0; + int32_t lino = 0; + STFileOp op = {0}; + + // remove old + op = (STFileOp){ + .optype = TSDB_FOP_REMOVE, + .fid = fobj->f->fid, + .of = fobj->f[0], + }; + + code = TARRAY2_APPEND(rtxer->fopArr, op); + TSDB_CHECK_CODE(code, lino, _exit); + + // create new + op = (STFileOp){ + .optype = TSDB_FOP_CREATE, + .fid = fobj->f->fid, + .nf = + { + .type = fobj->f->type, + .did = did[0], + .fid = fobj->f->fid, + .cid = rtxer->cid, + .size = fobj->f->size, + .stt[0] = + { + .level = fobj->f->stt[0].level, + }, + }, + }; + + code = TARRAY2_APPEND(rtxer->fopArr, op); + TSDB_CHECK_CODE(code, lino, _exit); + + // do copy the file + code = tsdbDoCopyFile(rtxer, fobj, &op.nf); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtxer->tsdb->pVnode), lino, code); + } + return code; +} + +static int32_t tsdbDoRetentionBegin(STsdb *tsdb, SRTXer *rtxer) { + int32_t code = 0; + int32_t lino = 0; + + // TODO: wait for merge and compact task done + + rtxer->tsdb = tsdb; + rtxer->szPage = tsdb->pVnode->config.tsdbPageSize; + rtxer->now = taosGetTimestampMs(); + rtxer->cid = tsdbFSAllocEid(tsdb->pFS); + + code = tsdbFSCreateCopySnapshot(tsdb->pFS, &rtxer->fsetArr); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtxer->tsdb->pVnode), lino, code); + } else { + tsdbInfo("vid:%d, cid:%" PRId64 ", %s done", TD_VID(rtxer->tsdb->pVnode), rtxer->cid, __func__); + } + return code; +} + +static int32_t tsdbDoRetentionEnd(SRTXer *rtxer) { + int32_t code = 0; + int32_t lino = 0; + + if (TARRAY2_SIZE(rtxer->fopArr) == 0) goto _exit; + + code = tsdbFSEditBegin(rtxer->tsdb->pFS, rtxer->fopArr, TSDB_FEDIT_MERGE); + TSDB_CHECK_CODE(code, lino, _exit); + + taosThreadRwlockWrlock(&rtxer->tsdb->rwLock); + + code = tsdbFSEditCommit(rtxer->tsdb->pFS); + if (code) { + taosThreadRwlockUnlock(&rtxer->tsdb->rwLock); + TSDB_CHECK_CODE(code, lino, _exit); + } + + taosThreadRwlockUnlock(&rtxer->tsdb->rwLock); + + TARRAY2_DESTROY(rtxer->fopArr, NULL); + tsdbFSDestroyCopySnapshot(&rtxer->fsetArr); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtxer->tsdb->pVnode), lino, code); + } else { + tsdbInfo("vid:%d, cid:%" PRId64 ", %s done", TD_VID(rtxer->tsdb->pVnode), rtxer->cid, __func__); + } + return code; +} + +static int32_t tsdbDoRetention2(STsdb *tsdb) { + int32_t code = 0; + int32_t lino = 0; + + SRTXer rtxer[1] = {0}; + + code = tsdbDoRetentionBegin(tsdb, rtxer); + TSDB_CHECK_CODE(code, lino, _exit); + + while (rtxer->ctx->fsetArrIdx < TARRAY2_SIZE(rtxer->fsetArr)) { + rtxer->ctx->fset = TARRAY2_GET(rtxer->fsetArr, rtxer->ctx->fsetArrIdx); + + STFileObj *fobj; + int32_t expLevel = tsdbFidLevel(rtxer->ctx->fset->fid, &rtxer->tsdb->keepCfg, rtxer->now); + + if (expLevel < 0) { // remove the file set + for (int32_t ftype = 0; (ftype < TSDB_FTYPE_MAX) && (fobj = rtxer->ctx->fset->farr[ftype], 1); ++ftype) { + if (fobj == NULL) continue; + + code = tsdbDoRemoveFileObject(rtxer, fobj); + TSDB_CHECK_CODE(code, lino, _exit); + } + + SSttLvl *lvl; + TARRAY2_FOREACH(rtxer->ctx->fset->lvlArr, lvl) { + TARRAY2_FOREACH(lvl->fobjArr, fobj) { + code = tsdbDoRemoveFileObject(rtxer, fobj); + TSDB_CHECK_CODE(code, lino, _exit); + } + } + } else if (expLevel == 0) { + continue; + } else { + SDiskID did; + + if (tfsAllocDisk(rtxer->tsdb->pVnode->pTfs, expLevel, &did) < 0) { + code = terrno; + TSDB_CHECK_CODE(code, lino, _exit); + } + + // data + for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX && (fobj = rtxer->ctx->fset->farr[ftype], 1); ++ftype) { + if (fobj == NULL) continue; + + if (fobj->f->did.level == did.level) continue; + code = tsdbDoMigrateFileObj(rtxer, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } + + // stt + SSttLvl *lvl; + TARRAY2_FOREACH(rtxer->ctx->fset->lvlArr, lvl) { + TARRAY2_FOREACH(lvl->fobjArr, fobj) { + if (fobj->f->did.level == did.level) continue; + + code = tsdbDoMigrateFileObj(rtxer, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } + } + } + } + + code = tsdbDoRetentionEnd(rtxer); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtxer->tsdb->pVnode), lino, code); + } + return code; +}