diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 32249e3d8b..560832cd74 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -239,6 +239,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_FILL, + QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL, QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION, QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index e6e34648f9..25ff18a8fc 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -464,6 +464,8 @@ typedef struct SFillPhysiNode { EOrder inputTsOrder; } SFillPhysiNode; +typedef SFillPhysiNode SStreamFillPhysiNode; + typedef struct SMultiTableIntervalPhysiNode { SIntervalPhysiNode interval; SNodeList* pPartitionKeys; diff --git a/include/libs/stream/streamState.h b/include/libs/stream/streamState.h index 849d83a58b..0adcf976f0 100644 --- a/include/libs/stream/streamState.h +++ b/include/libs/stream/streamState.h @@ -31,6 +31,7 @@ typedef struct { TDB* db; TTB* pStateDb; TTB* pFuncStateDb; + TTB* pFillStateDb; // todo refactor TXN txn; } SStreamState; @@ -51,15 +52,22 @@ int32_t streamStateFuncDel(SStreamState* pState, const STupleKey* key); int32_t streamStatePut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen); int32_t streamStateGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); int32_t streamStateDel(SStreamState* pState, const SWinKey* key); + +int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen); +int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); +int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key); + int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); int32_t streamStateReleaseBuf(SStreamState* pState, const SWinKey* key, void* pVal); void streamFreeVal(void* val); SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key); -SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key); -SStreamStateCur* streamStateSeekKeyPrev(SStreamState* pState, const SWinKey* key); +SStreamStateCur* streamStateGetAndCheckCur(SStreamState* pState, SWinKey* key); +SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey* key); +SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey* key); void streamStateFreeCur(SStreamStateCur* pCur); +int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen); int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen); int32_t streamStateSeekFirst(SStreamState* pState, SStreamStateCur* pCur); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 12e00a0a06..a9a0267fbf 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -34,6 +34,7 @@ extern "C" { #include "scalar.h" #include "taosdef.h" #include "tarray.h" +#include "tfill.h" #include "thash.h" #include "tlockfree.h" #include "tmsg.h" @@ -798,6 +799,22 @@ typedef struct SStreamPartitionOperatorInfo { SSDataBlock* pDelRes; } SStreamPartitionOperatorInfo; +typedef struct SStreamFillOperatorInfo { + SStreamFillSupporter* pFillSup; + SSDataBlock* pRes; + SSDataBlock* pSrcBlock; + int32_t srcRowIndex; + SSDataBlock* pPrevSrcBlock; + SSDataBlock* pSrcDelBlock; + int32_t srcDelRowIndex; + SSDataBlock* pDelRes; + SNode* pCondition; + SArray* pColMatchColInfo; + int32_t primaryTsCol; + int32_t primarySrcSlotId; + SStreamFillInfo* pFillInfo; +} SStreamFillOperatorInfo; + typedef struct STimeSliceOperatorInfo { SSDataBlock* pRes; STimeWindow win; @@ -1006,6 +1023,8 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, + SExecTaskInfo* pTaskInfo); int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx, int32_t numOfOutput, SArray* pPseudoList); @@ -1094,6 +1113,7 @@ int32_t setOutputBuf(STimeWindow* win, SResultRow** pResult, int64_t tableGroupI SExecTaskInfo* pTaskInfo); int32_t releaseOutputBuf(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult); int32_t saveOutputBuf(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult, int32_t resSize); +void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order); #ifdef __cplusplus } diff --git a/source/libs/executor/inc/tfill.h b/source/libs/executor/inc/tfill.h index 63abfc019d..ed019be767 100644 --- a/source/libs/executor/inc/tfill.h +++ b/source/libs/executor/inc/tfill.h @@ -23,12 +23,13 @@ extern "C" { #include "os.h" #include "taosdef.h" #include "tcommon.h" +#include "tsimplehash.h" struct SSDataBlock; typedef struct SFillColInfo { - SExprInfo *pExpr; - bool notFillCol; // denote if this column needs fill operation + SExprInfo* pExpr; + bool notFillCol; // denote if this column needs fill operation SVariant fillVal; } SFillColInfo; @@ -51,46 +52,96 @@ typedef struct { } SRowVal; typedef struct SFillInfo { - TSKEY start; // start timestamp - TSKEY end; // endKey for fill - TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure. - int32_t tsSlotId; // primary time stamp slot id - int32_t srcTsSlotId; // timestamp column id in the source data block. - int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC] - int32_t type; // fill type - int32_t numOfRows; // number of rows in the input data block - int32_t index; // active row index - int32_t numOfTotal; // number of filled rows in one round - int32_t numOfCurrent; // number of filled rows in current results - int32_t numOfCols; // number of columns, including the tags columns - SInterval interval; - SRowVal prev; - SRowVal next; - SSDataBlock *pSrcBlock; - int32_t alloc; // data buffer size in rows + TSKEY start; // start timestamp + TSKEY end; // endKey for fill + TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure. + int32_t tsSlotId; // primary time stamp slot id + int32_t srcTsSlotId; // timestamp column id in the source data block. + int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC] + int32_t type; // fill type + int32_t numOfRows; // number of rows in the input data block + int32_t index; // active row index + int32_t numOfTotal; // number of filled rows in one round + int32_t numOfCurrent; // number of filled rows in current results + int32_t numOfCols; // number of columns, including the tags columns + SInterval interval; + SRowVal prev; + SRowVal next; + SSDataBlock* pSrcBlock; + int32_t alloc; // data buffer size in rows - SFillColInfo* pFillCol; // column info for fill operations - SFillTagColInfo* pTags; // tags value for filling gap - const char* id; + SFillColInfo* pFillCol; // column info for fill operations + SFillTagColInfo* pTags; // tags value for filling gap + const char* id; } SFillInfo; +typedef struct SResultCellData { + bool isNull; + int8_t type; + int32_t bytes; + char pData[]; +} SResultCellData; + +typedef struct SResultRowData { + TSKEY key; + SResultCellData* pRowVal; +} SResultRowData; + +typedef struct SStreamFillLinearInfo { + TSKEY nextEnd; + SArray* pDeltaVal; // double. value for Fill(linear). + SArray* pNextDeltaVal; // double. value for Fill(linear). + int64_t winIndex; + bool hasNext; +} SStreamFillLinearInfo; + +typedef struct SStreamFillInfo { + TSKEY start; // startKey for fill + TSKEY end; // endKey for fill + TSKEY current; // current Key for fill + TSKEY preRowKey; + TSKEY nextRowKey; + SResultRowData* pResRow; + SStreamFillLinearInfo* pLinearInfo; + bool needFill; + int32_t type; // fill type + int32_t pos; + SArray* delRanges; + int32_t delIndex; +} SStreamFillInfo; + +typedef struct SStreamFillSupporter { + int32_t type; // fill type + SInterval interval; + SResultRowData prev; + SResultRowData cur; + SResultRowData next; + SResultRowData nextNext; + SFillColInfo* pAllColInfo; // fill exprs and not fill exprs + int32_t numOfAllCols; // number of all exprs, including the tags columns + int32_t numOfFillCols; + int32_t numOfNotFillCols; + int32_t rowSize; + SSHashObj* pResMap; + bool hasDelete; +} SStreamFillSupporter; + int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows); - -void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey); -void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp); -void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput); -struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr, int32_t numOfNotFillCols, const struct SNodeListNode* val); -bool taosFillHasMoreResults(struct SFillInfo* pFillInfo); +void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey); +void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp); +void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput); +struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr, + int32_t numOfNotFillCols, const struct SNodeListNode* val); +bool taosFillHasMoreResults(struct SFillInfo* pFillInfo); SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t numOfNotFillCols, int32_t capacity, SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol, int32_t slotId, int32_t order, const char* id); -void* taosDestroyFillInfo(struct SFillInfo *pFillInfo); +void* taosDestroyFillInfo(struct SFillInfo* pFillInfo); int64_t taosFillResultDataBlock(struct SFillInfo* pFillInfo, SSDataBlock* p, int32_t capacity); -int64_t getFillInfoStart(struct SFillInfo *pFillInfo); - +int64_t getFillInfoStart(struct SFillInfo* pFillInfo); #ifdef __cplusplus } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index a0729bdf3b..9917791312 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3742,6 +3742,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) { pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, pTaskInfo); + } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL == type) { + pOptr = createStreamFillOperatorInfo(ops[0], (SStreamFillPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) { pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 6c5c33ae29..5e1ec29a75 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1022,11 +1022,7 @@ static uint64_t getGroupIdByCol(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0); } -static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) { - if (pInfo->partitionSup.needCalc) { - return getGroupIdByCol(pInfo, uid, ts, maxVersion); - } - +static uint64_t getGroupIdByUid(SStreamScanInfo* pInfo, uint64_t uid) { SHashObj* map = pInfo->pTableScanOp->pTaskInfo->tableqinfoList.map; uint64_t* groupId = taosHashGet(map, &uid, sizeof(int64_t)); if (groupId) { @@ -1035,6 +1031,14 @@ static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, return 0; } +static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) { + if (pInfo->partitionSup.needCalc) { + return getGroupIdByCol(pInfo, uid, ts, maxVersion); + } + + return getGroupIdByUid(pInfo, uid); +} + static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t* pRowIndex) { if ((*pRowIndex) == pBlock->info.rows) { return false; @@ -1081,26 +1085,32 @@ static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_ return true; } -static STimeWindow getSlidingWindow(TSKEY* startTsCol, TSKEY* endTsCol, SInterval* pInterval, +static STimeWindow getSlidingWindow(TSKEY* startTsCol, TSKEY* endTsCol, uint64_t* gpIdCol, SInterval* pInterval, SDataBlockInfo* pDataBlockInfo, int32_t* pRowIndex, bool hasGroup) { SResultRowInfo dumyInfo; dumyInfo.cur.pageId = -1; STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTsCol[*pRowIndex], pInterval, TSDB_ORDER_ASC); STimeWindow endWin = win; STimeWindow preWin = win; + uint64_t groupId = gpIdCol[*pRowIndex]; while (1) { if (hasGroup) { (*pRowIndex) += 1; } else { - (*pRowIndex) += getNumOfRowsInTimeWindow(pDataBlockInfo, startTsCol, *pRowIndex, endWin.ekey, binarySearchForKey, - NULL, TSDB_ORDER_ASC); + while ((groupId == gpIdCol[(*pRowIndex)] && startTsCol[*pRowIndex] < endWin.ekey)) { + (*pRowIndex) += 1; + if ((*pRowIndex) == pDataBlockInfo->rows) { + break; + } + } } + do { preWin = endWin; getNextTimeWindow(pInterval, &endWin, TSDB_ORDER_ASC); } while (endTsCol[(*pRowIndex) - 1] >= endWin.skey); endWin = preWin; - if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows) { + if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows || groupId != gpIdCol[*pRowIndex]) { win.ekey = endWin.ekey; return win; } @@ -1235,11 +1245,13 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS int64_t version = pSrcBlock->info.version - 1; for (int32_t i = 0; i < rows;) { uint64_t srcUid = srcUidData[i]; - uint64_t groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version); - uint64_t srcGpId = srcGp[i]; - TSKEY calStartTs = srcStartTsCol[i]; + uint64_t groupId = srcGp[i]; + if (groupId == 0) { + groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version); + } + TSKEY calStartTs = srcStartTsCol[i]; colDataAppend(pCalStartTsCol, pDestBlock->info.rows, (const char*)(&calStartTs), false); - STimeWindow win = getSlidingWindow(srcStartTsCol, srcEndTsCol, &pInfo->interval, &pSrcBlock->info, &i, + STimeWindow win = getSlidingWindow(srcStartTsCol, srcEndTsCol, srcGp, &pInfo->interval, &pSrcBlock->info, &i, pInfo->partitionSup.needCalc); TSKEY calEndTs = srcStartTsCol[i - 1]; colDataAppend(pCalEndTsCol, pDestBlock->info.rows, (const char*)(&calEndTs), false); @@ -1248,15 +1260,6 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS colDataAppend(pEndTsCol, pDestBlock->info.rows, (const char*)(&win.ekey), false); colDataAppend(pGpCol, pDestBlock->info.rows, (const char*)(&groupId), false); pDestBlock->info.rows++; - if (pInfo->partitionSup.needCalc && srcGpId != 0 && groupId != srcGpId) { - colDataAppend(pCalStartTsCol, pDestBlock->info.rows, (const char*)(&calStartTs), false); - colDataAppend(pCalEndTsCol, pDestBlock->info.rows, (const char*)(&calEndTs), false); - colDataAppend(pDeUidCol, pDestBlock->info.rows, (const char*)(&srcUid), false); - colDataAppend(pStartTsCol, pDestBlock->info.rows, (const char*)(&win.skey), false); - colDataAppend(pEndTsCol, pDestBlock->info.rows, (const char*)(&win.ekey), false); - colDataAppend(pGpCol, pDestBlock->info.rows, (const char*)(&srcGpId), false); - pDestBlock->info.rows++; - } } return TSDB_CODE_SUCCESS; } @@ -1331,7 +1334,7 @@ void appendOneRow(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock* pBlock, bool out) { if (out) { blockDataCleanup(pInfo->pUpdateDataRes); - blockDataEnsureCapacity(pInfo->pUpdateDataRes, pBlock->info.rows); + blockDataEnsureCapacity(pInfo->pUpdateDataRes, pBlock->info.rows * 2); } SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex); ASSERT(pColDataInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP); @@ -1352,10 +1355,12 @@ static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock isDeletedStreamWindow(&win, pBlock->info.groupId, pInfo->pTableScanOp, &pInfo->twAggSup); if ((update || closedWin) && out) { qDebug("stream update check not pass, update %d, closedWin %d", update, closedWin); - uint64_t gpId = closedWin && pInfo->partitionSup.needCalc - ? calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pBlock, rowId) - : 0; + uint64_t gpId = 0; appendOneRow(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId); + if (closedWin && pInfo->partitionSup.needCalc) { + gpId = calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pBlock, rowId); + appendOneRow(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId); + } } } if (out && pInfo->pUpdateDataRes->info.rows > 0) { @@ -1532,6 +1537,30 @@ static int32_t filterDelBlockByUid(SSDataBlock* pDst, const SSDataBlock* pSrc, S return 0; } +// for partition by tag +static void setBlockGroupIdByUid(SStreamScanInfo* pInfo, SSDataBlock* pBlock) { + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startTsCol = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* gpCol = (uint64_t*)pGpCol->pData; + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + uint64_t* uidCol = (uint64_t*)pUidCol->pData; + int32_t rows = pBlock->info.rows; + if (!pInfo->partitionSup.needCalc) { + for (int32_t i = 0; i < rows; i++) { + uint64_t groupId = getGroupIdByUid(pInfo, uidCol[i]); + colDataAppend(pGpCol, i, (const char*)&groupId, false); + } + } else { + // SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, uidCol[i], startTsCol, ts, maxVersion); + // if (!pPreRes || pPreRes->info.rows == 0) { + // return 0; + // } + // ASSERT(pPreRes->info.rows == 1); + // return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0); + } +} + static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { // NOTE: this operator does never check if current status is done or not SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; @@ -1628,7 +1657,8 @@ FETCH_NEXT_BLOCK: } else { pDelBlock = pBlock; } - printDataBlock(pBlock, "stream scan delete recv filtered"); + setBlockGroupIdByUid(pInfo, pDelBlock); + printDataBlock(pDelBlock, "stream scan delete recv filtered"); if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) { generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT; diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c index f23552c5a7..ea0d26f4de 100644 --- a/source/libs/executor/src/tfill.c +++ b/source/libs/executor/src/tfill.c @@ -19,6 +19,7 @@ #include "tmsg.h" #include "ttypes.h" +#include "executorimpl.h" #include "tcommon.h" #include "thash.h" #include "ttime.h" @@ -35,18 +36,30 @@ #define GET_DEST_SLOT_ID(_p) ((_p)->pExpr->base.resSchema.slotId) +#define FILL_POS_INVALID 0 +#define FILL_POS_START 1 +#define FILL_POS_MID 2 +#define FILL_POS_END 3 + +typedef struct STimeRange { + TSKEY skey; + TSKEY ekey; + uint64_t groupId; +} STimeRange; + static void doSetVal(SColumnInfoData* pDstColInfoData, int32_t rowIndex, const SGroupKeys* pKey); -static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex); +static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, + int32_t rowIndex); static void setNullRow(SSDataBlock* pBlock, SFillInfo* pFillInfo, int32_t rowIndex) { - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - int32_t dstSlotId = GET_DEST_SLOT_ID(pCol); + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + int32_t dstSlotId = GET_DEST_SLOT_ID(pCol); SColumnInfoData* pDstColInfo = taosArrayGet(pBlock->pDataBlock, dstSlotId); if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfo, rowIndex); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfo, rowIndex, pKey); } @@ -76,8 +89,9 @@ static void doSetUserSpecifiedValue(SColumnInfoData* pDst, SVariant* pVar, int32 } } -//fill windows pseudo column, _wstart, _wend, _wduration and return true, otherwise return false -static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex) { +// fill windows pseudo column, _wstart, _wend, _wduration and return true, otherwise return false +static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, + int32_t rowIndex) { if (!pCol->notFillCol) { return false; } @@ -89,15 +103,15 @@ static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, S colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->currentKey, false); return true; } else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_END) { - //TODO: include endpoint + // TODO: include endpoint SInterval* pInterval = &pFillInfo->interval; - int32_t step = (pFillInfo->order == TSDB_ORDER_ASC) ? 1 : -1; - int64_t windowEnd = + int32_t step = (pFillInfo->order == TSDB_ORDER_ASC) ? 1 : -1; + int64_t windowEnd = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision); colDataAppend(pDstColInfoData, rowIndex, (const char*)&windowEnd, false); return true; } else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_DURATION) { - //TODO: include endpoint + // TODO: include endpoint colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->interval.sliding, false); return true; } @@ -115,13 +129,13 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* // set the other values if (pFillInfo->type == TSDB_FILL_PREV) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo)? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); + bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); if (!filled) { SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfoData, index, pKey); @@ -131,9 +145,9 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->next.pRowVal : pFillInfo->prev.pRowVal; // todo refactor: start from 0 not 1 for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); + bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); if (!filled) { SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfoData, index, pKey); @@ -154,7 +168,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstCol, index); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstCol, index, pKey); } @@ -190,13 +204,13 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - int32_t slotId = GET_DEST_SLOT_ID(pCol); + int32_t slotId = GET_DEST_SLOT_ID(pCol); SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, slotId); if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDst, index); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDst, index, pKey); } @@ -261,8 +275,8 @@ static void copyCurrentRowIntoBuf(SFillInfo* pFillInfo, int32_t rowIndex, SArray } else if (type == QUERY_NODE_OPERATOR) { SColumnInfoData* pSrcCol = taosArrayGet(pFillInfo->pSrcBlock->pDataBlock, i); - bool isNull = colDataIsNull_s(pSrcCol, rowIndex); - char* p = colDataGetData(pSrcCol, rowIndex); + bool isNull = colDataIsNull_s(pSrcCol, rowIndex); + char* p = colDataGetData(pSrcCol, rowIndex); saveColData(pRow, i, p, isNull); } else { ASSERT(0); @@ -425,9 +439,9 @@ struct SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t pFillInfo->order = order; pFillInfo->srcTsSlotId = primaryTsSlotId; - for(int32_t i = 0; i < numOfNotFillCols; ++i) { + for (int32_t i = 0; i < numOfNotFillCols; ++i) { SFillColInfo* p = &pCol[i + numOfFillCols]; - int32_t srcSlotId = GET_DEST_SLOT_ID(p); + int32_t srcSlotId = GET_DEST_SLOT_ID(p); if (srcSlotId == primaryTsSlotId) { pFillInfo->tsSlotId = i + numOfFillCols; break; @@ -499,9 +513,9 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) { } taosArrayDestroy(pFillInfo->next.pRowVal); -// for (int32_t i = 0; i < pFillInfo->numOfTags; ++i) { -// taosMemoryFreeClear(pFillInfo->pTags[i].tagVal); -// } + // for (int32_t i = 0; i < pFillInfo->numOfTags; ++i) { + // taosMemoryFreeClear(pFillInfo->pTags[i].tagVal); + // } taosMemoryFreeClear(pFillInfo->pTags); taosMemoryFreeClear(pFillInfo->pFillCol); @@ -640,7 +654,7 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprIn } } - for(int32_t i = 0; i < numOfNotFillExpr; ++i) { + for (int32_t i = 0; i < numOfNotFillExpr; ++i) { SExprInfo* pExprInfo = &pNotFillExpr[i]; pFillCol[i + numOfFillExpr].pExpr = pExprInfo; pFillCol[i + numOfFillExpr].notFillCol = true; @@ -648,3 +662,1050 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprIn return pFillCol; } + +TSKEY getNextWindowTs(TSKEY ts, SInterval* pInterval) { + STimeWindow win = {.skey = ts, .ekey = ts}; + getNextIntervalWindow(pInterval, &win, TSDB_ORDER_ASC); + return win.skey; +} + +TSKEY getPrevWindowTs(TSKEY ts, SInterval* pInterval) { + STimeWindow win = {.skey = ts, .ekey = ts}; + getNextIntervalWindow(pInterval, &win, TSDB_ORDER_DESC); + return win.skey; +} + +void setRowCell(SColumnInfoData* pCol, int32_t rowId, const SResultCellData* pCell) { + colDataAppend(pCol, rowId, pCell->pData, pCell->isNull); +} + +SResultCellData* getResultCell(SResultRowData* pRaw, int32_t index) { + if (!pRaw || !pRaw->pRowVal) { + return NULL; + } + char* pData = (char*)pRaw->pRowVal; + SResultCellData* pCell = pRaw->pRowVal; + for (int32_t i = 0; i < index; i++) { + pData += (pCell->bytes + sizeof(SResultCellData)); + pCell = (SResultCellData*)pData; + } + return pCell; +} + +void* destroyFillColumnInfo(SFillColInfo* pFillCol, int32_t start, int32_t end) { + for (int32_t i = start; i < end; i++) { + destroyExprInfo(pFillCol[i].pExpr, 1); + taosMemoryFreeClear(pFillCol[i].pExpr); + taosVariantDestroy(&pFillCol[i].fillVal); + } + taosMemoryFree(pFillCol); + return NULL; +} + +void* destroyStreamFillSupporter(SStreamFillSupporter* pFillSup) { + pFillSup->pAllColInfo = destroyFillColumnInfo(pFillSup->pAllColInfo, pFillSup->numOfFillCols, pFillSup->numOfAllCols); + tSimpleHashCleanup(pFillSup->pResMap); + pFillSup->pResMap = NULL; + taosMemoryFree(pFillSup); + return NULL; +} + +void* destroyStreamFillLinearInfo(SStreamFillLinearInfo* pFillLinear) { + taosArrayDestroy(pFillLinear->pDeltaVal); + taosArrayDestroy(pFillLinear->pNextDeltaVal); + taosMemoryFree(pFillLinear); + return NULL; +} +void* destroyStreamFillInfo(SStreamFillInfo* pFillInfo) { + if (pFillInfo->type == TSDB_FILL_SET_VALUE || pFillInfo->type == TSDB_FILL_NULL) { + taosMemoryFreeClear(pFillInfo->pResRow->pRowVal); + taosMemoryFreeClear(pFillInfo->pResRow); + } + pFillInfo->pLinearInfo = destroyStreamFillLinearInfo(pFillInfo->pLinearInfo); + taosMemoryFree(pFillInfo); + return NULL; +} + +void destroyStreamFillOperatorInfo(void* param) { + SStreamFillOperatorInfo* pInfo = (SStreamFillOperatorInfo*)param; + pInfo->pFillInfo = destroyStreamFillInfo(pInfo->pFillInfo); + pInfo->pFillSup = destroyStreamFillSupporter(pInfo->pFillSup); + pInfo->pRes = blockDataDestroy(pInfo->pRes); + pInfo->pSrcBlock = blockDataDestroy(pInfo->pSrcBlock); + pInfo->pColMatchColInfo = taosArrayDestroy(pInfo->pColMatchColInfo); + taosMemoryFree(pInfo); +} + +static void resetFillWindow(SResultRowData* pRowData) { + pRowData->key = INT64_MIN; + pRowData->pRowVal = NULL; +} + +void resetPrevAndNextWindow(SStreamFillSupporter* pFillSup, SStreamState* pState) { + resetFillWindow(&pFillSup->prev); + resetFillWindow(&pFillSup->cur); + resetFillWindow(&pFillSup->next); + resetFillWindow(&pFillSup->nextNext); +} + +void getCurWindowFromDiscBuf(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, SStreamFillSupporter* pFillSup) { + SStreamState* pState = pOperator->pTaskInfo->streamInfo.pState; + resetPrevAndNextWindow(pFillSup, pState); + + SWinKey key = {.ts = ts, .groupId = groupId}; + void* curVal = NULL; + int32_t curVLen = 0; + int32_t code = streamStateFillGet(pState, &key, (void**)&curVal, &curVLen); + ASSERT(code == TSDB_CODE_SUCCESS); + pFillSup->cur.key = key.ts; + pFillSup->cur.pRowVal = curVal; +} + +void getWindowFromDiscBuf(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, SStreamFillSupporter* pFillSup) { + SStreamState* pState = pOperator->pTaskInfo->streamInfo.pState; + resetPrevAndNextWindow(pFillSup, pState); + + SWinKey key = {.ts = ts, .groupId = groupId}; + void* curVal = NULL; + int32_t curVLen = 0; + int32_t code = streamStateFillGet(pState, &key, (void**)&curVal, &curVLen); + ASSERT(code == TSDB_CODE_SUCCESS); + pFillSup->cur.key = key.ts; + pFillSup->cur.pRowVal = curVal; + + SStreamStateCur* pCur = streamStateFillSeekKeyPrev(pState, &key); + SWinKey preKey = {.groupId = groupId}; + void* preVal = NULL; + int32_t preVLen = 0; + if (pCur) { + code = streamStateGetGroupKVByCur(pCur, &preKey, (const void**)&preVal, &preVLen); + } + + if (pCur && code == TSDB_CODE_SUCCESS) { + pFillSup->prev.key = preKey.ts; + pFillSup->prev.pRowVal = preVal; + + code = streamStateCurNext(pState, pCur); + ASSERT(code == TSDB_CODE_SUCCESS); + + code = streamStateCurNext(pState, pCur); + if (code != TSDB_CODE_SUCCESS) { + pCur = NULL; + } + } else { + pCur = streamStateFillSeekKeyNext(pState, &key); + } + + if (pCur) { + SWinKey nextKey = {.groupId = groupId}; + void* nextVal = NULL; + int32_t nextVLen = 0; + code = streamStateGetGroupKVByCur(pCur, &nextKey, (const void**)&nextVal, &nextVLen); + if (code == TSDB_CODE_SUCCESS) { + pFillSup->next.key = nextKey.ts; + pFillSup->next.pRowVal = nextVal; + if (pFillSup->type == TSDB_FILL_PREV || pFillSup->type == TSDB_FILL_NEXT) { + code = streamStateCurNext(pState, pCur); + if (code == TSDB_CODE_SUCCESS) { + SWinKey nextNextKey = {.groupId = groupId}; + void* nextNextVal = NULL; + int32_t nextNextVLen = 0; + code = streamStateGetGroupKVByCur(pCur, &nextNextKey, (const void**)&nextNextVal, &nextNextVLen); + if (code == TSDB_CODE_SUCCESS) { + pFillSup->nextNext.key = nextNextKey.ts; + pFillSup->nextNext.pRowVal = nextNextVal; + } + } + } + } + } +} + +static bool hasPrevWindow(SStreamFillSupporter* pFillSup) { return pFillSup->prev.key != INT64_MIN; } +static bool hasNextWindow(SStreamFillSupporter* pFillSup) { return pFillSup->next.key != INT64_MIN; } +static bool hasNextNextWindow(SStreamFillSupporter* pFillSup) { + return pFillSup->nextNext.key != INT64_MIN; + return false; +} + +static void transBlockToResultRow(const SSDataBlock* pBlock, int32_t rowId, TSKEY ts, SResultRowData* pRowVal) { + int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); + SResultCellData* pCell = getResultCell(pRowVal, i); + if (!colDataIsNull_s(pColData, rowId)) { + pCell->isNull = false; + pCell->type = pColData->info.type; + pCell->bytes = pColData->info.bytes; + char* val = colDataGetData(pColData, rowId); + if (IS_VAR_DATA_TYPE(pCell->type)) { + memcpy(pCell->pData, val, varDataTLen(val)); + } else { + memcpy(pCell->pData, val, pCell->bytes); + } + } else { + pCell->isNull = true; + } + } + pRowVal->key = ts; +} + +static void calcDeltaData(SSDataBlock* pBlock, int32_t rowId, SResultRowData* pRowVal, SArray* pDelta, + SFillColInfo* pFillCol, int32_t numOfCol, int32_t winCount, int32_t order) { + for (int32_t i = 0; i < numOfCol; i++) { + if (!pFillCol[i].notFillCol) { + int32_t slotId = GET_DEST_SLOT_ID(pFillCol + i); + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + char* var = colDataGetData(pCol, rowId); + double start = 0; + GET_TYPED_DATA(start, double, pCol->info.type, var); + SResultCellData* pCell = getResultCell(pRowVal, slotId); + double end = 0; + GET_TYPED_DATA(end, double, pCell->type, pCell->pData); + double delta = 0; + if (order == TSDB_ORDER_ASC) { + delta = (end - start) / winCount; + } else { + delta = (start - end) / winCount; + } + taosArraySet(pDelta, slotId, &delta); + } + } +} + +static void calcRowDeltaData(SResultRowData* pStartRow, SResultRowData* pEndRow, SArray* pDelta, SFillColInfo* pFillCol, + int32_t numOfCol, int32_t winCount) { + for (int32_t i = 0; i < numOfCol; i++) { + if (!pFillCol[i].notFillCol) { + int32_t slotId = GET_DEST_SLOT_ID(pFillCol + i); + SResultCellData* pSCell = getResultCell(pStartRow, slotId); + double start = 0.0; + GET_TYPED_DATA(start, double, pSCell->type, pSCell->pData); + SResultCellData* pECell = getResultCell(pEndRow, slotId); + double end = 0.0; + GET_TYPED_DATA(end, double, pECell->type, pECell->pData); + double delta = (end - start) / winCount; + taosArraySet(pDelta, slotId, &delta); + } + } +} + +static void setFillInfoStart(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + ts = taosTimeAdd(ts, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); + pFillInfo->start = ts; +} + +static void setFillInfoEnd(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + ts = taosTimeAdd(ts, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision); + pFillInfo->end = ts; +} + +static void setFillKeyInfo(TSKEY start, TSKEY end, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + setFillInfoStart(start, pInterval, pFillInfo); + pFillInfo->current = pFillInfo->start; + setFillInfoEnd(end, pInterval, pFillInfo); +} + +void setDeleteFillValueInfo(TSKEY start, TSKEY end, SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo) { + if (!hasPrevWindow(pFillSup) || !hasNextWindow(pFillSup)) { + pFillInfo->needFill = false; + return; + } + + pFillInfo->needFill = true; + pFillInfo->start = start; + pFillInfo->current = pFillInfo->start; + pFillInfo->end = end; + pFillInfo->pos = FILL_POS_INVALID; + switch (pFillInfo->type) { + case TSDB_FILL_NULL: + case TSDB_FILL_SET_VALUE: + break; + case TSDB_FILL_PREV: + pFillInfo->pResRow = &pFillSup->prev; + break; + case TSDB_FILL_NEXT: + pFillInfo->pResRow = &pFillSup->next; + break; + case TSDB_FILL_LINEAR: { + setFillKeyInfo(pFillSup->prev.key, pFillSup->next.key, &pFillSup->interval, pFillInfo); + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(pFillSup->prev.key, pFillSup->next.key, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->next, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + pFillInfo->pLinearInfo->winIndex = 0; + } break; + default: + ASSERT(0); + break; + } +} + +void setFillValueInfo(SSDataBlock* pBlock, TSKEY ts, int32_t rowId, SStreamFillSupporter* pFillSup, + SStreamFillInfo* pFillInfo) { + pFillInfo->preRowKey = pFillSup->cur.key; + if (!hasPrevWindow(pFillSup) && !hasNextWindow(pFillSup)) { + pFillInfo->needFill = false; + pFillInfo->pos = FILL_POS_START; + return; + } + TSKEY prevWKey = INT64_MIN; + TSKEY nextWKey = INT64_MIN; + if (hasPrevWindow(pFillSup)) { + prevWKey = pFillSup->prev.key; + } + if (hasNextWindow(pFillSup)) { + nextWKey = pFillSup->next.key; + } + + pFillInfo->needFill = true; + pFillInfo->pos = FILL_POS_INVALID; + switch (pFillInfo->type) { + case TSDB_FILL_NULL: + case TSDB_FILL_SET_VALUE: { + if (pFillSup->prev.key == pFillInfo->preRowKey) { + resetFillWindow(&pFillSup->prev); + } + if (hasPrevWindow(pFillSup) && hasNextWindow(pFillSup)) { + if (pFillSup->next.key == pFillInfo->nextRowKey) { + pFillInfo->preRowKey = INT64_MIN; + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + } else { + pFillInfo->needFill = false; + pFillInfo->pos = FILL_POS_START; + } + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + } else { + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + } + } break; + case TSDB_FILL_PREV: { + if (hasNextWindow(pFillSup) && ((pFillSup->next.key != pFillInfo->nextRowKey) || + (pFillSup->next.key == pFillInfo->nextRowKey && hasNextNextWindow(pFillSup)) || + (pFillSup->next.key == pFillInfo->nextRowKey && !hasPrevWindow(pFillSup)))) { + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + pFillSup->prev.key = pFillSup->cur.key; + pFillSup->prev.pRowVal = pFillSup->cur.pRowVal; + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillInfo->preRowKey = INT64_MIN; + } + pFillInfo->pResRow = &pFillSup->prev; + } break; + case TSDB_FILL_NEXT: { + if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillSup->next.key = pFillSup->cur.key; + pFillSup->next.pRowVal = pFillSup->cur.pRowVal; + pFillInfo->preRowKey = INT64_MIN; + } else { + ASSERT(hasNextWindow(pFillSup)); + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + } + pFillInfo->pResRow = &pFillSup->next; + } break; + case TSDB_FILL_LINEAR: { + pFillInfo->pLinearInfo->winIndex = 0; + if (hasPrevWindow(pFillSup) && hasNextWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_MID; + pFillInfo->pLinearInfo->nextEnd = nextWKey; + int32_t numOfWins = taosTimeCountInterval(prevWKey, ts, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->cur, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + + numOfWins = taosTimeCountInterval(ts, nextWKey, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->cur, &pFillSup->next, pFillInfo->pLinearInfo->pNextDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pLinearInfo->hasNext = true; + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(prevWKey, ts, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->cur, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + pFillInfo->pLinearInfo->hasNext = false; + } else { + ASSERT(hasNextWindow(pFillSup)); + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(ts, nextWKey, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->cur, &pFillSup->next, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->cur; + pFillInfo->pLinearInfo->hasNext = false; + } + } break; + default: + ASSERT(0); + break; + } + ASSERT(pFillInfo->pos != FILL_POS_INVALID); +} + +static bool checkResult(SStreamFillSupporter* pFillSup, TSKEY ts, uint64_t groupId) { + SWinKey key = {.groupId = groupId, .ts = ts}; + if (tSimpleHashGet(pFillSup->pResMap, &key, sizeof(SWinKey)) != NULL) { + return false; + } + tSimpleHashPut(pFillSup->pResMap, &key, sizeof(SWinKey), NULL, 0); + return true; +} + +static void buildFillResult(SResultRowData* pResRow, SStreamFillSupporter* pFillSup, TSKEY ts, SSDataBlock* pBlock) { + uint64_t groupId = pBlock->info.groupId; + if (pFillSup->hasDelete && !checkResult(pFillSup, ts, groupId)) { + return; + } + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, slotId); + SFillInfo tmpInfo = { + .currentKey = ts, + .order = TSDB_ORDER_ASC, + .interval = pFillSup->interval, + }; + bool filled = fillIfWindowPseudoColumn(&tmpInfo, pFillCol, pColData, pBlock->info.rows); + if (!filled) { + SResultCellData* pCell = getResultCell(pResRow, slotId); + setRowCell(pColData, pBlock->info.rows, pCell); + } + } + pBlock->info.rows++; +} + +static bool hasRemainCalc(SStreamFillInfo* pFillInfo) { + if (pFillInfo->current != INT64_MIN && pFillInfo->current <= pFillInfo->end) { + return true; + } + return false; +} + +static void doStreamFillNormal(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock) { + while (hasRemainCalc(pFillInfo) && pBlock->info.rows < pBlock->info.capacity) { + buildFillResult(pFillInfo->pResRow, pFillSup, pFillInfo->current, pBlock); + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + } +} + +static void doStreamFillLinear(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock) { + while (hasRemainCalc(pFillInfo) && pBlock->info.rows < pBlock->info.capacity) { + uint64_t groupId = pBlock->info.groupId; + SWinKey key = {.groupId = groupId, .ts = pFillInfo->current}; + if (pFillSup->hasDelete && !checkResult(pFillSup, pFillInfo->current, groupId)) { + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + pFillInfo->pLinearInfo->winIndex++; + continue; + } + pFillInfo->pLinearInfo->winIndex++; + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pFillSup->pAllColInfo + i; + SFillInfo tmp = { + .currentKey = pFillInfo->current, + .order = TSDB_ORDER_ASC, + .interval = pFillSup->interval, + }; + + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, slotId); + int16_t type = pColData->info.type; + SResultCellData* pCell = getResultCell(pFillInfo->pResRow, slotId); + int32_t index = pBlock->info.rows; + if (pFillCol->notFillCol) { + bool filled = fillIfWindowPseudoColumn(&tmp, pFillCol, pColData, index); + if (!filled) { + setRowCell(pColData, index, pCell); + } + } else { + if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || pCell->isNull) { + colDataAppendNULL(pColData, index); + continue; + } + double* pDelta = taosArrayGet(pFillInfo->pLinearInfo->pDeltaVal, slotId); + double vCell = 0; + GET_TYPED_DATA(vCell, double, pCell->type, pCell->pData); + vCell += (*pDelta) * pFillInfo->pLinearInfo->winIndex; + int64_t result = 0; + SET_TYPED_DATA(&result, pCell->type, vCell); + colDataAppend(pColData, index, (const char*)&result, false); + } + } + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + pBlock->info.rows++; + } +} + +static void keepResultInDiscBuf(SOperatorInfo* pOperator, uint64_t groupId, SResultRowData* pRow, int32_t len) { + SWinKey key = {.groupId = groupId, .ts = pRow->key}; + int32_t code = streamStateFillPut(pOperator->pTaskInfo->streamInfo.pState, &key, pRow->pRowVal, len); + ASSERT(code == TSDB_CODE_SUCCESS); +} + +static void doStreamFillRange(SStreamFillInfo* pFillInfo, SStreamFillSupporter* pFillSup, SSDataBlock* pRes) { + if (pFillInfo->needFill == false) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + return; + } + + if (pFillInfo->pos == FILL_POS_START) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } + if (pFillInfo->type != TSDB_FILL_LINEAR) { + doStreamFillNormal(pFillSup, pFillInfo, pRes); + } else { + doStreamFillLinear(pFillSup, pFillInfo, pRes); + + if (pFillInfo->pos == FILL_POS_MID) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } + + if (pFillInfo->current > pFillInfo->end && pFillInfo->pLinearInfo->hasNext) { + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->winIndex = 0; + taosArrayClear(pFillInfo->pLinearInfo->pDeltaVal); + taosArrayAddAll(pFillInfo->pLinearInfo->pDeltaVal, pFillInfo->pLinearInfo->pNextDeltaVal); + pFillInfo->pResRow = &pFillSup->cur; + setFillKeyInfo(pFillSup->cur.key, pFillInfo->pLinearInfo->nextEnd, &pFillSup->interval, pFillInfo); + doStreamFillLinear(pFillSup, pFillInfo, pRes); + } + } + if (pFillInfo->pos == FILL_POS_END) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } +} + +void keepBlockRowInDiscBuf(SOperatorInfo* pOperator, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock, TSKEY* tsCol, + int32_t rowId, uint64_t groupId, int32_t rowSize) { + TSKEY ts = tsCol[rowId]; + pFillInfo->nextRowKey = ts; + SResultRowData tmpNextRow = {.key = ts}; + tmpNextRow.pRowVal = taosMemoryCalloc(1, rowSize); + transBlockToResultRow(pBlock, rowId, ts, &tmpNextRow); + keepResultInDiscBuf(pOperator, groupId, &tmpNextRow, rowSize); + taosMemoryFreeClear(tmpNextRow.pRowVal); +} + +static void doFillResults(SOperatorInfo* pOperator, SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, + SSDataBlock* pBlock, TSKEY* tsCol, int32_t rowId, SSDataBlock* pRes) { + uint64_t groupId = pBlock->info.groupId; + getWindowFromDiscBuf(pOperator, tsCol[rowId], groupId, pFillSup); + if (pFillSup->prev.key == pFillInfo->preRowKey) { + resetFillWindow(&pFillSup->prev); + } + setFillValueInfo(pBlock, tsCol[rowId], rowId, pFillSup, pFillInfo); + doStreamFillRange(pFillInfo, pFillSup, pRes); +} + +static void doStreamFillImpl(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStreamFillSupporter* pFillSup = pInfo->pFillSup; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + SSDataBlock* pBlock = pInfo->pSrcBlock; + uint64_t groupId = pBlock->info.groupId; + SSDataBlock* pRes = pInfo->pRes; + pRes->info.groupId = groupId; + if (hasRemainCalc(pFillInfo)) { + doStreamFillRange(pFillInfo, pFillSup, pRes); + } + + SColumnInfoData* pTsCol = taosArrayGet(pInfo->pSrcBlock->pDataBlock, pInfo->primaryTsCol); + TSKEY* tsCol = (TSKEY*)pTsCol->pData; + + if (pInfo->srcRowIndex == 0) { + keepBlockRowInDiscBuf(pOperator, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex, groupId, pFillSup->rowSize); + SSDataBlock* preBlock = pInfo->pPrevSrcBlock; + if (preBlock->info.rows > 0) { + int preRowId = preBlock->info.rows - 1; + SColumnInfoData* pPreTsCol = taosArrayGet(preBlock->pDataBlock, pInfo->primaryTsCol); + doFillResults(pOperator, pFillSup, pFillInfo, preBlock, (TSKEY*)pPreTsCol->pData, preRowId, pRes); + } + pInfo->srcRowIndex++; + } + + while (pInfo->srcRowIndex < pBlock->info.rows) { + TSKEY ts = tsCol[pInfo->srcRowIndex]; + keepBlockRowInDiscBuf(pOperator, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex, groupId, pFillSup->rowSize); + doFillResults(pOperator, pFillSup, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex - 1, pRes); + if (pInfo->pRes->info.rows == pInfo->pRes->info.capacity) { + blockDataUpdateTsWindow(pRes, pInfo->primaryTsCol); + return; + } + pInfo->srcRowIndex++; + } + blockDataUpdateTsWindow(pRes, pInfo->primaryTsCol); + blockDataCleanup(pInfo->pPrevSrcBlock); + copyDataBlock(pInfo->pPrevSrcBlock, pInfo->pSrcBlock); + blockDataCleanup(pInfo->pSrcBlock); +} + +static void buildDeleteRange(TSKEY start, TSKEY end, uint64_t groupId, SSDataBlock* delRes) { + SSDataBlock* pBlock = delRes; + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + SColumnInfoData* pCalStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + SColumnInfoData* pCalEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + colDataAppend(pStartCol, pBlock->info.rows, (const char*)&start, false); + colDataAppend(pEndCol, pBlock->info.rows, (const char*)&end, false); + colDataAppendNULL(pUidCol, pBlock->info.rows); + colDataAppend(pGroupCol, pBlock->info.rows, (const char*)&groupId, false); + colDataAppendNULL(pCalStartCol, pBlock->info.rows); + colDataAppendNULL(pCalEndCol, pBlock->info.rows); + pBlock->info.rows++; +} + +static void buildDeleteResult(SStreamFillSupporter* pFillSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SSDataBlock* delRes) { + if (hasPrevWindow(pFillSup)) { + TSKEY start = getNextWindowTs(pFillSup->prev.key, &pFillSup->interval); + buildDeleteRange(start, endTs, groupId, delRes); + } else if (hasNextWindow(pFillSup)) { + TSKEY end = getPrevWindowTs(pFillSup->next.key, &pFillSup->interval); + buildDeleteRange(startTs, end, groupId, delRes); + } else { + buildDeleteRange(startTs, endTs, groupId, delRes); + } +} + +static void doDeleteFillResultImpl(SOperatorInfo* pOperator, TSKEY startTs, TSKEY endTs, uint64_t groupId) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + getWindowFromDiscBuf(pOperator, startTs, groupId, pInfo->pFillSup); + setDeleteFillValueInfo(startTs, endTs, pInfo->pFillSup, pInfo->pFillInfo); + SWinKey key = {.ts = startTs, .groupId = groupId}; + if (!pInfo->pFillInfo->needFill) { + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &key); + buildDeleteResult(pInfo->pFillSup, startTs, endTs, groupId, pInfo->pDelRes); + } else { + STimeRange tw = { + .skey = startTs, + .ekey = endTs, + .groupId = groupId, + }; + taosArrayPush(pInfo->pFillInfo->delRanges, &tw); + while (key.ts <= endTs) { + key.ts = taosTimeAdd(key.ts, pInfo->pFillSup->interval.sliding, pInfo->pFillSup->interval.slidingUnit, + pInfo->pFillSup->interval.precision); + tSimpleHashPut(pInfo->pFillSup->pResMap, &key, sizeof(SWinKey), NULL, 0); + } + } +} + +static void doDeleteFillFinalize(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + int32_t size = taosArrayGetSize(pFillInfo->delRanges); + tSimpleHashClear(pInfo->pFillSup->pResMap); + for (; pFillInfo->delIndex < size; pFillInfo->delIndex++) { + STimeRange* range = taosArrayGet(pFillInfo->delRanges, pFillInfo->delIndex); + if (pInfo->pRes->info.groupId != 0 && pInfo->pRes->info.groupId != range->groupId) { + return; + } + getWindowFromDiscBuf(pOperator, range->skey, range->groupId, pInfo->pFillSup); + setDeleteFillValueInfo(range->skey, range->ekey, pInfo->pFillSup, pInfo->pFillInfo); + if (pInfo->pFillInfo->needFill) { + doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); + pInfo->pRes->info.groupId = range->groupId; + } + SWinKey key = {.ts = range->skey, .groupId = range->groupId}; + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &key); + } +} + +static void doDeleteFillResult(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SStreamFillSupporter* pFillSup = pInfo->pFillSup; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + SSDataBlock* pBlock = pInfo->pSrcDelBlock; + SSDataBlock* pRes = pInfo->pRes; + SSDataBlock* pDelRes = pInfo->pDelRes; + + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* tsStarts = (TSKEY*)pStartCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* groupIds = (uint64_t*)pGroupCol->pData; + while (pInfo->srcDelRowIndex < pBlock->info.rows) { + TSKEY ts = tsStarts[pInfo->srcDelRowIndex]; + TSKEY endTs = ts; + uint64_t groupId = groupIds[pInfo->srcDelRowIndex]; + SWinKey key = {.ts = ts, .groupId = groupId}; + SStreamStateCur* pCur = streamStateGetAndCheckCur(pOperator->pTaskInfo->streamInfo.pState, &key); + if (!pCur) { + pInfo->srcDelRowIndex++; + continue; + } + + SWinKey nextKey = {.groupId = groupId, .ts = ts}; + while (pInfo->srcDelRowIndex < pBlock->info.rows) { + void* nextVal = NULL; + int32_t nextLen = 0; + TSKEY delTs = tsStarts[pInfo->srcDelRowIndex]; + uint64_t delGroupId = groupIds[pInfo->srcDelRowIndex]; + int32_t code = TSDB_CODE_SUCCESS; + if (groupId != delGroupId) { + break; + } + if (delTs > nextKey.ts) { + break; + } + endTs = delTs; + SWinKey delKey = {.groupId = delGroupId, .ts = delTs}; + if (delTs == nextKey.ts) { + code = streamStateCurNext(pOperator->pTaskInfo->streamInfo.pState, pCur); + if (code == TSDB_CODE_SUCCESS) { + code = streamStateGetGroupKVByCur(pCur, &nextKey, (const void**)&nextVal, &nextLen); + } + if (delTs != ts) { + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &delKey); + } + if (code != TSDB_CODE_SUCCESS) { + break; + } + } + pInfo->srcDelRowIndex++; + } + doDeleteFillResultImpl(pOperator, ts, endTs, groupId); + } + pFillInfo->current = pFillInfo->end + 1; +} + +static void resetStreamFillInfo(SStreamFillOperatorInfo* pInfo) { + blockDataCleanup(pInfo->pPrevSrcBlock); + tSimpleHashClear(pInfo->pFillSup->pResMap); + pInfo->pFillSup->hasDelete = false; + taosArrayClear(pInfo->pFillInfo->delRanges); + pInfo->pFillInfo->delIndex = 0; +} + +static void doApplyStreamScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pSrcBlock, SSDataBlock* pDstBlock) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExprSupp* pSup = &pOperator->exprSupp; + + blockDataCleanup(pDstBlock); + blockDataEnsureCapacity(pDstBlock, pSrcBlock->info.rows); + setInputDataBlock(pOperator, pSup->pCtx, pSrcBlock, TSDB_ORDER_ASC, MAIN_SCAN, false); + projectApplyFunctions(pSup->pExprInfo, pDstBlock, pSrcBlock, pSup->pCtx, pSup->numOfExprs, NULL); + pDstBlock->info.groupId = pSrcBlock->info.groupId; + + SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, pInfo->primaryTsCol); + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, pInfo->primarySrcSlotId); + colDataAssign(pDst, pSrc, pDstBlock->info.rows, &pDstBlock->info); + + int32_t numOfNotFill = pInfo->pFillSup->numOfAllCols - pInfo->pFillSup->numOfFillCols; + for (int32_t i = 0; i < numOfNotFill; ++i) { + SFillColInfo* pCol = &pInfo->pFillSup->pAllColInfo[i + pInfo->pFillSup->numOfFillCols]; + ASSERT(pCol->notFillCol); + + SExprInfo* pExpr = pCol->pExpr; + int32_t srcSlotId = pExpr->base.pParam[0].pCol->slotId; + int32_t dstSlotId = pExpr->base.resSchema.slotId; + + SColumnInfoData* pDst1 = taosArrayGet(pDstBlock->pDataBlock, dstSlotId); + SColumnInfoData* pSrc1 = taosArrayGet(pSrcBlock->pDataBlock, srcSlotId); + colDataAssign(pDst1, pSrc1, pDstBlock->info.rows, &pDstBlock->info); + } + blockDataUpdateTsWindow(pDstBlock, pInfo->primaryTsCol); +} + +static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + blockDataCleanup(pInfo->pRes); + if (pOperator->status == OP_RES_TO_RETURN) { + if (hasRemainCalc(pInfo->pFillInfo)) { + doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); + if (pInfo->pRes->info.rows > 0) { + return pInfo->pRes; + } + } + doDeleteFillFinalize(pOperator); + if (pInfo->pRes->info.rows > 0) { + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; + } + doSetOperatorCompleted(pOperator); + resetStreamFillInfo(pInfo); + return NULL; + } + + SSDataBlock* fillResult = NULL; + SOperatorInfo* downstream = pOperator->pDownstream[0]; + while (1) { + if (pInfo->srcRowIndex >= pInfo->pSrcBlock->info.rows) { + // If there are delete datablocks, we receive them first. + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + pOperator->status = OP_RES_TO_RETURN; + SSDataBlock* preBlock = pInfo->pPrevSrcBlock; + if (preBlock->info.rows > 0) { + int preRowId = preBlock->info.rows - 1; + SColumnInfoData* pPreTsCol = taosArrayGet(preBlock->pDataBlock, pInfo->primaryTsCol); + doFillResults(pOperator, pInfo->pFillSup, pInfo->pFillInfo, preBlock, (TSKEY*)pPreTsCol->pData, preRowId, + pInfo->pRes); + } + pInfo->pFillInfo->preRowKey = INT64_MIN; + if (pInfo->pRes->info.rows > 0) { + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; + } + break; + } + printDataBlock(pBlock, "stream fill recv"); + + switch (pBlock->info.type) { + case STREAM_RETRIEVE: + return pBlock; + case STREAM_DELETE_RESULT: { + pInfo->pSrcDelBlock = pBlock; + pInfo->srcDelRowIndex = 0; + blockDataCleanup(pInfo->pDelRes); + pInfo->pFillSup->hasDelete = true; + doDeleteFillResult(pOperator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "stream fill delete"); + return pInfo->pDelRes; + } + continue; + } break; + case STREAM_NORMAL: + case STREAM_INVALID: { + doApplyStreamScalarCalculation(pOperator, pBlock, pInfo->pSrcBlock); + pInfo->srcRowIndex = 0; + } break; + default: + ASSERT(0); + break; + } + } + + doStreamFillImpl(pOperator); + doFilter(pInfo->pCondition, pInfo->pRes, pInfo->pColMatchColInfo); + pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; + if (pInfo->pRes->info.rows > 0) { + break; + } + } + if (pOperator->status == OP_RES_TO_RETURN) { + doDeleteFillFinalize(pOperator); + } + + if (pInfo->pRes->info.rows == 0) { + doSetOperatorCompleted(pOperator); + resetStreamFillInfo(pInfo); + return NULL; + } + + pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; +} + +static int32_t initResultBuf(SStreamFillSupporter* pFillSup) { + pFillSup->rowSize = sizeof(SResultCellData) * pFillSup->numOfAllCols; + for (int i = 0; i < pFillSup->numOfAllCols; i++) { + SFillColInfo* pCol = &pFillSup->pAllColInfo[i]; + SResSchema* pSchema = &pCol->pExpr->base.resSchema; + pFillSup->rowSize += pSchema->bytes; + } + pFillSup->next.key = INT64_MIN; + pFillSup->nextNext.key = INT64_MIN; + pFillSup->prev.key = INT64_MIN; + pFillSup->next.pRowVal = NULL; + pFillSup->nextNext.pRowVal = NULL; + pFillSup->prev.pRowVal = NULL; + return TSDB_CODE_SUCCESS; +} + +static SStreamFillSupporter* initStreamFillSup(SStreamFillPhysiNode* pPhyFillNode, SInterval* pInterval, + SExprInfo* pFillExprInfo, int32_t numOfFillCols) { + SStreamFillSupporter* pFillSup = taosMemoryCalloc(1, sizeof(SStreamFillSupporter)); + if (!pFillSup) { + return NULL; + } + pFillSup->numOfFillCols = numOfFillCols; + int32_t numOfNotFillCols = 0; + SExprInfo* pNotFillExprInfo = createExprInfo(pPhyFillNode->pNotFillExprs, NULL, &numOfNotFillCols); + pFillSup->pAllColInfo = createFillColInfo(pFillExprInfo, pFillSup->numOfFillCols, pNotFillExprInfo, numOfNotFillCols, + (const SNodeListNode*)(pPhyFillNode->pValues)); + pFillSup->type = convertFillType(pPhyFillNode->mode); + pFillSup->numOfAllCols = pFillSup->numOfFillCols + numOfNotFillCols; + pFillSup->interval = *pInterval; + + int32_t code = initResultBuf(pFillSup); + if (code != TSDB_CODE_SUCCESS) { + destroyStreamFillSupporter(pFillSup); + return NULL; + } + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pFillSup->pResMap = tSimpleHashInit(16, hashFn); + pFillSup->hasDelete = false; + return pFillSup; +} + +SStreamFillInfo* initStreamFillInfo(SStreamFillSupporter* pFillSup, SSDataBlock* pRes) { + SStreamFillInfo* pFillInfo = taosMemoryCalloc(1, sizeof(SStreamFillInfo)); + pFillInfo->start = INT64_MIN; + pFillInfo->current = INT64_MIN; + pFillInfo->end = INT64_MIN; + pFillInfo->preRowKey = INT64_MIN; + pFillInfo->needFill = false; + pFillInfo->pLinearInfo = taosMemoryCalloc(1, sizeof(SStreamFillLinearInfo)); + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + pFillInfo->pLinearInfo->pDeltaVal = NULL; + pFillInfo->pLinearInfo->pNextDeltaVal = NULL; + if (pFillSup->type == TSDB_FILL_LINEAR) { + pFillInfo->pLinearInfo->pDeltaVal = taosArrayInit(pFillSup->numOfAllCols, sizeof(double)); + pFillInfo->pLinearInfo->pNextDeltaVal = taosArrayInit(pFillSup->numOfAllCols, sizeof(double)); + for (int32_t i = 0; i < pFillSup->numOfAllCols; i++) { + double value = 0.0; + taosArrayPush(pFillInfo->pLinearInfo->pDeltaVal, &value); + taosArrayPush(pFillInfo->pLinearInfo->pNextDeltaVal, &value); + } + } + pFillInfo->pLinearInfo->winIndex = 0; + + pFillInfo->pResRow = NULL; + if (pFillSup->type == TSDB_FILL_SET_VALUE || pFillSup->type == TSDB_FILL_NULL) { + pFillInfo->pResRow = taosMemoryCalloc(1, sizeof(SResultRowData)); + pFillInfo->pResRow->key = INT64_MIN; + pFillInfo->pResRow->pRowVal = taosMemoryCalloc(1, pFillSup->rowSize); + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SColumnInfoData* pColData = taosArrayGet(pRes->pDataBlock, i); + SResultCellData* pCell = getResultCell(pFillInfo->pResRow, i); + pCell->bytes = pColData->info.bytes; + pCell->type = pColData->info.type; + } + } + + pFillInfo->type = pFillSup->type; + pFillInfo->delRanges = taosArrayInit(16, sizeof(STimeRange)); + pFillInfo->delIndex = 0; + return pFillInfo; +} + +SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, + SExecTaskInfo* pTaskInfo) { + SStreamFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamFillOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + SInterval* pInterval = QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL == downstream->operatorType + ? &((SStreamFinalIntervalOperatorInfo*)downstream->info)->interval + : &((SStreamIntervalOperatorInfo*)downstream->info)->interval; + int32_t numOfFillCols = 0; + SExprInfo* pFillExprInfo = createExprInfo(pPhyFillNode->pFillExprs, NULL, &numOfFillCols); + pInfo->pFillSup = initStreamFillSup(pPhyFillNode, pInterval, pFillExprInfo, numOfFillCols); + if (!pInfo->pFillSup) { + goto _error; + } + + SResultInfo* pResultInfo = &pOperator->resultInfo; + initResultSizeInfo(&pOperator->resultInfo, 4096); + pInfo->pRes = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + pInfo->pSrcBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + pInfo->pPrevSrcBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + blockDataEnsureCapacity(pInfo->pSrcBlock, pOperator->resultInfo.capacity); + blockDataEnsureCapacity(pInfo->pPrevSrcBlock, pOperator->resultInfo.capacity); + + pInfo->pFillInfo = initStreamFillInfo(pInfo->pFillSup, pInfo->pRes); + if (!pInfo->pFillInfo) { + goto _error; + } + + if (pInfo->pFillInfo->type == TSDB_FILL_SET_VALUE) { + for (int32_t i = 0; i < pInfo->pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pInfo->pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SResultCellData* pCell = getResultCell(pInfo->pFillInfo->pResRow, slotId); + SVariant* pVar = &(pFillCol->fillVal); + if (pCell->type == TSDB_DATA_TYPE_FLOAT) { + float v = 0; + GET_TYPED_DATA(v, float, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else if (pCell->type == TSDB_DATA_TYPE_DOUBLE) { + double v = 0; + GET_TYPED_DATA(v, double, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else if (IS_SIGNED_NUMERIC_TYPE(pCell->type)) { + int64_t v = 0; + GET_TYPED_DATA(v, int64_t, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else { + pCell->isNull = true; + } + } + } else if (pInfo->pFillInfo->type == TSDB_FILL_NULL) { + for (int32_t i = 0; i < pInfo->pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pInfo->pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SResultCellData* pCell = getResultCell(pInfo->pFillInfo->pResRow, slotId); + pCell->isNull = true; + } + } + + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + blockDataEnsureCapacity(pInfo->pDelRes, pOperator->resultInfo.capacity); + + pInfo->primaryTsCol = ((STargetNode*)pPhyFillNode->pWStartTs)->slotId; + pInfo->primarySrcSlotId = ((SColumnNode*)((STargetNode*)pPhyFillNode->pWStartTs)->pExpr)->slotId; + + int32_t numOfOutputCols = 0; + SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pFillExprs, pPhyFillNode->node.pOutputDataBlockDesc, + &numOfOutputCols, COL_MATCH_FROM_SLOT_ID); + pInfo->pCondition = pPhyFillNode->node.pConditions; + pInfo->pColMatchColInfo = pColMatchColInfo; + initExprSupp(&pOperator->exprSupp, pFillExprInfo, numOfFillCols); + pInfo->srcRowIndex = 0; + + pOperator->name = "FillOperator"; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL; + pOperator->info = pInfo; + pOperator->pTaskInfo = pTaskInfo; + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStreamFill, NULL, NULL, destroyStreamFillOperatorInfo, + NULL, NULL, NULL); + + int32_t code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + return pOperator; + +_error: + destroyStreamFillOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + return NULL; +} diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 4671570802..12d35be0b7 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -271,6 +271,10 @@ static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t o tw->ekey -= 1; } +void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) { + getNextTimeWindow(pInterval, pInterval->precision, order, tw); +} + void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) { SqlFunctionCtx* pCtx = pSup->pCtx; @@ -3146,20 +3150,21 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - if (pInfo->binfo.pRes->info.rows == 0) { - pOperator->status = OP_EXEC_DONE; - if (!IS_FINAL_OP(pInfo)) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamIntervalOperator(pInfo); - qDebug("===stream===clear semi operator"); - } else { - freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); - } - return NULL; + if (pInfo->binfo.pRes->info.rows != 0) { + printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + return pInfo->binfo.pRes; } - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->binfo.pRes; + + doSetOperatorCompleted(pOperator); + if (!IS_FINAL_OP(pInfo)) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamIntervalOperator(pInfo); + qDebug("===stream===clear semi operator"); + } else { + freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); + } + return NULL; } else { if (!IS_FINAL_OP(pInfo)) { doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); @@ -3316,7 +3321,13 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { return pInfo->pPullDataRes; } - // we should send result first. + doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + return pInfo->pDelRes; + } + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pInfo->binfo.pRes->info.rows != 0) { printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); @@ -3330,13 +3341,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { // process the rest of the data return pInfo->pUpdateRes; } - - doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pDelRes; - } return NULL; } @@ -5744,19 +5748,18 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval"); + printDataBlock(pInfo->pDelRes, "single interval delete"); return pInfo->pDelRes; } doBuildResult(pOperator, pInfo->binfo.pRes, &pInfo->groupResInfo); - // doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainResults(&pInfo->groupResInfo)) { - pOperator->status = OP_EXEC_DONE; - qDebug("===stream===single interval is done"); - freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval"); + return pInfo->binfo.pRes; } - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes; + + doSetOperatorCompleted(pOperator); + return NULL; } SOperatorInfo* downstream = pOperator->pDownstream[0]; @@ -5823,24 +5826,24 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { } taosArraySort(pUpdated, resultrowComparAsc); - // new disc buf - // finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, - // pSup->rowEntryInfoOffset); initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); removeDeleteResults(pUpdatedMap, pInfo->pDelWins); taosHashCleanup(pUpdatedMap); + doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval"); + printDataBlock(pInfo->pDelRes, "single interval delete"); return pInfo->pDelRes; } - // doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - // new disc buf doBuildResult(pOperator, pInfo->binfo.pRes, &pInfo->groupResInfo); - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes; + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval"); + return pInfo->binfo.pRes; + } + + return NULL; } void destroyStreamIntervalOperatorInfo(void* param) { diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 78afadb75c..e401a3da7f 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -254,6 +254,7 @@ const char* nodesNodeName(ENodeType type) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return "PhysiStreamSemiInterval"; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return "PhysiFill"; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: return "PhysiSessionWindow"; @@ -4635,6 +4636,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return physiIntervalNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return physiFillNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: @@ -4788,6 +4790,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return jsonToPhysiIntervalNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return jsonToPhysiFillNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 989a4f5925..8d1d332ac7 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -3633,6 +3633,7 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { code = physiIntervalNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: code = physiFillNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: @@ -3770,6 +3771,7 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) { code = msgToPhysiIntervalNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: code = msgToPhysiFillNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 71e53bd9be..f8dda501e9 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -511,6 +511,7 @@ SNode* nodesMakeNode(ENodeType type) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return makeNode(type, sizeof(SStreamSemiIntervalPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return makeNode(type, sizeof(SFillPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: return makeNode(type, sizeof(SSessionWinodwPhysiNode)); @@ -1156,7 +1157,8 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode); break; - case QUERY_NODE_PHYSICAL_PLAN_FILL: { + case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: { SFillPhysiNode* pPhyNode = (SFillPhysiNode*)pNode; destroyPhysiNode((SPhysiNode*)pPhyNode); nodesDestroyList(pPhyNode->pFillExprs); diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 421da8f110..810b82b9fc 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1409,7 +1409,9 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SFillLogicNode* pFillNode, SPhysiNode** pPhyNode) { - SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pFillNode, QUERY_NODE_PHYSICAL_PLAN_FILL); + SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode( + pCxt, (SLogicNode*)pFillNode, + pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL : QUERY_NODE_PHYSICAL_PLAN_FILL); if (NULL == pFill) { return TSDB_CODE_OUT_OF_MEMORY; } diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index fde8bca77b..7f3e155a70 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -40,6 +40,11 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) { goto _err; } + // todo refactor + if (tdbTbOpen("func.state.db", sizeof(SWinKey), -1, SWinKeyCmpr, pState->db, &pState->pFillStateDb) < 0) { + goto _err; + } + if (tdbTbOpen("func.state.db", sizeof(STupleKey), -1, STupleKeyCmpr, pState->db, &pState->pFuncStateDb) < 0) { goto _err; } @@ -55,6 +60,7 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) { _err: tdbTbClose(pState->pStateDb); tdbTbClose(pState->pFuncStateDb); + tdbTbClose(pState->pFillStateDb); tdbClose(pState->db); taosMemoryFree(pState); return NULL; @@ -64,6 +70,7 @@ void streamStateClose(SStreamState* pState) { tdbCommit(pState->db, &pState->txn); tdbTbClose(pState->pStateDb); tdbTbClose(pState->pFuncStateDb); + tdbTbClose(pState->pFillStateDb); tdbClose(pState->db); taosMemoryFree(pState); @@ -126,14 +133,30 @@ int32_t streamStateFuncDel(SStreamState* pState, const STupleKey* key) { int32_t streamStatePut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen) { return tdbTbUpsert(pState->pStateDb, key, sizeof(SWinKey), value, vLen, &pState->txn); } + +// todo refactor +int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen) { + return tdbTbUpsert(pState->pFillStateDb, key, sizeof(SWinKey), value, vLen, &pState->txn); +} + int32_t streamStateGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { return tdbTbGet(pState->pStateDb, key, sizeof(SWinKey), pVal, pVLen); } +// todo refactor +int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { + return tdbTbGet(pState->pFillStateDb, key, sizeof(SWinKey), pVal, pVLen); +} + int32_t streamStateDel(SStreamState* pState, const SWinKey* key) { return tdbTbDelete(pState->pStateDb, key, sizeof(SWinKey), &pState->txn); } +// todo refactor +int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key) { + return tdbTbDelete(pState->pFillStateDb, key, sizeof(SWinKey), &pState->txn); +} + int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { // todo refactor int32_t size = *pVLen; @@ -165,6 +188,31 @@ SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key) { return pCur; } +SStreamStateCur* streamStateFillGetCur(SStreamState* pState, const SWinKey* key) { + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + if (pCur == NULL) return NULL; + tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL); + + int32_t c; + tdbTbcMoveTo(pCur->pCur, key, sizeof(SWinKey), &c); + if (c != 0) { + taosMemoryFree(pCur); + return NULL; + } + return pCur; +} + +SStreamStateCur* streamStateGetAndCheckCur(SStreamState* pState, SWinKey* key) { + SStreamStateCur* pCur = streamStateFillGetCur(pState, key); + if (pCur) { + int32_t code = streamStateGetGroupKVByCur(pCur, key, NULL, 0); + if (code == 0) { + return pCur; + } + } + return NULL; +} + int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen) { const SWinKey* pKTmp = NULL; int32_t kLen; @@ -175,6 +223,17 @@ int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** return 0; } +int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen) { + uint64_t groupId = pKey->groupId; + int32_t code = streamStateGetKVByCur(pCur, pKey, pVal, pVLen); + if (code == 0) { + if (pKey->groupId == groupId) { + return 0; + } + } + return -1; +} + int32_t streamStateSeekFirst(SStreamState* pState, SStreamStateCur* pCur) { // return tdbTbcMoveToFirst(pCur->pCur); @@ -185,12 +244,12 @@ int32_t streamStateSeekLast(SStreamState* pState, SStreamStateCur* pCur) { return tdbTbcMoveToLast(pCur->pCur); } -SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key) { +SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey* key) { SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - if (tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL) < 0) { + if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) { taosMemoryFree(pCur); return NULL; } @@ -211,12 +270,12 @@ SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key return pCur; } -SStreamStateCur* streamStateSeekKeyPrev(SStreamState* pState, const SWinKey* key) { +SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey* key) { SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - if (tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL) < 0) { + if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) { taosMemoryFree(pCur); return NULL; } diff --git a/tests/script/tsim/stream/deleteInterval.sim b/tests/script/tsim/stream/deleteInterval.sim index 00d10afad9..7532b2d5de 100644 --- a/tests/script/tsim/stream/deleteInterval.sim +++ b/tests/script/tsim/stream/deleteInterval.sim @@ -413,13 +413,8 @@ if $data12 != 3 then goto loop14 endi -return 1 -sql drop stream if exists streams3; -sql drop database if exists test3; -sql drop database if exists test; sql create database test3 vgroups 4; -sql create database test vgroups 1; sql use test3; sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); sql create table t1 using st tags(1,1,1); @@ -435,7 +430,7 @@ sql delete from t1; loop15: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -453,7 +448,7 @@ sql delete from t1 where ts > 100; loop16: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -471,7 +466,7 @@ sql delete from st; loop17: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then diff --git a/tests/script/tsim/stream/fillIntervalDelete0.sim b/tests/script/tsim/stream/fillIntervalDelete0.sim new file mode 100644 index 0000000000..77d09d5ae8 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalDelete0.sim @@ -0,0 +1,375 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791213000,1,1,1,1.0,'aaa'); +sleep 200 + +$loop_count = 0 + +loop0: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows=$rows + goto loop0 +endi + +sql delete from t1; + +$loop_count = 0 + +loop1: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 0 then + print =====rows1=$rows + goto loop1 +endi + +sql select * from streamt2 order by ts; + +if $rows != 0 then + print =====rows2=$rows + goto loop1 +endi + +sql select * from streamt3 order by ts; + +if $rows != 0 then + print =====rows3=$rows + goto loop1 +endi + +sql select * from streamt4 order by ts; + +if $rows != 0 then + print =====rows4=$rows + goto loop1 +endi + +sql select * from streamt5 order by ts; + +if $rows != 0 then + print =====rows5=$rows + goto loop1 +endi + +sql insert into t1 values(1648791210000,4,4,4,4.0,'ddd'); +sql insert into t1 values(1648791215000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791217000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791219000,5,5,5,5.0,'eee'); + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 10 then + print =====rows=$rows + goto loop2 +endi + +#temp +system sh/stop_dnodes.sh +return 1 + +sql delete from t1 where ts >= 1648791214000; + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows1=$rows + goto loop3 +endi + +sql select * from streamt2 order by ts; + +if $rows != 1 then + print =====rows2=$rows + goto loop3 +endi + +sql select * from streamt3 order by ts; + +if $rows != 1 then + print =====rows3=$rows + goto loop3 +endi + +sql select * from streamt4 order by ts; + +if $rows != 1 then + print =====rows4=$rows + goto loop3 +endi + +sql select * from streamt5 order by ts; + +if $rows != 1 then + print =====rows5=$rows + goto loop3 +endi + +if $data01 != 4 then + print =====data01=$data01 + return -1 +endi + + + +sql insert into t1 values(1648791213000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791219000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop4: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 4 then + print =====rows=$rows + goto loop4 +endi + + +sql delete from t1 where ts <= 1648791216000; + +$loop_count = 0 + +loop5: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows1=$rows + goto loop5 +endi + +sql select * from streamt2 order by ts; + +if $rows != 1 then + print =====rows2=$rows + goto loop5 +endi + +sql select * from streamt3 order by ts; + +if $rows != 1 then + print =====rows3=$rows + goto loop5 +endi + +sql select * from streamt4 order by ts; + +if $rows != 1 then + print =====rows4=$rows + goto loop5 +endi + +sql select * from streamt5 order by ts; + +if $rows != 1 then + print =====rows5=$rows + goto loop5 +endi + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi + + + + +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; +sql drop database if exists test6; +sql create database test6 vgroups 1; +sql use test6; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(1,1,1); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams9 trigger at_once into streamt9 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams10 trigger at_once into streamt10 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,1,1,1,1.0,'aaa'); + +sql insert into t2 values(1648791215000,1,1,1,1.0,'aaa'); + +sleep 200 + +$loop_count = 0 + +loop7: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 8 then + print =====rows=$rows + goto loop7 +endi + +sql delete from t1; + +$loop_count = 0 + +loop8: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 0 then + print =====rows6=$rows + goto loop8 +endi + +sql select * from streamt7 order by ts; + +if $rows != 0 then + print =====rows7=$rows + goto loop8 +endi + +sql select * from streamt8 order by ts; + +if $rows != 0 then + print =====rows8=$rows + goto loop8 +endi + +sql select * from streamt9 order by ts; + +if $rows != 0 then + print =====rows9=$rows + goto loop8 +endi + +sql select * from streamt10 order by ts; + +if $rows != 0 then + print =====rows10=$rows + goto loop8 +endi + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalDelete1.sim b/tests/script/tsim/stream/fillIntervalDelete1.sim new file mode 100644 index 0000000000..8e6972975e --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalDelete1.sim @@ -0,0 +1,379 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,0,0,0,0.0,'aaa'); +sql insert into t1 values(1648791213000,1,1,1,1.0,'bbb'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'ccc'); +sql insert into t1 values(1648791217000,6,6,6,6.0,'ddd'); + +$loop_count = 0 + +loop0: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print =====rows=$rows + goto loop0 +endi + + +sql delete from t1 where ts = 1648791213000; + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print ====streamt1=rows1=$rows + goto loop2 +endi +if $data31 != NULL then + print ====streamt1=data31=$data31 + goto loop2 +endi + +sql select * from streamt2 order by ts; + +if $rows != 8 then + print ====streamt2=rows2=$rows + goto loop2 +endi +if $data31 != 100 then + print ====streamt2=data31=$data31 + goto loop2 +endi + +sql select * from streamt3 order by ts; + +if $rows != 8 then + print ====streamt3=rows3=$rows + goto loop2 +endi +if $data31 != 5 then + print ====streamt3=data31=$data31 + goto loop2 +endi + +sql select * from streamt4 order by ts; + +if $rows != 8 then + print ====streamt4=rows4=$rows + goto loop2 +endi +if $data31 != 0 then + print ====streamt4=data31=$data31 + goto loop2 +endi + +sql select * from streamt5 order by ts; + +if $rows != 8 then + print ====streamt5=rows5=$rows + goto loop2 +endi +if $data31 != 3 then + print ====streamt5=data31=$data31 + goto loop2 +endi + + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791213000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $data21 != 5 then + print ====133=rows=$rows + goto loop3 +endi +if $data31 != 6 then + print ====137=rows=$rows + goto loop3 +endi + + +sql delete from t1 where ts >= 1648791211000 and ts <= 1648791214000; + +$loop_count = 0 + +loop4: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print ====streamt1=rows1=$rows + goto loop4 +endi +if $data31 != NULL then + print ====streamt1=data31=$data31 + goto loop4 +endi + +sql select * from streamt2 order by ts; + +if $rows != 8 then + print ====streamt2=rows2=$rows + goto loop4 +endi +if $data31 != 100 then + print ====streamt2=data31=$data31 + goto loop4 +endi + +sql select * from streamt3 order by ts; + +if $rows != 8 then + print ====streamt3=rows3=$rows + goto loop4 +endi +if $data31 != 5 then + print ====streamt3=data31=$data31 + goto loop4 +endi + +sql select * from streamt4 order by ts; + +if $rows != 8 then + print ====streamt4=rows4=$rows + goto loop4 +endi +if $data31 != 0 then + print ====streamt4=data31=$data31 + goto loop4 +endi + +sql select * from streamt5 order by ts; + +if $rows != 8 then + print ====streamt5=rows5=$rows + goto loop4 +endi +if $data31 != 3 then + print ====streamt5=data31=$data31 + goto loop4 +endi + + + +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; +sql drop database if exists test6; +sql create database test6 vgroups 1; +sql use test6; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(1,1,1); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams9 trigger at_once into streamt9 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams10 trigger at_once into streamt10 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791215000,6,8,8,8.0,'bbb'); +sql insert into t1 values(1648791220000,11,10,10,10.0,'ccc'); +sql insert into t1 values(1648791221000,6,6,6,6.0,'fff'); + +sql insert into t2 values(1648791212000,4,4,4,4.0,'ddd'); +sql insert into t2 values(1648791214000,5,5,5,5.0,'eee'); +sql insert into t2 values(1648791216000,2,2,2,2.0,'bbb'); +sql insert into t2 values(1648791222000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop5: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 13 then + print ====streamt6=rows1=$rows + goto loop5 +endi +if $data21 != 4 then + print ====streamt6=data21=$data21 + goto loop5 +endi + +sql delete from t2; +print delete from t2; + +$loop_count = 0 + +loop6: + +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 12 then + print ====streamt6=rows2=$rows + goto loop6 +endi +if $data31 != NULL then + print ====streamt6=data31=$data31 + goto loop6 +endi + + +sql select * from streamt7 order by ts; + +if $rows != 12 then + print ====streamt7=rows2=$rows + goto loop6 +endi +if $data31 != 100 then + print ====streamt7=data31=$data31 + goto loop6 +endi + +sql select * from streamt8 order by ts; + +if $rows != 12 then + print ====streamt8=rows3=$rows + goto loop6 +endi +if $data31 != 6 then + print ====streamt8=data31=$data31 + goto loop6 +endi + +sql select * from streamt9 order by ts; + +if $rows != 12 then + print ====streamt9=rows4=$rows + goto loop6 +endi +if $data31 != 1 then + print ====streamt9=data31=$data31 + goto loop6 +endi + +sql select * from streamt10 order by ts; + +if $rows != 12 then + print ====streamt10=rows5=$rows + goto loop6 +endi +if $data21 != 3 then + print ====streamt10=data21=$data21 + return -1 +endi +if $data31 != 4 then + print ====streamt10=data31=$data31 + return -1 +endi +if $data71 != 8 then + print ====streamt10=data71=$data71 + return -1 +endi +if $data91 != 10 then + print ====streamt10=data91=$data91 + return -1 +endi + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalLinear.sim b/tests/script/tsim/stream/fillIntervalLinear.sim new file mode 100644 index 0000000000..46ff785fd3 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalLinear.sim @@ -0,0 +1,695 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a)+sum(c), avg(b), first(s), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791216000,5,5,5,5.0,'bbb'); +sql insert into t1 values(1648791210000,1,1,1,1.0,'ccc') (1648791219000,2,2,2,2.0,'ddd') (1648791222000,3,3,3,3.0,'eee'); + + +$loop_count = 0 + +loop1: +sleep 200 +sql use test1; +sql select * from streamt1 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 13 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 2.000000000 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi +if $data04 != 1 then + print =====data04=$data04 + return -1 +endi + + +if $data11 != 4.000000000 then + print =====data11=$data11 + return -1 +endi +if $data12 != 2.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 6.000000000 then + print =====data21=$data21 + return -1 +endi +if $data22 != 3.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != NULL then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 8.000000000 then + print =====data31=$data31 + return -1 +endi +if $data32 != 4.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != aaa then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 8.666666667 then + print =====data41=$data41 + return -1 +endi +if $data42 != 4.333333333 then + print =====data42=$data42 + return -1 +endi +if $data43 != NULL then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 9.333333333 then + print =====data01=$data01 + return -1 +endi +if $data52 != 4.666666667 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 10.000000000 then + print =====data61=$data61 + return -1 +endi +if $data62 != 5.000000000 then + print =====data62=$data62 + return -1 +endi + + +if $data71 != 8.000000000 then + print =====data71=$data71 + return -1 +endi +if $data72 != 4.000000000 then + print =====data72=$data72 + return -1 +endi + + +if $data81 != 6.000000000 then + print =====data81=$data81 + return -1 +endi +if $data82 != 3.000000000 then + print =====data82=$data82 + return -1 +endi + + +if $data91 != 4.000000000 then + print =====data91=$data91 + return -1 +endi +if $data92 != 2.000000000 then + print =====data92=$data92 + return -1 +endi + +if $data[10][1] != 4.666666667 then + print =====data[10][1]=$data[10][1] + return -1 +endi +if $data[10][2] != 2.333333333 then + print =====data[10][2]=$data[10][2] + return -1 +endi + + +if $data[11][1] != 5.333333333 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 2.666666667 then + print =====data[11][2]=$data[11][2] + return -1 +endi + + +if $data[12][1] != 6.000000000 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 3.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi + + + +sql drop stream if exists streams2; +sql drop database if exists test2; +sql create database test2 vgroups 1; +sql use test2; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a)+sum(c), avg(b), first(s), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791210000,1,1,1,1.0,'ccc') (1648791219000,2,2,2,2.0,'ddd') (1648791222000,3,3,3,3.0,'eee'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791216000,5,5,5,5.0,'bbb'); + + +$loop_count = 0 + +loop2: + +sleep 200 + +sql select * from streamt2 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 13 then + print =====rows=$rows + goto loop2 +endi + +if $data01 != 2.000000000 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi +if $data04 != 1 then + print =====data04=$data04 + return -1 +endi + + +if $data11 != 4.000000000 then + print =====data11=$data11 + return -1 +endi +if $data12 != 2.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 6.000000000 then + print =====data21=$data21 + return -1 +endi +if $data22 != 3.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != NULL then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 8.000000000 then + print =====data31=$data31 + return -1 +endi +if $data32 != 4.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != aaa then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 8.666666667 then + print =====data41=$data41 + return -1 +endi +if $data42 != 4.333333333 then + print =====data42=$data42 + return -1 +endi +if $data43 != NULL then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 9.333333333 then + print =====data01=$data01 + return -1 +endi +if $data52 != 4.666666667 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 10.000000000 then + print =====data61=$data61 + return -1 +endi +if $data62 != 5.000000000 then + print =====data62=$data62 + return -1 +endi + + +if $data71 != 8.000000000 then + print =====data71=$data71 + return -1 +endi +if $data72 != 4.000000000 then + print =====data72=$data72 + return -1 +endi + + +if $data81 != 6.000000000 then + print =====data81=$data81 + return -1 +endi +if $data82 != 3.000000000 then + print =====data82=$data82 + return -1 +endi + + +if $data91 != 4.000000000 then + print =====data91=$data91 + return -1 +endi +if $data92 != 2.000000000 then + print =====data92=$data92 + return -1 +endi + +if $data[10][1] != 4.666666667 then + print =====data[10][1]=$data[10][1] + return -1 +endi +if $data[10][2] != 2.333333333 then + print =====data[10][2]=$data[10][2] + return -1 +endi + + +if $data[11][1] != 5.333333333 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 2.666666667 then + print =====data[11][2]=$data[11][2] + return -1 +endi + + +if $data[12][1] != 6.000000000 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 3.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi + + + +sql drop stream if exists streams3; +sql drop database if exists test3; +sql create database test3 vgroups 1; +sql use test3; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), b+c, s, b+1, 1 from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791215000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791211000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'ddd'); + + +$loop_count = 0 + +loop3: +sleep 300 +sql select * from streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 7 then + print =====rows=$rows + goto loop3 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 6.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi + +if $data11 != 3 then + print =====data11=$data11 + return -1 +endi +if $data12 != 7.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 8.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ddd then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 2 then + print =====data31=$data31 + return -1 +endi +if $data32 != 5.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != NULL then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 2.000000000 then + print =====data42=$data42 + return -1 +endi +if $data43 != aaa then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 1 then + print =====data51=$data51 + return -1 +endi +if $data52 != 3.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 4.000000000 then + print =====data62=$data62 + return -1 +endi +if $data63 != bbb then + print =====data63=$data63 + return -1 +endi + + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791207000,6,6,6,6.0,'fff') (1648791209000,7,7,7,7.0,'ggg') (1648791219000,8,8,8,8.0,'hhh') (1648791221000,9,9,9,9.0,'iii'); + + + +$loop_count = 0 + +loop4: + +sleep 200 + +sql select * from test3.streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 15 then + print =====rows=$rows + goto loop4 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 12.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != fff then + print =====data03=$data03 + return -1 +endi + +if $data11 != 6 then + print =====data11=$data11 + return -1 +endi +if $data12 != 13.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data22 != 14.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ggg then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 5 then + print =====data31=$data31 + return -1 +endi +if $data32 != 10.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != NULL then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data52 != 10.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != eee then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 5 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 10.000000000 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != NULL then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 16.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi +if $data[12][3] != hhh then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 8 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][2] != 17.000000000 then + print =====data[13][2]=$data[13][2] + return -1 +endi +if $data[13][3] != NULL then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][2] != 18.000000000 then + print =====data[14][2]=$data[14][2] + return -1 +endi +if $data[14][3] != iii then + print =====data[14][3]=$data[14][3] + return -1 +endi + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalPartitionBy.sim b/tests/script/tsim/stream/fillIntervalPartitionBy.sim new file mode 100644 index 0000000000..384aa2c8e4 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalPartitionBy.sim @@ -0,0 +1,171 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,0,0,0,0.0,'aaa'); +sql insert into t1 values(1648791213000,1,1,1,1.0,'bbb'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'ccc'); +sql insert into t1 values(1648791216000,6,6,6,6.0,'ddd'); +sql insert into t2 values(1648791210000,7,0,0,0.0,'aaa'); +sql insert into t2 values(1648791213000,8,1,1,1.0,'bbb'); +sql insert into t2 values(1648791215000,9,5,5,5.0,'ccc'); +sql insert into t2 values(1648791216000,10,6,6,6.0,'ddd'); + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +sql select * from streamt1 order by group_id, ts; + +if $rows != 14 then + print ====streamt1=rows1=$rows + goto loop2 +endi + +sql select * from streamt2 order by group_id, ts; + +if $rows != 14 then + print ====streamt2=rows2=$rows + goto loop2 +endi + +sql select * from streamt3 order by group_id, ts; + +if $rows != 14 then + print ====streamt3=rows3=$rows + goto loop2 +endi + +sql select * from streamt4 order by group_id, ts; + +if $rows != 14 then + print ====streamt4=rows4=$rows + goto loop2 +endi + +sql select * from streamt5 order by group_id, ts; + +if $rows != 14 then + print ====streamt5=rows5=$rows + goto loop2 +endi + +sql delete from t1 where ts = 1648791216000; +print ======delete from t1 where ts = 1648791216000; + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by group_id, ts; + +if $rows != 13 then + print ====streamt1=rows1=$rows + goto loop3 +endi + +sql select * from streamt2 order by group_id, ts; + +if $rows != 13 then + print ====streamt2=rows2=$rows + goto loop3 +endi + +sql select * from streamt3 order by group_id, ts; + +if $rows != 13 then + print ====streamt3=rows3=$rows + goto loop3 +endi + +sql select * from streamt4 order by group_id, ts; + +if $rows != 13 then + print ====streamt4=rows4=$rows + goto loop3 +endi + +sql select * from streamt5 order by group_id, ts; + +if $rows != 13 then + print ====streamt5=rows5=$rows + goto loop3 +endi + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalPrevNext.sim b/tests/script/tsim/stream/fillIntervalPrevNext.sim new file mode 100644 index 0000000000..5eab5fdac1 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalPrevNext.sim @@ -0,0 +1,1036 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, count(*) c1, max(a)+min(c), avg(b) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); + + +$loop_count = 0 + +loop1: +sleep 200 +sql use test1; +sql select * from streamt1 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi + + +if $data11 != 1 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 2.000000000 then + print =====data12=$data12 + goto loop1 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi + + +if $data31 != 1 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 8.000000000 then + print =====data32=$data32 + goto loop1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop1 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi + + +if $data51 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data52 != 10.000000000 then + print =====data52=$data52 + goto loop1 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop1 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop1 +endi + +if $data72 != 4.000000000 then + print =====data72=$data72 + goto loop1 +endi + + +if $data81 != 1 then + print =====data81=$data81 + goto loop1 +endi + +if $data82 != 4.000000000 then + print =====data82=$data82 + goto loop1 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop1 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop1 +endi + +sql use test1; +sql select * from streamt2 order by ts; + +print next----------------------151 + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi +if $data03 != 1.000000000 then + print =====data03=$data03 + goto loop1 +endi + +if $data12 != 8.000000000 then + print =====data12=$data12 + goto loop1 +endi +if $data13 != 4.000000000 then + print =====data13=$data13 + goto loop1 +endi + + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi +if $data23 != 4.000000000 then + print =====data23=$data23 + goto loop1 +endi + + +if $data32 != 10.000000000 then + print =====data32=$data32 + goto loop1 +endi +if $data33 != 5.000000000 then + print =====data33=$data33 + goto loop1 +endi + + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi +if $data43 != 5.000000000 then + print =====data43=$data43 + goto loop1 +endi + + +if $data52 != 4.000000000 then + print =====data52=$data52 + goto loop1 +endi +if $data53 != 2.000000000 then + print =====data53=$data53 + goto loop1 +endi + + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi +if $data63 != 2.000000000 then + print =====data63=$data63 + goto loop1 +endi + + +if $data72 != 6.000000000 then + print =====data72=$data72 + return -1 +endi +if $data73 != 3.000000000 then + print =====data73=$data73 + return -1 +endi + + +if $data82 != 6.000000000 then + print =====data82=$data82 + return -1 +endi +if $data83 != 3.000000000 then + print =====data83=$data83 + return -1 +endi + + +if $data92 != 6.000000000 then + print =====data92=$data92 + return -1 +endi +if $data93 != 3.000000000 then + print =====data93=$data93 + return -1 +endi + + + +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop database if exists test5; +sql create database test5 vgroups 1; +sql use test5; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, count(*) c1, max(a)+min(c), avg(b) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); + +$loop_count = 0 + +loop5: +sleep 200 +sql select * from streamt5 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop5 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop5 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop5 +endi + + +if $data11 != 1 then + print =====data11=$data11 + goto loop5 +endi + +if $data12 != 2.000000000 then + print =====data12=$data12 + goto loop5 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop5 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop5 +endi + + +if $data31 != 1 then + print =====data31=$data31 + goto loop5 +endi + +if $data32 != 8.000000000 then + print =====data32=$data32 + goto loop5 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop5 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop5 +endi + + +if $data51 != 1 then + print =====data01=$data01 + goto loop5 +endi + +if $data52 != 10.000000000 then + print =====data52=$data52 + goto loop5 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop5 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop5 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop5 +endi + +if $data72 != 4.000000000 then + print =====data72=$data72 + goto loop5 +endi + + +if $data81 != 1 then + print =====data81=$data81 + goto loop5 +endi + +if $data82 != 4.000000000 then + print =====data82=$data82 + goto loop5 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop5 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop5 +endi + + +$loop_count = 0 + +loop6: + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sleep 200 + +sql select * from streamt6 order by ts; + +if $rows != 10 then + print =====rows=$rows + goto loop6 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop6 +endi +if $data03 != 1.000000000 then + print =====data03=$data03 + goto loop6 +endi + +if $data12 != 8.000000000 then + print =====data12=$data12 + goto loop6 +endi +if $data13 != 4.000000000 then + print =====data13=$data13 + goto loop6 +endi + + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop6 +endi +if $data23 != 4.000000000 then + print =====data23=$data23 + goto loop6 +endi + + +if $data32 != 10.000000000 then + print =====data32=$data32 + goto loop6 +endi +if $data33 != 5.000000000 then + print =====data33=$data33 + goto loop6 +endi + + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop6 +endi +if $data43 != 5.000000000 then + print =====data43=$data43 + goto loop6 +endi + + +if $data52 != 4.000000000 then + print =====data52=$data52 + goto loop6 +endi +if $data53 != 2.000000000 then + print =====data53=$data53 + goto loop6 +endi + + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop6 +endi +if $data63 != 2.000000000 then + print =====data63=$data63 + goto loop6 +endi + + +if $data72 != 6.000000000 then + print =====data72=$data72 + return -1 +endi +if $data73 != 3.000000000 then + print =====data73=$data73 + return -1 +endi + + +if $data82 != 6.000000000 then + print =====data82=$data82 + return -1 +endi +if $data83 != 3.000000000 then + print =====data83=$data83 + return -1 +endi + + +if $data92 != 6.000000000 then + print =====data92=$data92 + return -1 +endi +if $data93 != 3.000000000 then + print =====data93=$data93 + return -1 +endi + + + +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop database if exists test7; +sql create database test7 vgroups 1; +sql use test7; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), b+c, s from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), 1, b+1 from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791215000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791211000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'ddd'); + + +$loop_count = 0 + +loop7: +sleep 300 +sql select * from streamt7 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 7 then + print =====rows=$rows + goto loop7 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 6.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi + +if $data11 != 3 then + print =====data11=$data11 + return -1 +endi +if $data12 != 6.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != ccc then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 8.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ddd then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 4 then + print =====data31=$data31 + return -1 +endi +if $data32 != 8.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != ddd then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 2.000000000 then + print =====data42=$data42 + return -1 +endi +if $data43 != aaa then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 1 then + print =====data51=$data51 + return -1 +endi +if $data52 != 2.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != aaa then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 4.000000000 then + print =====data62=$data62 + return -1 +endi +if $data63 != bbb then + print =====data63=$data63 + return -1 +endi + +#-------------- + +sleep 200 +sql select * from streamt8 order by ts; + + +if $rows != 7 then + print =====rows=$rows + return -1 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1 then + print =====data02=$data02 + return -1 +endi +if $data03 != 4.000000000 then + print =====data03=$data03 + return -1 +endi + +if $data11 != 4 then + print =====data11=$data11 + return -1 +endi +if $data12 != 1 then + print =====data12=$data12 + return -1 +endi +if $data13 != 5.000000000 then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 1 then + print =====data22=$data22 + return -1 +endi +if $data23 != 5.000000000 then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 1 then + print =====data31=$data31 + return -1 +endi +if $data32 != 1 then + print =====data32=$data32 + return -1 +endi +if $data33 != 2.000000000 then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 1 then + print =====data42=$data42 + return -1 +endi +if $data43 != 2.000000000 then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 2 then + print =====data51=$data51 + return -1 +endi +if $data52 != 1 then + print =====data52=$data52 + return -1 +endi +if $data53 != 3.000000000 then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 1 then + print =====data62=$data62 + return -1 +endi +if $data63 != 3.000000000 then + print =====data63=$data63 + return -1 +endi + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791207000,6,6,6,6.0,'fff') (1648791209000,7,7,7,7.0,'ggg') (1648791219000,8,8,8,8.0,'hhh') (1648791221000,9,9,9,9.0,'iii'); + + + +$loop_count = 0 + +loop8: +sleep 200 +sql select * from streamt7 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 15 then + print =====rows=$rows + goto loop8 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 12.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != fff then + print =====data03=$data03 + return -1 +endi + +if $data11 != 6 then + print =====data11=$data11 + return -1 +endi +if $data12 != 12.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != fff then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data22 != 14.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ggg then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 7 then + print =====data31=$data31 + return -1 +endi +if $data32 != 14.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != ggg then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data52 != 10.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != eee then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 2 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 4.000000000 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != bbb then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 16.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi +if $data[12][3] != hhh then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 8 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][2] != 16.000000000 then + print =====data[13][2]=$data[13][2] + return -1 +endi +if $data[13][3] != hhh then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][2] != 18.000000000 then + print =====data[14][2]=$data[14][2] + return -1 +endi +if $data[14][3] != iii then + print =====data[14][3]=$data[14][3] + return -1 +endi + +print fill next-----------------890 +sql use test7; +sql select * from streamt8 order by ts; + +if $rows != 15 then + print =====rows=$rows + goto loop8 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1 then + print =====data02=$data02 + return -1 +endi +if $data03 != 7.000000000 then + print =====data03=$data03 + return -1 +endi + +if $data11 != 7 then + print =====data11=$data11 + return -1 +endi +if $data13 != 8.000000000 then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data23 != 8.000000000 then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 3 then + print =====data31=$data31 + return -1 +endi +if $data33 != 4.000000000 then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data53 != 6.000000000 then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 8 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 1 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != 9.000000000 then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][3] != 9.000000000 then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 9 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][3] != 10.000000000 then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][3] != 10.000000000 then + print =====data[14][3]=$data[14][3] + return -1 +endi + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalValue.sim b/tests/script/tsim/stream/fillIntervalValue.sim new file mode 100644 index 0000000000..113eae9270 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalValue.sim @@ -0,0 +1,488 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop database if exists test; +sql create database test vgroups 1; +sql use test; + +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20));; +sql create stream streams1 trigger at_once into streamt as select _wstart ts, count(*) c1 from t1 where ts > 1648791210000 and ts < 1648791413000 interval(10s) fill(value, 100); +sql insert into t1 values(1648791213000,1,2,3,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791233000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791223000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791283000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791253000,1,2,3,1.0,'aaa'); + +$loop_count = 0 + +loop0: +sleep 200 +sql select * from streamt order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 8 then + print =====rows=$rows + goto loop0 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +if $data11 != 1 then + print =====data11=$data11 + goto loop0 +endi + +if $data21 != 1 then + print =====data21=$data21 + goto loop0 +endi + +if $data31 != 100 then + print =====data31=$data31 + goto loop0 +endi + +if $data41 != 1 then + print =====data41=$data41 + goto loop0 +endi + +if $data51 != 100 then + print =====data01=$data01 + goto loop0 +endi + +if $data61 != 100 then + print =====data61=$data61 + goto loop0 +endi + +if $data71 != 1 then + print =====data71=$data71 + goto loop0 +endi + +sql drop stream if exists streams2; +sql drop database if exists test2; +sql create database test2 vgroups 1; +sql use test2; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value, 100,200); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); + +$loop_count = 0 + +loop1: +sleep 200 +sql select * from streamt2 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi + + +if $data11 != 100 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 200.000000000 then + print =====data12=$data12 + goto loop1 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi + + +if $data31 != 100 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 200.000000000 then + print =====data32=$data32 + goto loop1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop1 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi + + +if $data51 != 100 then + print =====data01=$data01 + goto loop1 +endi + +if $data52 != 200.000000000 then + print =====data52=$data52 + goto loop1 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop1 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi + + +if $data71 != 100 then + print =====data71=$data71 + goto loop1 +endi + +if $data72 != 200.000000000 then + print =====data72=$data72 + goto loop1 +endi + + +if $data81 != 100 then + print =====data81=$data81 + goto loop1 +endi + +if $data82 != 200.000000000 then + print =====data82=$data82 + goto loop1 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop1 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop1 +endi + +sql drop stream if exists streams3; +sql drop database if exists test3; +sql create database test3 vgroups 1; +sql use test3; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(b), a+b, c from t1 where ts >= 1648791200000 and ts < 1648791261000 interval(10s) sliding(3s) fill(value, 100,200,300); + +sql insert into t1 values(1648791220000,1,1,1,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791260000,1,1,1,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791200000,1,1,1,1.0,'aaa'); + +$loop_count = 0 + +loop3: +sleep 200 +sql select * from streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 23 then + print =====rows=$rows + goto loop3 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop3 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop3 +endi + +if $data03 != 1 then + print =====data03=$data03 + goto loop3 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop3 +endi + +if $data22 != 2.000000000 then + print =====data22=$data22 + goto loop3 +endi + +if $data23 != 1 then + print =====data23=$data23 + goto loop3 +endi + + +if $data31 != 100 then + print =====data31=$data31 + goto loop3 +endi + +if $data32 != 200.000000000 then + print =====data32=$data32 + goto loop3 +endi + +if $data33 != 300 then + print =====data33=$data33 + goto loop3 +endi + +if $data61 != 100 then + print =====data61=$data61 + goto loop3 +endi + +if $data62 != 200.000000000 then + print =====data62=$data62 + goto loop3 +endi + +if $data63 != 300 then + print =====data63=$data63 + goto loop3 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop3 +endi + +if $data72 != 2.000000000 then + print =====data72=$data72 + goto loop3 +endi + +if $data73 != 1 then + print =====data73=$data73 + goto loop3 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop3 +endi + +if $data92 != 2.000000000 then + print =====data92=$data92 + goto loop3 +endi + +if $data93 != 1 then + print =====data93=$data93 + goto loop3 +endi + + +if $data[10][1] != 100 then + print =====data[10][1]=$data[10][1] + goto loop3 +endi + +if $data[10][2] != 200.000000000 then + print =====data[10][2]=$data[10][2] + goto loop3 +endi + +if $data[10][3] != 300 then + print =====data[10][3]=$data[10][3] + goto loop3 +endi + +if $data[19][1] != 100 then + print =====data[19][1]=$data[19][1] + goto loop3 +endi + +if $data[19][2] != 200.000000000 then + print =====data[19][2]=$data[19][2] + goto loop3 +endi + +if $data[19][3] != 300 then + print =====data[19][3]=$data[19][3] + goto loop3 +endi + + +if $data[20][1] != 1 then + print =====data[20][1]=$data[20][1] + goto loop3 +endi + +if $data[20][2] != 2.000000000 then + print =====data[20][2]=$data[20][2] + goto loop3 +endi + +if $data[20][3] != 1 then + print =====data[20][3]=$data[20][3] + goto loop3 +endi + + +if $data[22][1] != 1 then + print =====data[22][1]=$data[22][1] + goto loop3 +endi + +if $data[22][2] != 2.000000000 then + print =====data[22][2]=$data[22][2] + goto loop3 +endi + +if $data[22][3] != 1 then + print =====data[22][3]=$data[22][3] + goto loop3 +endi + + +sql drop stream if exists streams4; +sql drop database if exists test4; +sql create database test4 vgroups 1; +sql use test4; + +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20));; +sql create stream streams4 trigger at_once into streamt4 as select _wstart ts, count(*) c1 from t1 where ts > 1648791210000 and ts < 1648791413000 interval(10s) fill(NULL); +sql insert into t1 values(1648791213000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791233000,1,2,3,1.0,'aaa'); + +$loop_count = 0 + +loop4: +sleep 200 +sql select * from streamt4 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 3 then + print =====rows=$rows + goto loop4 +endi + +if $data11 != NULL then + print =====data11=$data11 + goto loop4 +endi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/partitionby.sim b/tests/script/tsim/stream/partitionby.sim index e5e02c3873..bc2c07b951 100644 --- a/tests/script/tsim/stream/partitionby.sim +++ b/tests/script/tsim/stream/partitionby.sim @@ -5,13 +5,14 @@ sleep 50 sql connect sql create database test vgroups 4; +sql create database test0 vgroups 1; sql use test; sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); +sql create stream stream_t1 trigger at_once into test0.streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); sql insert into ts1 values(1648791213001,1,12,3,1.0); sql insert into ts2 values(1648791213001,1,12,3,1.0); @@ -22,7 +23,7 @@ $loop_count = 0 loop0: sleep 300 -sql select * from streamtST1; +sql select * from test0.streamtST1; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -34,6 +35,29 @@ print =====rows=$rows goto loop0 endi +sql insert into ts1 values(1648791223001,1,12,3,1.0); +sql insert into ts2 values(1648791223001,1,12,3,1.0); + +sql insert into ts3 values(1648791223001,1,12,3,1.0); +sql insert into ts4 values(1648791223001,1,12,3,1.0); +sleep 300 +sql delete from st where ts = 1648791223001; + +loop00: +sleep 300 +sql select * from test0.streamtST1; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 4 then + print =====rows=$rows + goto loop00 +endi + + print =====loop0 sql create database test1 vgroups 1; diff --git a/tests/script/tsim/stream/partitionbyColumnInterval.sim b/tests/script/tsim/stream/partitionbyColumnInterval.sim index 24fdb9c994..fd1d796fdb 100644 --- a/tests/script/tsim/stream/partitionbyColumnInterval.sim +++ b/tests/script/tsim/stream/partitionbyColumnInterval.sim @@ -562,6 +562,53 @@ if $data21 != 1 then goto loop14 endi +sql drop stream if exists streams5; +sql drop database if exists test5; +sql create database test5 vgroups 4; +sql use test5; +sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(2,2,2); +sql create table t4 using st tags(2,2,2); +sql create stream streams5 trigger at_once into test.streamt5 as select _wstart c1, count(*) c2, max(a) c3 from st partition by a interval(10s); + +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t2 values(1648791213000,2,2,3,1.0); +sql insert into t3 values(1648791213000,3,2,3,1.0); +sql insert into t4 values(1648791213000,4,2,3,1.0); + +sql insert into t1 values(1648791223000,1,2,3,1.0); +sql insert into t2 values(1648791223000,2,2,3,1.0); +sql insert into t3 values(1648791223000,3,2,3,1.0); +sql insert into t4 values(1648791223000,4,2,3,1.0); + +sleep 300 + +sql delete from st where ts = 1648791223000; + +sql select * from test.streamt5; + +$loop_count = 0 + +loop15: +sleep 50 +sql select * from test.streamt5 order by c1, c2, c3; + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +if $rows != 4 then + print =====rows=$rows + print =====rows=$rows + print =====rows=$rows +# goto loop15 +endi + + + $loop_all = $loop_all + 1 print ============loop_all=$loop_all