diff --git a/cmake/cmake.version b/cmake/cmake.version
index fcb31adc39..2d86335b3c 100644
--- a/cmake/cmake.version
+++ b/cmake/cmake.version
@@ -2,7 +2,7 @@
IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER})
ELSE ()
- SET(TD_VER_NUMBER "3.0.1.2")
+ SET(TD_VER_NUMBER "3.0.1.3")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)
diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in
index 448c2b99c0..5d2fcf27b2 100644
--- a/cmake/taostools_CMakeLists.txt.in
+++ b/cmake/taostools_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taos-tools
ExternalProject_Add(taos-tools
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
- GIT_TAG f03c09a
+ GIT_TAG 70f5a1c
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md
index 414986d107..a65a2fff63 100644
--- a/docs/en/28-releases/01-tdengine.md
+++ b/docs/en/28-releases/01-tdengine.md
@@ -6,6 +6,10 @@ description: TDengine release history, Release Notes and download links.
import Release from "/components/ReleaseV3";
+## 3.0.1.3
+
+
+
## 3.0.1.2
diff --git a/docs/en/28-releases/02-tools.md b/docs/en/28-releases/02-tools.md
index 086d3adea2..a83723bff7 100644
--- a/docs/en/28-releases/02-tools.md
+++ b/docs/en/28-releases/02-tools.md
@@ -6,6 +6,10 @@ description: taosTools release history, Release Notes, download links.
import Release from "/components/ReleaseV3";
+## 2.2.3
+
+
+
## 2.2.2
diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md
index b05cf7a942..597e98238b 100644
--- a/docs/zh/28-releases/01-tdengine.md
+++ b/docs/zh/28-releases/01-tdengine.md
@@ -6,6 +6,10 @@ description: TDengine 发布历史、Release Notes 及下载链接
import Release from "/components/ReleaseV3";
+## 3.0.1.3
+
+
+
## 3.0.1.2
diff --git a/docs/zh/28-releases/02-tools.md b/docs/zh/28-releases/02-tools.md
index f793981d06..8604885d3c 100644
--- a/docs/zh/28-releases/02-tools.md
+++ b/docs/zh/28-releases/02-tools.md
@@ -6,6 +6,10 @@ description: taosTools 的发布历史、Release Notes 和下载链接
import Release from "/components/ReleaseV3";
+## 2.2.3
+
+
+
## 2.2.2
diff --git a/include/common/tmsg.h b/include/common/tmsg.h
index 49db88d703..7aec00c7c1 100644
--- a/include/common/tmsg.h
+++ b/include/common/tmsg.h
@@ -55,11 +55,10 @@ extern int32_t tMsgDict[];
#define TMSG_SEG_CODE(TYPE) (((TYPE)&0xff00) >> 8)
#define TMSG_SEG_SEQ(TYPE) ((TYPE)&0xff)
-#define TMSG_INFO(TYPE) \
- ((TYPE) >= 0 && ((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || \
- (TYPE) < TDMT_SCH_MAX_MSG || (TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || \
- (TYPE) < TDMT_SYNC_MAX_MSG)) \
- ? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \
+#define TMSG_INFO(TYPE) \
+ ((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || (TYPE) < TDMT_SCH_MAX_MSG || \
+ (TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || (TYPE) < TDMT_SYNC_MAX_MSG) \
+ ? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \
: 0
#define TMSG_INDEX(TYPE) (tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE))
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/common/src/tglobal.c b/source/common/src/tglobal.c
index 973203097b..e4128c2474 100644
--- a/source/common/src/tglobal.c
+++ b/source/common/src/tglobal.c
@@ -206,7 +206,9 @@ static int32_t taosLoadCfg(SConfig *pCfg, const char **envCmd, const char *input
tstrncpy(cfgFile, cfgDir, sizeof(cfgDir));
}
- if (apolloUrl == NULL || apolloUrl[0] == '\0') cfgGetApollUrl(envCmd, envFile, apolloUrl);
+ if (apolloUrl != NULL && apolloUrl[0] == '\0') {
+ cfgGetApollUrl(envCmd, envFile, apolloUrl);
+ }
if (cfgLoad(pCfg, CFG_STYPE_APOLLO_URL, apolloUrl) != 0) {
uError("failed to load from apollo url:%s since %s", apolloUrl, terrstr());
@@ -1132,11 +1134,20 @@ int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDi
if (tsc) {
tsLogEmbedded = 0;
- if (taosAddClientLogCfg(pCfg) != 0) return -1;
+ if (taosAddClientLogCfg(pCfg) != 0) {
+ cfgCleanup(pCfg);
+ return -1;
+ }
} else {
tsLogEmbedded = 1;
- if (taosAddClientLogCfg(pCfg) != 0) return -1;
- if (taosAddServerLogCfg(pCfg) != 0) return -1;
+ if (taosAddClientLogCfg(pCfg) != 0) {
+ cfgCleanup(pCfg);
+ return -1;
+ }
+ if (taosAddServerLogCfg(pCfg) != 0) {
+ cfgCleanup(pCfg);
+ return -1;
+ }
}
if (taosLoadCfg(pCfg, envCmd, cfgDir, envFile, apolloUrl) != 0) {
diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c
index 1c7edbe6be..66386b0ee0 100644
--- a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c
+++ b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c
@@ -87,6 +87,7 @@ int32_t qmPutRpcMsgToQueue(SQnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) {
return 0;
default:
terrno = TSDB_CODE_INVALID_PARA;
+ taosFreeQitem(pMsg);
return -1;
}
}
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c
index cbcb541200..25e85227e3 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c
@@ -141,6 +141,7 @@ _OVER:
}
int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
+ int32_t ret = 0;
char file[PATH_MAX] = {0};
char realfile[PATH_MAX] = {0};
snprintf(file, sizeof(file), "%s%svnodes.json.bak", pMgmt->path, TD_DIRSEP);
@@ -161,13 +162,16 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
char *content = taosMemoryCalloc(1, maxLen + 1);
if (content == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
+ ret = -1;
+ goto _OVER;
}
len += snprintf(content + len, maxLen - len, "{\n");
len += snprintf(content + len, maxLen - len, " \"vnodes\": [\n");
for (int32_t i = 0; i < numOfVnodes; ++i) {
SVnodeObj *pVnode = pVnodes[i];
+ if (pVnode == NULL) continue;
+
len += snprintf(content + len, maxLen - len, " {\n");
len += snprintf(content + len, maxLen - len, " \"vgId\": %d,\n", pVnode->vgId);
len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pVnode->dropped);
@@ -180,12 +184,13 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
}
len += snprintf(content + len, maxLen - len, " ]\n");
len += snprintf(content + len, maxLen - len, "}\n");
+ terrno = 0;
+_OVER:
taosWriteFile(pFile, content, len);
taosFsyncFile(pFile);
taosCloseFile(&pFile);
taosMemoryFree(content);
- terrno = 0;
for (int32_t i = 0; i < numOfVnodes; ++i) {
SVnodeObj *pVnode = pVnodes[i];
@@ -196,6 +201,8 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
taosMemoryFree(pVnodes);
}
+ if (ret != 0) return -1;
+
dDebug("successed to write %s, numOfVnodes:%d", realfile, numOfVnodes);
return taosRenameFile(file, realfile);
}
\ No newline at end of file
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/index/src/indexCache.c b/source/libs/index/src/indexCache.c
index 7e867db755..39bba4e269 100644
--- a/source/libs/index/src/indexCache.c
+++ b/source/libs/index/src/indexCache.c
@@ -302,6 +302,7 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR
char* p = taosMemoryCalloc(1, strlen(c->colVal) + 1);
memcpy(p, c->colVal, strlen(c->colVal));
cond = cmpFn(p + skip, term->colVal, dType);
+ taosMemoryFree(p);
}
}
if (cond == MATCH) {
diff --git a/source/libs/index/src/indexFstFile.c b/source/libs/index/src/indexFstFile.c
index 2a33ddd477..7021fdfae3 100644
--- a/source/libs/index/src/indexFstFile.c
+++ b/source/libs/index/src/indexFstFile.c
@@ -69,6 +69,8 @@ static int idxFileCtxDoReadFrom(IFileCtx* ctx, uint8_t* buf, int len, int32_t of
int32_t blkOffset = offset % kBlockSize;
int32_t blkLeft = kBlockSize - blkOffset;
+ if (offset >= ctx->file.size) return 0;
+
do {
char key[128] = {0};
idxGenLRUKey(key, ctx->file.buf, blkId);
@@ -80,24 +82,34 @@ static int idxFileCtxDoReadFrom(IFileCtx* ctx, uint8_t* buf, int len, int32_t of
memcpy(buf + total, blk->buf + blkOffset, nread);
taosLRUCacheRelease(ctx->lru, h, false);
} else {
- int32_t cacheMemSize = sizeof(SDataBlock) + kBlockSize;
+ int32_t left = ctx->file.size - offset;
+ if (left < kBlockSize) {
+ nread = TMIN(left, len);
+ int32_t bytes = taosPReadFile(ctx->file.pFile, buf + total, nread, offset);
+ assert(bytes == nread);
- SDataBlock* blk = taosMemoryCalloc(1, cacheMemSize);
- blk->blockId = blkId;
- blk->nread = taosPReadFile(ctx->file.pFile, blk->buf, kBlockSize, blkId * kBlockSize);
- assert(blk->nread <= kBlockSize);
+ total += bytes;
+ return total;
+ } else {
+ int32_t cacheMemSize = sizeof(SDataBlock) + kBlockSize;
- if (blk->nread < kBlockSize && blk->nread < len) {
- break;
- }
+ SDataBlock* blk = taosMemoryCalloc(1, cacheMemSize);
+ blk->blockId = blkId;
+ blk->nread = taosPReadFile(ctx->file.pFile, blk->buf, kBlockSize, blkId * kBlockSize);
+ assert(blk->nread <= kBlockSize);
- nread = TMIN(blkLeft, len);
- memcpy(buf + total, blk->buf + blkOffset, nread);
+ if (blk->nread < kBlockSize && blk->nread < len) {
+ break;
+ }
- LRUStatus s = taosLRUCacheInsert(ctx->lru, key, strlen(key), blk, cacheMemSize, deleteDataBlockFromLRU, NULL,
- TAOS_LRU_PRIORITY_LOW);
- if (s != TAOS_LRU_STATUS_OK) {
- return -1;
+ nread = TMIN(blkLeft, len);
+ memcpy(buf + total, blk->buf + blkOffset, nread);
+
+ LRUStatus s = taosLRUCacheInsert(ctx->lru, key, strlen(key), blk, cacheMemSize, deleteDataBlockFromLRU, NULL,
+ TAOS_LRU_PRIORITY_LOW);
+ if (s != TAOS_LRU_STATUS_OK) {
+ return -1;
+ }
}
}
total += nread;
@@ -146,9 +158,7 @@ IFileCtx* idxFileCtxCreate(WriterType type, const char* path, bool readOnly, int
} else {
ctx->file.pFile = taosOpenFile(path, TD_FILE_READ);
- int64_t size = 0;
taosFStatFile(ctx->file.pFile, &ctx->file.size, NULL);
- ctx->file.size = (int)size;
#ifdef USE_MMAP
ctx->file.ptr = (char*)tfMmapReadOnly(ctx->file.pFile, ctx->file.size);
#endif
diff --git a/source/libs/index/test/jsonUT.cc b/source/libs/index/test/jsonUT.cc
index 1911514d97..8ae3fd4135 100644
--- a/source/libs/index/test/jsonUT.cc
+++ b/source/libs/index/test/jsonUT.cc
@@ -172,9 +172,9 @@ TEST_F(JsonEnv, testWriteMillonData) {
{
std::string colName("voltagefdadfa");
std::string colVal("abxxxxxxxxxxxx");
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 10000; i++) {
colVal[i % colVal.size()] = '0' + i % 128;
- for (size_t i = 0; i < 100; i++) {
+ for (size_t i = 0; i < 10; i++) {
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
colVal.c_str(), colVal.size());
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/source/util/src/tqueue.c b/source/util/src/tqueue.c
index eb70002680..eb62e12a19 100644
--- a/source/util/src/tqueue.c
+++ b/source/util/src/tqueue.c
@@ -151,15 +151,15 @@ int64_t taosQueueMemorySize(STaosQueue *queue) {
void *taosAllocateQitem(int32_t size, EQItype itype) {
STaosQnode *pNode = taosMemoryCalloc(1, sizeof(STaosQnode) + size);
- pNode->size = size;
- pNode->itype = itype;
- pNode->timestamp = taosGetTimestampUs();
-
if (pNode == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
+ pNode->size = size;
+ pNode->itype = itype;
+ pNode->timestamp = taosGetTimestampUs();
+
if (itype == RPC_QITEM) {
int64_t alloced = atomic_add_fetch_64(&tsRpcQueueMemoryUsed, size);
if (alloced > tsRpcQueueMemoryAllowed) {
diff --git a/source/util/src/tuuid.c b/source/util/src/tuuid.c
index 7460ccbc82..d192b1229d 100644
--- a/source/util/src/tuuid.c
+++ b/source/util/src/tuuid.c
@@ -20,8 +20,8 @@ static int32_t tUUIDSerialNo = 0;
int32_t tGenIdPI32(void) {
if (tUUIDHashId == 0) {
- char uid[64];
- int32_t code = taosGetSystemUUID(uid, tListLen(uid));
+ char uid[65] = {0};
+ int32_t code = taosGetSystemUUID(uid, sizeof(uid));
if (code != TSDB_CODE_SUCCESS) {
terrno = TAOS_SYSTEM_ERROR(errno);
} else {
diff --git a/source/util/src/tworker.c b/source/util/src/tworker.c
index 1f0731812c..d9ded20070 100644
--- a/source/util/src/tworker.c
+++ b/source/util/src/tworker.c
@@ -46,7 +46,7 @@ int32_t tQWorkerInit(SQWorkerPool *pool) {
void tQWorkerCleanup(SQWorkerPool *pool) {
for (int32_t i = 0; i < pool->max; ++i) {
SQWorker *worker = pool->workers + i;
- if (worker == NULL) continue;
+ // if (worker == NULL) continue;
if (taosCheckPthreadValid(worker->thread)) {
taosQsetThreadResume(pool->qset);
}
@@ -54,7 +54,7 @@ void tQWorkerCleanup(SQWorkerPool *pool) {
for (int32_t i = 0; i < pool->max; ++i) {
SQWorker *worker = pool->workers + i;
- if (worker == NULL) continue;
+ // if (worker == NULL) continue;
if (taosCheckPthreadValid(worker->thread)) {
taosThreadJoin(worker->thread, NULL);
taosThreadClear(&worker->thread);
@@ -138,8 +138,8 @@ STaosQueue *tQWorkerAllocQueue(SQWorkerPool *pool, void *ahandle, FItem fp) {
}
void tQWorkerFreeQueue(SQWorkerPool *pool, STaosQueue *queue) {
- taosCloseQueue(queue);
uDebug("worker:%s, queue:%p is freed", pool->name, queue);
+ taosCloseQueue(queue);
}
int32_t tWWorkerInit(SWWorkerPool *pool) {
@@ -283,8 +283,8 @@ STaosQueue *tWWorkerAllocQueue(SWWorkerPool *pool, void *ahandle, FItems fp) {
}
void tWWorkerFreeQueue(SWWorkerPool *pool, STaosQueue *queue) {
- taosCloseQueue(queue);
uDebug("worker:%s, queue:%p is freed", pool->name, queue);
+ taosCloseQueue(queue);
}
int32_t tSingleWorkerInit(SSingleWorker *pWorker, const SSingleWorkerCfg *pCfg) {
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
diff --git a/tools/shell/src/shellArguments.c b/tools/shell/src/shellArguments.c
index 93f8b8a23b..eedb6d7295 100644
--- a/tools/shell/src/shellArguments.c
+++ b/tools/shell/src/shellArguments.c
@@ -358,7 +358,7 @@ static int32_t shellCheckArgs() {
return -1;
}
- if (pArgs->password != NULL && (strlen(pArgs->password) <= 0)) {
+ if (/*pArgs->password != NULL && */ (strlen(pArgs->password) <= 0)) {
printf("Invalid password\r\n");
return -1;
}
diff --git a/utils/tsim/src/simExe.c b/utils/tsim/src/simExe.c
index 16732ff9a1..5bb53287db 100644
--- a/utils/tsim/src/simExe.c
+++ b/utils/tsim/src/simExe.c
@@ -224,10 +224,24 @@ char *simGetVariable(SScript *script, char *varName, int32_t varLen) {
}
int32_t simExecuteExpression(SScript *script, char *exp) {
- char *op1, *op2, *var1, *var2, *var3, *rest;
- int32_t op1Len, op2Len, var1Len, var2Len, var3Len, val0, val1;
- char t0[1024], t1[1024], t2[1024], t3[2048];
- int32_t result;
+ char *op1 = NULL;
+ char *op2 = NULL;
+ char *var1 = NULL;
+ char *var2 = NULL;
+ char *var3 = NULL;
+ char *rest = NULL;
+ int32_t op1Len = 0;
+ int32_t op2Len = 0;
+ int32_t var1Len = 0;
+ int32_t var2Len = 0;
+ int32_t var3Len = 0;
+ int32_t val0 = 0;
+ int32_t val1 = 0;
+ char t0[1024] = {0};
+ char t1[1024] = {0};
+ char t2[1024] = {0};
+ char t3[2048] = {0};
+ int32_t result = 0;
rest = paGetToken(exp, &var1, &var1Len);
rest = paGetToken(rest, &op1, &op1Len);
@@ -241,9 +255,9 @@ int32_t simExecuteExpression(SScript *script, char *exp) {
t0[var1Len] = 0;
}
- if (var2[0] == '$')
- strcpy(t1, simGetVariable(script, var2 + 1, var2Len - 1));
- else {
+ if (var2[0] == '$') {
+ tstrncpy(t1, simGetVariable(script, var2 + 1, var2Len - 1), 1024);
+ } else {
memcpy(t1, var2, var2Len);
t1[var2Len] = 0;
}
@@ -258,14 +272,21 @@ int32_t simExecuteExpression(SScript *script, char *exp) {
t2[var3Len] = 0;
}
+ int64_t t1l = atoll(t1);
+ int64_t t2l = atoll(t2);
+
if (op2[0] == '+') {
- sprintf(t3, "%lld", atoll(t1) + atoll(t2));
+ sprintf(t3, "%" PRId64, t1l + t2l);
} else if (op2[0] == '-') {
- sprintf(t3, "%lld", atoll(t1) - atoll(t2));
+ sprintf(t3, "%" PRId64, t1l - t2l);
} else if (op2[0] == '*') {
- sprintf(t3, "%lld", atoll(t1) * atoll(t2));
+ sprintf(t3, "%" PRId64, t1l * t2l);
} else if (op2[0] == '/') {
- sprintf(t3, "%lld", atoll(t1) / atoll(t2));
+ if (t2l == 0) {
+ sprintf(t3, "%" PRId64, INT64_MAX);
+ } else {
+ sprintf(t3, "%" PRId64, t1l / t2l);
+ }
} else if (op2[0] == '.') {
sprintf(t3, "%s%s", t1, t2);
}
@@ -636,7 +657,7 @@ bool simCreateTaosdConnect(SScript *script, char *rest) {
}
bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) {
- char timeStr[30] = {0};
+ char timeStr[80] = {0};
time_t tt;
struct tm tp;
SCmdLine *line = &script->lines[script->linePos];
@@ -943,7 +964,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
return true;
}
- TAOS_RES *pSql = pSql = taos_query(script->taos, rest);
+ TAOS_RES *pSql = taos_query(script->taos, rest);
int32_t ret = taos_errno(pSql);
taos_free_result(pSql);
@@ -961,7 +982,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) {
}
bool simExecuteLineInsertCmd(SScript *script, char *rest) {
- char buf[TSDB_MAX_BINARY_LEN];
+ char buf[TSDB_MAX_BINARY_LEN] = {0};
simVisuallizeOption(script, rest, buf);
rest = buf;
@@ -973,10 +994,7 @@ bool simExecuteLineInsertCmd(SScript *script, char *rest) {
char *lines[] = {rest};
#if 0
int32_t ret = taos_insert_lines(script->taos, lines, 1);
-#else
- int32_t ret = 0;
-#endif
- if (ret == TSDB_CODE_SUCCESS) {
+ if (ret == TSDB_CODE_SUCCESS) {
simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest);
script->linePos++;
return true;
@@ -985,6 +1003,11 @@ bool simExecuteLineInsertCmd(SScript *script, char *rest) {
tstrerror(ret));
return false;
}
+#else
+ simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest);
+ script->linePos++;
+ return true;
+#endif
}
bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) {
diff --git a/utils/tsim/src/simMain.c b/utils/tsim/src/simMain.c
index 713e46df58..e58a22cf68 100644
--- a/utils/tsim/src/simMain.c
+++ b/utils/tsim/src/simMain.c
@@ -33,7 +33,7 @@ int32_t main(int32_t argc, char *argv[]) {
if (strcmp(argv[i], "-c") == 0 && i < argc - 1) {
tstrncpy(configDir, argv[++i], 128);
} else if (strcmp(argv[i], "-f") == 0 && i < argc - 1) {
- strcpy(scriptFile, argv[++i]);
+ tstrncpy(scriptFile, argv[++i], MAX_FILE_NAME_LEN);
} else if (strcmp(argv[i], "-m") == 0) {
useMultiProcess = true;
} else if (strcmp(argv[i], "-v") == 0) {
diff --git a/utils/tsim/src/simParse.c b/utils/tsim/src/simParse.c
index b9f7610be8..14be10bc8a 100644
--- a/utils/tsim/src/simParse.c
+++ b/utils/tsim/src/simParse.c
@@ -175,14 +175,17 @@ SScript *simBuildScriptObj(char *fileName) {
SScript *simParseScript(char *fileName) {
TdFilePtr pFile;
int32_t tokenLen, lineNum = 0;
- char buffer[10*1024], name[128], *token, *rest;
- SCommand *pCmd;
- SScript *script;
+ char buffer[10 * 1024] = {0};
+ char name[PATH_MAX] = {9};
+ char *token = NULL;
+ char *rest = NULL;
+ SCommand *pCmd = NULL;
+ SScript *script = NULL;
if ((fileName[0] == '.') || (fileName[0] == '/')) {
- strcpy(name, fileName);
+ tstrncpy(name, fileName, PATH_MAX);
} else {
- sprintf(name, "%s" TD_DIRSEP "%s", simScriptDir, fileName);
+ snprintf(name, PATH_MAX, "%s" TD_DIRSEP "%s", simScriptDir, fileName);
taosRealPath(name, NULL, sizeof(name));
}