Merge remote-tracking branch 'origin/3.0' into feat/TD-27337
This commit is contained in:
commit
98ed2458ea
|
@ -91,6 +91,7 @@ TDengine 会为 WAL 文件自动创建索引以支持快速随机访问,并提
|
|||
不同语言下, TMQ 订阅相关的 API 及数据结构如下(详细的接口说明可以参考连接器章节,注意consumer结构不是线程安全的,在一个线程使用consumer时,不要在另一个线程close这个consumer):
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
|
||||
<TabItem value="c" label="C">
|
||||
|
||||
```c
|
||||
|
@ -146,7 +147,6 @@ TDengine 会为 WAL 文件自动创建索引以支持快速随机访问,并提
|
|||
DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res);
|
||||
DLL_EXPORT const char *tmq_err2str(int32_t code);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
|
@ -304,7 +304,6 @@ TDengine 会为 WAL 文件自动创建索引以支持快速随机访问,并提
|
|||
|
||||
void Close()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
@ -335,8 +334,8 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
对于不同编程语言,其设置方式如下:
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
<TabItem value="c" label="C">
|
||||
|
||||
<TabItem value="c" label="C">
|
||||
```c
|
||||
/* 根据需要,设置消费组 (group.id)、自动提交 (enable.auto.commit)、
|
||||
自动提交时间间隔 (auto.commit.interval.ms)、用户名 (td.connect.user)、密码 (td.connect.pass) 等参数 */
|
||||
|
@ -353,8 +352,8 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
tmq_t* tmq = tmq_consumer_new(conf, NULL, 0);
|
||||
tmq_conf_destroy(conf);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
对于 Java 程序,还可以使用如下配置项:
|
||||
|
@ -388,7 +387,6 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
public class MetersDeserializer extends ReferenceDeserializer<Meters> {
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem label="Go" value="Go">
|
||||
|
@ -502,6 +500,7 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
一个 consumer 支持同时订阅多个 topic。
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
|
||||
<TabItem value="c" label="C">
|
||||
|
||||
```c
|
||||
|
@ -581,6 +580,7 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
以下代码展示了不同语言下如何对 TMQ 消息进行消费。
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
|
||||
<TabItem value="c" label="C">
|
||||
|
||||
```c
|
||||
|
@ -717,6 +717,7 @@ INSERT INTO tmqdb.ctb1 VALUES(now, 1, 1, 'a1')(now+1s, 11, 11, 'a11');
|
|||
消费结束后,应当取消订阅。
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
|
||||
<TabItem value="c" label="C">
|
||||
|
||||
```c
|
||||
|
|
|
@ -54,6 +54,8 @@ typedef struct SSessionKey {
|
|||
uint64_t groupId;
|
||||
} SSessionKey;
|
||||
|
||||
typedef int64_t COUNT_TYPE;
|
||||
|
||||
typedef struct SVersionRange {
|
||||
int64_t minVer;
|
||||
int64_t maxVer;
|
||||
|
|
|
@ -248,6 +248,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_HINT,
|
||||
QUERY_NODE_VIEW,
|
||||
QUERY_NODE_WINDOW_OFFSET,
|
||||
QUERY_NODE_COUNT_WINDOW,
|
||||
|
||||
// Statement nodes are used in parser and planner module.
|
||||
QUERY_NODE_SET_OPERATOR = 100,
|
||||
|
@ -433,7 +434,9 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_HASH_JOIN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE,
|
||||
QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL
|
||||
QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL,
|
||||
} ENodeType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -3183,18 +3186,11 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
int64_t leftForVer;
|
||||
int64_t resetRelHalt; // reset related stream task halt status
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
} SVDropStreamTaskReq;
|
||||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
int64_t dataVer;
|
||||
} SVStreamTaskVerUpdateReq;
|
||||
|
||||
typedef struct {
|
||||
int8_t reserved;
|
||||
} SVDropStreamTaskRsp;
|
||||
|
|
|
@ -305,74 +305,76 @@
|
|||
#define TK_SESSION 287
|
||||
#define TK_STATE_WINDOW 288
|
||||
#define TK_EVENT_WINDOW 289
|
||||
#define TK_SLIDING 290
|
||||
#define TK_FILL 291
|
||||
#define TK_VALUE 292
|
||||
#define TK_VALUE_F 293
|
||||
#define TK_NONE 294
|
||||
#define TK_PREV 295
|
||||
#define TK_NULL_F 296
|
||||
#define TK_LINEAR 297
|
||||
#define TK_NEXT 298
|
||||
#define TK_HAVING 299
|
||||
#define TK_RANGE 300
|
||||
#define TK_EVERY 301
|
||||
#define TK_ORDER 302
|
||||
#define TK_SLIMIT 303
|
||||
#define TK_SOFFSET 304
|
||||
#define TK_LIMIT 305
|
||||
#define TK_OFFSET 306
|
||||
#define TK_ASC 307
|
||||
#define TK_NULLS 308
|
||||
#define TK_ABORT 309
|
||||
#define TK_AFTER 310
|
||||
#define TK_ATTACH 311
|
||||
#define TK_BEFORE 312
|
||||
#define TK_BEGIN 313
|
||||
#define TK_BITAND 314
|
||||
#define TK_BITNOT 315
|
||||
#define TK_BITOR 316
|
||||
#define TK_BLOCKS 317
|
||||
#define TK_CHANGE 318
|
||||
#define TK_COMMA 319
|
||||
#define TK_CONCAT 320
|
||||
#define TK_CONFLICT 321
|
||||
#define TK_COPY 322
|
||||
#define TK_DEFERRED 323
|
||||
#define TK_DELIMITERS 324
|
||||
#define TK_DETACH 325
|
||||
#define TK_DIVIDE 326
|
||||
#define TK_DOT 327
|
||||
#define TK_EACH 328
|
||||
#define TK_FAIL 329
|
||||
#define TK_FILE 330
|
||||
#define TK_FOR 331
|
||||
#define TK_GLOB 332
|
||||
#define TK_ID 333
|
||||
#define TK_IMMEDIATE 334
|
||||
#define TK_IMPORT 335
|
||||
#define TK_INITIALLY 336
|
||||
#define TK_INSTEAD 337
|
||||
#define TK_ISNULL 338
|
||||
#define TK_KEY 339
|
||||
#define TK_MODULES 340
|
||||
#define TK_NK_BITNOT 341
|
||||
#define TK_NK_SEMI 342
|
||||
#define TK_NOTNULL 343
|
||||
#define TK_OF 344
|
||||
#define TK_PLUS 345
|
||||
#define TK_PRIVILEGE 346
|
||||
#define TK_RAISE 347
|
||||
#define TK_RESTRICT 348
|
||||
#define TK_ROW 349
|
||||
#define TK_STAR 350
|
||||
#define TK_STATEMENT 351
|
||||
#define TK_STRICT 352
|
||||
#define TK_STRING 353
|
||||
#define TK_TIMES 354
|
||||
#define TK_VALUES 355
|
||||
#define TK_VARIABLE 356
|
||||
#define TK_WAL 357
|
||||
#define TK_COUNT_WINDOW 290
|
||||
#define TK_SLIDING 291
|
||||
#define TK_FILL 292
|
||||
#define TK_VALUE 293
|
||||
#define TK_VALUE_F 294
|
||||
#define TK_NONE 295
|
||||
#define TK_PREV 296
|
||||
#define TK_NULL_F 297
|
||||
#define TK_LINEAR 298
|
||||
#define TK_NEXT 299
|
||||
#define TK_HAVING 300
|
||||
#define TK_RANGE 301
|
||||
#define TK_EVERY 302
|
||||
#define TK_ORDER 303
|
||||
#define TK_SLIMIT 304
|
||||
#define TK_SOFFSET 305
|
||||
#define TK_LIMIT 306
|
||||
#define TK_OFFSET 307
|
||||
#define TK_ASC 308
|
||||
#define TK_NULLS 309
|
||||
#define TK_ABORT 310
|
||||
#define TK_AFTER 311
|
||||
#define TK_ATTACH 312
|
||||
#define TK_BEFORE 313
|
||||
#define TK_BEGIN 314
|
||||
#define TK_BITAND 315
|
||||
#define TK_BITNOT 316
|
||||
#define TK_BITOR 317
|
||||
#define TK_BLOCKS 318
|
||||
#define TK_CHANGE 319
|
||||
#define TK_COMMA 320
|
||||
#define TK_CONCAT 321
|
||||
#define TK_CONFLICT 322
|
||||
#define TK_COPY 323
|
||||
#define TK_DEFERRED 324
|
||||
#define TK_DELIMITERS 325
|
||||
#define TK_DETACH 326
|
||||
#define TK_DIVIDE 327
|
||||
#define TK_DOT 328
|
||||
#define TK_EACH 329
|
||||
#define TK_FAIL 330
|
||||
#define TK_FILE 331
|
||||
#define TK_FOR 332
|
||||
#define TK_GLOB 333
|
||||
#define TK_ID 334
|
||||
#define TK_IMMEDIATE 335
|
||||
#define TK_IMPORT 336
|
||||
#define TK_INITIALLY 337
|
||||
#define TK_INSTEAD 338
|
||||
#define TK_ISNULL 339
|
||||
#define TK_KEY 340
|
||||
#define TK_MODULES 341
|
||||
#define TK_NK_BITNOT 342
|
||||
#define TK_NK_SEMI 343
|
||||
#define TK_NOTNULL 344
|
||||
#define TK_OF 345
|
||||
#define TK_PLUS 346
|
||||
#define TK_PRIVILEGE 347
|
||||
#define TK_RAISE 348
|
||||
#define TK_RESTRICT 349
|
||||
#define TK_ROW 350
|
||||
#define TK_STAR 351
|
||||
#define TK_STATEMENT 352
|
||||
#define TK_STRICT 353
|
||||
#define TK_STRING 354
|
||||
#define TK_TIMES 355
|
||||
#define TK_VALUES 356
|
||||
#define TK_VARIABLE 357
|
||||
#define TK_WAL 358
|
||||
|
||||
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
|
|
|
@ -215,7 +215,6 @@ int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo);
|
|||
int32_t qStreamSourceScanParamForHistoryScanStep1(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow);
|
||||
int32_t qStreamSourceScanParamForHistoryScanStep2(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow);
|
||||
int32_t qStreamRecoverFinish(qTaskInfo_t tinfo);
|
||||
int32_t qRestoreStreamOperatorOption(qTaskInfo_t tinfo);
|
||||
bool qStreamScanhistoryFinished(qTaskInfo_t tinfo);
|
||||
int32_t qStreamInfoResetTimewindowFilter(qTaskInfo_t tinfo);
|
||||
void resetTaskInfo(qTaskInfo_t tinfo);
|
||||
|
|
|
@ -352,14 +352,19 @@ typedef struct SStateStore {
|
|||
int32_t (*streamStateSessionPut)(SStreamState* pState, const SSessionKey* key, void* value, int32_t vLen);
|
||||
int32_t (*streamStateSessionGet)(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateSessionDel)(SStreamState* pState, const SSessionKey* key);
|
||||
int32_t (*streamStateSessionReset)(SStreamState* pState, void* pVal);
|
||||
int32_t (*streamStateSessionClear)(SStreamState* pState);
|
||||
int32_t (*streamStateSessionGetKVByCur)(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateStateAddIfNotExist)(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
||||
int32_t (*streamStateSessionGetKeyByRange)(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t (*streamStateCountGetKeyByRange)(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t (*streamStateSessionAllocWinBuffByNextPosition)(SStreamState* pState, SStreamStateCur* pCur,
|
||||
const SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
int32_t (*streamStateCountWinAddIfNotExist)(SStreamState* pState, SSessionKey* pKey, COUNT_TYPE winCount, void** ppVal, int32_t* pVLen);
|
||||
int32_t (*streamStateCountWinAdd)(SStreamState* pState, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
SUpdateInfo* (*updateInfoInit)(int64_t interval, int32_t precision, int64_t watermark, bool igUp);
|
||||
TSKEY (*updateInfoFillBlockData)(SUpdateInfo* pInfo, SSDataBlock* pBlock, int32_t primaryTsCol);
|
||||
bool (*updateInfoIsUpdated)(SUpdateInfo* pInfo, uint64_t tableId, TSKEY ts);
|
||||
|
@ -377,6 +382,7 @@ typedef struct SStateStore {
|
|||
int32_t (*updateInfoDeserialize)(void* buf, int32_t bufLen, SUpdateInfo* pInfo);
|
||||
|
||||
SStreamStateCur* (*streamStateSessionSeekKeyNext)(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* (*streamStateCountSeekKeyPrev)(SStreamState* pState, const SSessionKey* pKey, COUNT_TYPE count);
|
||||
SStreamStateCur* (*streamStateSessionSeekKeyCurrentPrev)(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* (*streamStateSessionSeekKeyCurrentNext)(SStreamState* pState, const SSessionKey* key);
|
||||
|
||||
|
|
|
@ -249,7 +249,8 @@ typedef enum EWindowType {
|
|||
WINDOW_TYPE_INTERVAL = 1,
|
||||
WINDOW_TYPE_SESSION,
|
||||
WINDOW_TYPE_STATE,
|
||||
WINDOW_TYPE_EVENT
|
||||
WINDOW_TYPE_EVENT,
|
||||
WINDOW_TYPE_COUNT
|
||||
} EWindowType;
|
||||
|
||||
typedef enum EWindowAlgorithm {
|
||||
|
@ -287,6 +288,8 @@ typedef struct SWindowLogicNode {
|
|||
int8_t igCheckUpdate;
|
||||
EWindowAlgorithm windowAlgo;
|
||||
bool isPartTb;
|
||||
int64_t windowCount;
|
||||
int64_t windowSliding;
|
||||
} SWindowLogicNode;
|
||||
|
||||
typedef struct SFillLogicNode {
|
||||
|
@ -651,6 +654,14 @@ typedef struct SEventWinodwPhysiNode {
|
|||
|
||||
typedef SEventWinodwPhysiNode SStreamEventWinodwPhysiNode;
|
||||
|
||||
typedef struct SCountWinodwPhysiNode {
|
||||
SWindowPhysiNode window;
|
||||
int64_t windowCount;
|
||||
int64_t windowSliding;
|
||||
} SCountWinodwPhysiNode;
|
||||
|
||||
typedef SCountWinodwPhysiNode SStreamCountWinodwPhysiNode;
|
||||
|
||||
typedef struct SSortPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function
|
||||
|
|
|
@ -306,6 +306,13 @@ typedef struct SEventWindowNode {
|
|||
SNode* pEndCond;
|
||||
} SEventWindowNode;
|
||||
|
||||
typedef struct SCountWindowNode {
|
||||
ENodeType type; // QUERY_NODE_EVENT_WINDOW
|
||||
SNode* pCol; // timestamp primary key
|
||||
int64_t windowCount;
|
||||
int64_t windowSliding;
|
||||
} SCountWindowNode;
|
||||
|
||||
typedef enum EFillMode {
|
||||
FILL_MODE_NONE = 1,
|
||||
FILL_MODE_VALUE,
|
||||
|
|
|
@ -55,13 +55,16 @@ int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key,
|
|||
int32_t streamStateSessionPut(SStreamState* pState, const SSessionKey* key, void* value, int32_t vLen);
|
||||
int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key);
|
||||
int32_t streamStateSessionReset(SStreamState* pState, void* pVal);
|
||||
int32_t streamStateSessionClear(SStreamState* pState);
|
||||
int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
int32_t streamStateSessionGetKeyByRange(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t streamStateCountGetKeyByRange(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||
int32_t streamStateSessionAllocWinBuffByNextPosition(SStreamState* pState, SStreamStateCur* pCur,
|
||||
const SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateCountSeekKeyPrev(SStreamState* pState, const SSessionKey* pKey, COUNT_TYPE count);
|
||||
SStreamStateCur* streamStateSessionSeekKeyCurrentPrev(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekKeyCurrentNext(SStreamState* pState, const SSessionKey* key);
|
||||
|
||||
|
@ -79,6 +82,10 @@ int32_t streamStateReleaseBuf(SStreamState* pState, void* pVal, bool used);
|
|||
int32_t streamStateClearBuff(SStreamState* pState, void* pVal);
|
||||
void streamStateFreeVal(void* val);
|
||||
|
||||
// count window
|
||||
int32_t streamStateCountWinAddIfNotExist(SStreamState* pState, SSessionKey* pKey, COUNT_TYPE winCount, void** ppVal, int32_t* pVLen);
|
||||
int32_t streamStateCountWinAdd(SStreamState* pState, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
SStreamStateCur* streamStateGetAndCheckCur(SStreamState* pState, SWinKey* key);
|
||||
SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key);
|
||||
SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey* key);
|
||||
|
@ -128,10 +135,6 @@ int sessionRangeKeyCmpr(const SSessionKey* pWin1, const SSessionKey* pWin2);
|
|||
int sessionWinKeyCmpr(const SSessionKey* pWin1, const SSessionKey* pWin2);
|
||||
int stateSessionKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2);
|
||||
int stateKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2);
|
||||
#if 0
|
||||
char* streamStateSessionDump(SStreamState* pState);
|
||||
char* streamStateIntervalDump(SStreamState* pState);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -463,7 +463,8 @@ struct SStreamTask {
|
|||
struct SStreamMeta* pMeta;
|
||||
SSHashObj* pNameMap;
|
||||
void* pBackend;
|
||||
char reserve[256];
|
||||
int8_t subtableWithoutMd5;
|
||||
char reserve[255];
|
||||
};
|
||||
|
||||
typedef int32_t (*startComplete_fn_t)(struct SStreamMeta*);
|
||||
|
@ -532,7 +533,7 @@ int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo)
|
|||
int32_t tDecodeStreamEpInfo(SDecoder* pDecoder, SStreamChildEpInfo* pInfo);
|
||||
|
||||
SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset, bool fillHistory, int64_t triggerParam,
|
||||
SArray* pTaskList, bool hasFillhistory);
|
||||
SArray* pTaskList, bool hasFillhistory, int8_t subtableWithoutMd5);
|
||||
int32_t tEncodeStreamTask(SEncoder* pEncoder, const SStreamTask* pTask);
|
||||
int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask);
|
||||
void tFreeStreamTask(SStreamTask* pTask);
|
||||
|
@ -656,7 +657,6 @@ int32_t tEncodeStreamCheckpointSourceReq(SEncoder* pEncoder, const SStreamCheckp
|
|||
int32_t tDecodeStreamCheckpointSourceReq(SDecoder* pDecoder, SStreamCheckpointSourceReq* pReq);
|
||||
|
||||
int32_t tEncodeStreamCheckpointSourceRsp(SEncoder* pEncoder, const SStreamCheckpointSourceRsp* pRsp);
|
||||
int32_t tDecodeStreamCheckpointSourceRsp(SDecoder* pDecoder, SStreamCheckpointSourceRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
SMsgHead msgHead;
|
||||
|
@ -724,19 +724,6 @@ typedef struct SStreamTaskState {
|
|||
char* name;
|
||||
} SStreamTaskState;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
int32_t downstreamTaskId;
|
||||
int32_t taskId;
|
||||
} SStreamRecoverDownstreamReq;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
int32_t downstreamTaskId;
|
||||
int32_t taskId;
|
||||
SArray* checkpointVer; // SArray<SStreamCheckpointInfo>
|
||||
} SStreamRecoverDownstreamRsp;
|
||||
|
||||
int32_t tEncodeStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq* pReq);
|
||||
int32_t tDecodeStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq);
|
||||
|
||||
|
@ -745,10 +732,12 @@ int32_t tDecodeStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp)
|
|||
|
||||
int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq);
|
||||
int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq);
|
||||
|
||||
int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq);
|
||||
void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq);
|
||||
|
||||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
||||
int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq);
|
||||
void tDeleteStreamRetrieveReq(SStreamRetrieveReq* pReq);
|
||||
|
||||
typedef struct SStreamTaskCheckpointReq {
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
|
@ -787,21 +776,19 @@ void initRpcMsg(SRpcMsg* pMsg, int32_t msgType, void* pCont, int32_t contLen);
|
|||
// recover and fill history
|
||||
void streamTaskCheckDownstream(SStreamTask* pTask);
|
||||
|
||||
int32_t streamTaskCheckStatus(SStreamTask* pTask, int32_t upstreamTaskId, int32_t vgId, int64_t stage,
|
||||
int64_t* oldStage);
|
||||
int32_t streamTaskCheckStatus(SStreamTask* pTask, int32_t upstreamId, int32_t vgId, int64_t stage, int64_t* oldStage);
|
||||
int32_t streamTaskUpdateEpsetInfo(SStreamTask* pTask, SArray* pNodeList);
|
||||
void streamTaskResetUpstreamStageInfo(SStreamTask* pTask);
|
||||
bool streamTaskIsAllUpstreamClosed(SStreamTask* pTask);
|
||||
bool streamTaskSetSchedStatusWait(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusActive(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusInactive(SStreamTask* pTask);
|
||||
int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, bool metaLock);
|
||||
int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, int32_t clearRelHalt, bool metaLock);
|
||||
|
||||
int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event);
|
||||
int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent event);
|
||||
void streamTaskRestoreStatus(SStreamTask* pTask);
|
||||
|
||||
int32_t streamTaskStop(SStreamTask* pTask);
|
||||
int32_t streamSendCheckRsp(const SStreamMeta* pMeta, const SStreamTaskCheckReq* pReq, SStreamTaskCheckRsp* pRsp,
|
||||
SRpcHandleInfo* pRpcInfo, int32_t taskId);
|
||||
int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp);
|
||||
|
@ -813,9 +800,9 @@ bool streamHistoryTaskSetVerRangeStep2(SStreamTask* pTask, int64_t latestVer)
|
|||
int32_t streamQueueGetNumOfItems(const SStreamQueue* pQueue);
|
||||
|
||||
// common
|
||||
int32_t streamRestoreParam(SStreamTask* pTask);
|
||||
void streamTaskPause(SStreamMeta* pMeta, SStreamTask* pTask);
|
||||
void streamTaskResume(SStreamTask* pTask);
|
||||
int32_t streamTaskStop(SStreamTask* pTask);
|
||||
int32_t streamTaskSetUpstreamInfo(SStreamTask* pTask, const SStreamTask* pUpstreamTask);
|
||||
void streamTaskUpdateUpstreamInfo(SStreamTask* pTask, int32_t nodeId, const SEpSet* pEpSet);
|
||||
void streamTaskUpdateDownstreamInfo(SStreamTask* pTask, int32_t nodeId, const SEpSet* pEpSet);
|
||||
|
@ -839,7 +826,8 @@ SScanhistoryDataInfo streamScanHistoryData(SStreamTask* pTask, int64_t st);
|
|||
// stream task meta
|
||||
void streamMetaInit();
|
||||
void streamMetaCleanup();
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage, startComplete_fn_t fn);
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage,
|
||||
startComplete_fn_t fn);
|
||||
void streamMetaClose(SStreamMeta* streamMeta);
|
||||
int32_t streamMetaSaveTask(SStreamMeta* pMeta, SStreamTask* pTask); // save to stream meta store
|
||||
int32_t streamMetaRemoveTask(SStreamMeta* pMeta, STaskId* pKey);
|
||||
|
@ -881,7 +869,7 @@ int32_t streamProcessCheckpointReadyMsg(SStreamTask* pTask);
|
|||
int32_t streamTaskBuildCheckpoint(SStreamTask* pTask);
|
||||
void streamTaskClearCheckInfo(SStreamTask* pTask, bool clearChkpReadyMsg);
|
||||
int32_t streamAlignTransferState(SStreamTask* pTask);
|
||||
int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskId* pTaskId);
|
||||
int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskId* pTaskId, int64_t resetRelHalt);
|
||||
int32_t streamAddCheckpointSourceRspMsg(SStreamCheckpointSourceReq* pReq, SRpcHandleInfo* pRpcInfo, SStreamTask* pTask,
|
||||
int8_t isSucceed);
|
||||
int32_t buildCheckpointSourceRsp(SStreamCheckpointSourceReq* pReq, SRpcHandleInfo* pRpcInfo, SRpcMsg* pMsg,
|
||||
|
@ -892,6 +880,7 @@ void* streamDestroyStateMachine(SStreamTaskSM* pSM);
|
|||
|
||||
int32_t broadcastRetrieveMsg(SStreamTask* pTask, SStreamRetrieveReq *req);
|
||||
void sendRetrieveRsp(SStreamRetrieveReq *pReq, SRpcMsg* pRsp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,8 @@ typedef int32_t (*_state_file_remove_fn)(SStreamFileState* pFileState, const voi
|
|||
typedef int32_t (*_state_file_get_fn)(SStreamFileState* pFileState, void* pKey, void* data, int32_t* pDataLen);
|
||||
typedef int32_t (*_state_file_clear_fn)(SStreamState* pState);
|
||||
|
||||
typedef int32_t (*range_cmpr_fn)(const SSessionKey* pWin1, const SSessionKey* pWin2);
|
||||
|
||||
SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize,
|
||||
GetTsFun fp, void* pFile, TSKEY delMark, const char* taskId,
|
||||
int64_t checkpointId, int8_t type);
|
||||
|
@ -90,14 +92,19 @@ void sessionWinStateCleanup(void* pBuff);
|
|||
SStreamStateCur* sessionWinStateSeekKeyCurrentPrev(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
SStreamStateCur* sessionWinStateSeekKeyCurrentNext(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
SStreamStateCur* sessionWinStateSeekKeyNext(SStreamFileState* pFileState, const SSessionKey* pWinKey);
|
||||
SStreamStateCur* countWinStateSeekKeyPrev(SStreamFileState* pFileState, const SSessionKey* pWinKey, COUNT_TYPE count);
|
||||
int32_t sessionWinStateGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
int32_t sessionWinStateMoveToNext(SStreamStateCur* pCur);
|
||||
int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessionKey* key, SSessionKey* curKey);
|
||||
int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessionKey* key, SSessionKey* curKey, range_cmpr_fn cmpFn);
|
||||
|
||||
// state window
|
||||
int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
||||
|
||||
// count window
|
||||
int32_t getCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, COUNT_TYPE winCount, void** pVal, int32_t* pVLen);
|
||||
int32_t createCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -119,6 +119,8 @@ int32_t taosSetFileHandlesLimit();
|
|||
|
||||
int32_t taosLinkFile(char *src, char *dst);
|
||||
|
||||
bool lastErrorIsFileNotExist();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2121,6 +2121,9 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32
|
|||
pStart += colLength[i];
|
||||
}
|
||||
|
||||
// bool blankFill = *(bool*)p;
|
||||
p += sizeof(bool);
|
||||
|
||||
if (convertUcs4) {
|
||||
code = doConvertUCS4(pResultInfo, numOfRows, numOfCols, colLength);
|
||||
}
|
||||
|
|
|
@ -31,8 +31,7 @@ static char* buildCreateTableJson(SSchemaWrapper* schemaRow, SSchemaWrapper* sch
|
|||
char* string = NULL;
|
||||
cJSON* json = cJSON_CreateObject();
|
||||
if (json == NULL) {
|
||||
uError("create json object failed")
|
||||
return NULL;
|
||||
uError("create json object failed") return NULL;
|
||||
}
|
||||
cJSON* type = cJSON_CreateString("create");
|
||||
cJSON_AddItemToObject(json, "type", type);
|
||||
|
@ -131,7 +130,8 @@ static char* buildAlterSTableJson(void* alterData, int32_t alterDataLen) {
|
|||
cJSON* colType = cJSON_CreateNumber(field->type);
|
||||
cJSON_AddItemToObject(json, "colType", colType);
|
||||
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY || field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = field->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
cJSON_AddItemToObject(json, "colLength", cbytes);
|
||||
|
@ -156,7 +156,8 @@ static char* buildAlterSTableJson(void* alterData, int32_t alterDataLen) {
|
|||
cJSON_AddItemToObject(json, "colName", colName);
|
||||
cJSON* colType = cJSON_CreateNumber(field->type);
|
||||
cJSON_AddItemToObject(json, "colType", colType);
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY || field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = field->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
cJSON_AddItemToObject(json, "colLength", cbytes);
|
||||
|
@ -469,7 +470,8 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
cJSON* colType = cJSON_CreateNumber(vAlterTbReq.type);
|
||||
cJSON_AddItemToObject(json, "colType", colType);
|
||||
|
||||
if (vAlterTbReq.type == TSDB_DATA_TYPE_BINARY || vAlterTbReq.type == TSDB_DATA_TYPE_VARBINARY || vAlterTbReq.type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (vAlterTbReq.type == TSDB_DATA_TYPE_BINARY || vAlterTbReq.type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
vAlterTbReq.type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = vAlterTbReq.bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
cJSON_AddItemToObject(json, "colLength", cbytes);
|
||||
|
@ -490,7 +492,8 @@ static char* processAlterTable(SMqMetaRsp* metaRsp) {
|
|||
cJSON_AddItemToObject(json, "colName", colName);
|
||||
cJSON* colType = cJSON_CreateNumber(vAlterTbReq.colModType);
|
||||
cJSON_AddItemToObject(json, "colType", colType);
|
||||
if (vAlterTbReq.colModType == TSDB_DATA_TYPE_BINARY || vAlterTbReq.colModType == TSDB_DATA_TYPE_VARBINARY || vAlterTbReq.colModType == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (vAlterTbReq.colModType == TSDB_DATA_TYPE_BINARY || vAlterTbReq.colModType == TSDB_DATA_TYPE_VARBINARY ||
|
||||
vAlterTbReq.colModType == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = vAlterTbReq.colModBytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
cJSON_AddItemToObject(json, "colLength", cbytes);
|
||||
|
@ -731,8 +734,8 @@ static int32_t taosCreateStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
pReq.igExists = true;
|
||||
|
||||
uDebug(LOG_ID_TAG" create stable name:%s suid:%" PRId64 " processSuid:%" PRId64,
|
||||
LOG_ID_VALUE, req.name, req.suid, pReq.suid);
|
||||
uDebug(LOG_ID_TAG " create stable name:%s suid:%" PRId64 " processSuid:%" PRId64, LOG_ID_VALUE, req.name, req.suid,
|
||||
pReq.suid);
|
||||
STscObj* pTscObj = pRequest->pTscObj;
|
||||
SName tableName;
|
||||
tNameExtractFullName(toName(pTscObj->acctId, pRequest->pDb, req.name, &tableName), pReq.name);
|
||||
|
@ -835,8 +838,8 @@ static int32_t taosDropStb(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
// pReq.suid = processSuid(req.suid, pRequest->pDb);
|
||||
|
||||
uDebug(LOG_ID_TAG" drop stable name:%s suid:%" PRId64 " new suid:%" PRId64,
|
||||
LOG_ID_VALUE, req.name, req.suid, pReq.suid);
|
||||
uDebug(LOG_ID_TAG " drop stable name:%s suid:%" PRId64 " new suid:%" PRId64, LOG_ID_VALUE, req.name, req.suid,
|
||||
pReq.suid);
|
||||
STscObj* pTscObj = pRequest->pTscObj;
|
||||
SName tableName = {0};
|
||||
tNameExtractFullName(toName(pTscObj->acctId, pRequest->pDb, req.name, &tableName), pReq.name);
|
||||
|
@ -1142,7 +1145,8 @@ static int32_t taosDropTable(TAOS* taos, void* meta, int32_t metaLen) {
|
|||
tb_uid_t oldSuid = pDropReq->suid;
|
||||
pDropReq->suid = pTableMeta->suid;
|
||||
taosMemoryFreeClear(pTableMeta);
|
||||
uDebug(LOG_ID_TAG" drop table name:%s suid:%" PRId64 " new suid:%" PRId64, LOG_ID_VALUE, pDropReq->name, oldSuid, pDropReq->suid);
|
||||
uDebug(LOG_ID_TAG " drop table name:%s suid:%" PRId64 " new suid:%" PRId64, LOG_ID_VALUE, pDropReq->name, oldSuid,
|
||||
pDropReq->suid);
|
||||
|
||||
taosArrayPush(pRequest->tableList, &pName);
|
||||
SVgroupDropTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pInfo.vgId, sizeof(pInfo.vgId));
|
||||
|
@ -1410,8 +1414,8 @@ int taos_write_raw_block_with_fields_with_reqid(TAOS *taos, int rows, char *pDat
|
|||
return terrno;
|
||||
}
|
||||
|
||||
uDebug(LOG_ID_TAG " write raw block with field, rows:%d, pData:%p, tbname:%s, fields:%p, numFields:%d",
|
||||
LOG_ID_VALUE, rows, pData, tbname, fields, numFields);
|
||||
uDebug(LOG_ID_TAG " write raw block with field, rows:%d, pData:%p, tbname:%s, fields:%p, numFields:%d", LOG_ID_VALUE,
|
||||
rows, pData, tbname, fields, numFields);
|
||||
|
||||
pRequest->syncQuery = true;
|
||||
if (!pRequest->pDb) {
|
||||
|
|
|
@ -252,7 +252,8 @@ typedef struct SSyncCommitInfo {
|
|||
static int32_t syncAskEp(tmq_t* tmq);
|
||||
static int32_t makeTopicVgroupKey(char* dst, const char* topicName, int32_t vg);
|
||||
static int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet);
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, int32_t vgId, SEpSet* epSet, STqOffsetVal* offset, const char* pTopicName, SMqCommitCbParamSet* pParamSet);
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, int32_t vgId, SEpSet* epSet, STqOffsetVal* offset, const char* pTopicName,
|
||||
SMqCommitCbParamSet* pParamSet);
|
||||
static void commitRspCountDown(SMqCommitCbParamSet* pParamSet, int64_t consumerId, const char* pTopic, int32_t vgId);
|
||||
static void askEp(tmq_t* pTmq, void* param, bool sync, bool updateEpset);
|
||||
|
||||
|
@ -439,7 +440,8 @@ static int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, int32_t vgId, SEpSet* epSet, STqOffsetVal* offset, const char* pTopicName, SMqCommitCbParamSet* pParamSet) {
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, int32_t vgId, SEpSet* epSet, STqOffsetVal* offset, const char* pTopicName,
|
||||
SMqCommitCbParamSet* pParamSet) {
|
||||
SMqVgOffset pOffset = {0};
|
||||
|
||||
pOffset.consumerId = tmq->consumerId;
|
||||
|
@ -527,7 +529,8 @@ static SMqClientTopic* getTopicByName(tmq_t* tmq, const char* pTopicName) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SMqCommitCbParamSet* prepareCommitCbParamSet(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* userParam, int32_t rspNum){
|
||||
static SMqCommitCbParamSet* prepareCommitCbParamSet(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* userParam,
|
||||
int32_t rspNum) {
|
||||
SMqCommitCbParamSet* pParamSet = taosMemoryCalloc(1, sizeof(SMqCommitCbParamSet));
|
||||
if (pParamSet == NULL) {
|
||||
return NULL;
|
||||
|
@ -561,7 +564,8 @@ static int32_t getClientVg(tmq_t* tmq, char* pTopicName, int32_t vgId, SMqClient
|
|||
return *pVg == NULL ? TSDB_CODE_TMQ_INVALID_VGID : TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t asyncCommitOffset(tmq_t* tmq, char* pTopicName, int32_t vgId, STqOffsetVal* offsetVal, tmq_commit_cb* pCommitFp, void* userParam) {
|
||||
static int32_t asyncCommitOffset(tmq_t* tmq, char* pTopicName, int32_t vgId, STqOffsetVal* offsetVal,
|
||||
tmq_commit_cb* pCommitFp, void* userParam) {
|
||||
tscInfo("consumer:0x%" PRIx64 " do manual commit offset for %s, vgId:%d", tmq->consumerId, pTopicName, vgId);
|
||||
taosRLockLatch(&tmq->lock);
|
||||
SMqClientVg* pVg = NULL;
|
||||
|
@ -662,11 +666,13 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us
|
|||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
int32_t numOfVgroups = taosArrayGetSize(pTopic->vgs);
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " commit offset for topics:%s, numOfVgs:%d", tmq->consumerId, pTopic->topicName, numOfVgroups);
|
||||
tscInfo("consumer:0x%" PRIx64 " commit offset for topics:%s, numOfVgs:%d", tmq->consumerId, pTopic->topicName,
|
||||
numOfVgroups);
|
||||
for (int32_t j = 0; j < numOfVgroups; j++) {
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
|
||||
if (pVg->offsetInfo.endOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.endOffset, &pVg->offsetInfo.committedOffset)) {
|
||||
if (pVg->offsetInfo.endOffset.type > 0 &&
|
||||
!tOffsetEqual(&pVg->offsetInfo.endOffset, &pVg->offsetInfo.committedOffset)) {
|
||||
char offsetBuf[TSDB_OFFSET_LEN] = {0};
|
||||
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pVg->offsetInfo.endOffset);
|
||||
|
||||
|
@ -675,12 +681,15 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us
|
|||
|
||||
code = doSendCommitMsg(tmq, pVg->vgId, &pVg->epSet, &pVg->offsetInfo.endOffset, pTopic->topicName, pParamSet);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("consumer:0x%" PRIx64 " topic:%s on vgId:%d end commit msg failed, send offset:%s committed:%s, code:%s ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, offsetBuf, commitBuf, tstrerror(terrno), j + 1, numOfVgroups);
|
||||
tscError("consumer:0x%" PRIx64
|
||||
" topic:%s on vgId:%d end commit msg failed, send offset:%s committed:%s, code:%s ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, offsetBuf, commitBuf, tstrerror(terrno), j + 1,
|
||||
numOfVgroups);
|
||||
continue;
|
||||
}
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s, ordinal:%d/%d",
|
||||
tscInfo("consumer:0x%" PRIx64
|
||||
" topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s, ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, offsetBuf, commitBuf, j + 1, numOfVgroups);
|
||||
pVg->offsetInfo.committedOffset = pVg->offsetInfo.endOffset;
|
||||
} else {
|
||||
|
@ -691,7 +700,8 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us
|
|||
}
|
||||
taosRUnLockLatch(&tmq->lock);
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " total commit:%d for %d topics", tmq->consumerId, pParamSet->waitingRspNum - 1, numOfTopics);
|
||||
tscInfo("consumer:0x%" PRIx64 " total commit:%d for %d topics", tmq->consumerId, pParamSet->waitingRspNum - 1,
|
||||
numOfTopics);
|
||||
|
||||
// request is sent
|
||||
if (pParamSet->waitingRspNum != 1) {
|
||||
|
@ -1060,7 +1070,8 @@ static void tmqMgmtInit(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#define SET_ERROR_MSG(MSG) if(errstr!=NULL)snprintf(errstr,errstrLen,MSG);
|
||||
#define SET_ERROR_MSG(MSG) \
|
||||
if (errstr != NULL) snprintf(errstr, errstrLen, MSG);
|
||||
tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
||||
if (conf == NULL) {
|
||||
SET_ERROR_MSG("configure is null")
|
||||
|
@ -1154,7 +1165,8 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
tFormatOffset(buf, tListLen(buf), &offset);
|
||||
tscInfo("consumer:0x%" PRIx64 " is setup, refId:%" PRId64
|
||||
", groupId:%s, snapshot:%d, autoCommit:%d, commitInterval:%dms, offset:%s",
|
||||
pTmq->consumerId, pTmq->refId, pTmq->groupId, pTmq->useSnapshot, pTmq->autoCommit, pTmq->autoCommitInterval, buf);
|
||||
pTmq->consumerId, pTmq->refId, pTmq->groupId, pTmq->useSnapshot, pTmq->autoCommit, pTmq->autoCommitInterval,
|
||||
buf);
|
||||
|
||||
return pTmq;
|
||||
|
||||
|
@ -1456,7 +1468,8 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
|||
STqOffsetVal offsetNew = {0};
|
||||
offsetNew.type = tmq->resetOffsetCfg;
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d, num:%d, port:%d", tmq->consumerId, pTopic->topicName, vgNumGet, pVgEp->epSet.numOfEps,pVgEp->epSet.eps[pVgEp->epSet.inUse].port);
|
||||
tscInfo("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d, num:%d, port:%d", tmq->consumerId,
|
||||
pTopic->topicName, vgNumGet, pVgEp->epSet.numOfEps, pVgEp->epSet.eps[pVgEp->epSet.inUse].port);
|
||||
|
||||
SMqClientVg clientVg = {
|
||||
.pollCnt = 0,
|
||||
|
@ -1495,8 +1508,8 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
|||
|
||||
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
||||
if (epoch < tmq->epoch || (epoch == tmq->epoch && topicNumGet == 0)) {
|
||||
tscInfo("consumer:0x%" PRIx64 " no update ep epoch from %d to epoch %d, incoming topics:%d",
|
||||
tmq->consumerId, tmq->epoch, epoch, topicNumGet);
|
||||
tscInfo("consumer:0x%" PRIx64 " no update ep epoch from %d to epoch %d, incoming topics:%d", tmq->consumerId,
|
||||
tmq->epoch, epoch, topicNumGet);
|
||||
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__RECOVER) {
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__READY);
|
||||
}
|
||||
|
@ -1535,8 +1548,10 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
|||
tscInfo("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
|
||||
vgKey, buf);
|
||||
|
||||
SVgroupSaveInfo info = {.currentOffset = pVgCur->offsetInfo.endOffset, .seekOffset = pVgCur->offsetInfo.beginOffset,
|
||||
.commitOffset = pVgCur->offsetInfo.committedOffset, .numOfRows = pVgCur->numOfRows,
|
||||
SVgroupSaveInfo info = {.currentOffset = pVgCur->offsetInfo.endOffset,
|
||||
.seekOffset = pVgCur->offsetInfo.beginOffset,
|
||||
.commitOffset = pVgCur->offsetInfo.committedOffset,
|
||||
.numOfRows = pVgCur->numOfRows,
|
||||
.vgStatus = pVgCur->vgStatus};
|
||||
taosHashPut(pVgOffsetHashMap, vgKey, strlen(vgKey), &info, sizeof(SVgroupSaveInfo));
|
||||
}
|
||||
|
@ -1709,8 +1724,8 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
char offsetFormatBuf[TSDB_OFFSET_LEN] = {0};
|
||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.endOffset);
|
||||
code = asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &pVg->epSet, &transporterId, sendInfo);
|
||||
tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, code:%d, epoch %d, req:%s, reqId:0x%" PRIx64, pTmq->consumerId,
|
||||
pTopic->topicName, pVg->vgId, code, pTmq->epoch, offsetFormatBuf, req.reqId);
|
||||
tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, code:%d, epoch %d, req:%s, reqId:0x%" PRIx64,
|
||||
pTmq->consumerId, pTopic->topicName, pVg->vgId, code, pTmq->epoch, offsetFormatBuf, req.reqId);
|
||||
if (code != 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
@ -1751,9 +1766,10 @@ static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tmq->replayEnable && taosGetTimestampMs() - pVg->blockReceiveTs < pVg->blockSleepForReplay) { // less than 10ms
|
||||
tscTrace("consumer:0x%" PRIx64 " epoch %d, vgId:%d idle for %" PRId64 "ms before start next poll when replay", tmq->consumerId,
|
||||
tmq->epoch, pVg->vgId, pVg->blockSleepForReplay);
|
||||
if (tmq->replayEnable &&
|
||||
taosGetTimestampMs() - pVg->blockReceiveTs < pVg->blockSleepForReplay) { // less than 10ms
|
||||
tscTrace("consumer:0x%" PRIx64 " epoch %d, vgId:%d idle for %" PRId64 "ms before start next poll when replay",
|
||||
tmq->consumerId, tmq->epoch, pVg->vgId, pVg->blockSleepForReplay);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1779,7 +1795,8 @@ end:
|
|||
return code;
|
||||
}
|
||||
|
||||
static void updateVgInfo(SMqClientVg* pVg, STqOffsetVal* reqOffset, STqOffsetVal* rspOffset, int64_t sver, int64_t ever, int64_t consumerId, bool hasData){
|
||||
static void updateVgInfo(SMqClientVg* pVg, STqOffsetVal* reqOffset, STqOffsetVal* rspOffset, int64_t sver, int64_t ever,
|
||||
int64_t consumerId, bool hasData) {
|
||||
if (!pVg->seekUpdated) {
|
||||
tscDebug("consumer:0x%" PRIx64 " local offset is update, since seekupdate not set", consumerId);
|
||||
if (hasData) pVg->offsetInfo.beginOffset = *reqOffset;
|
||||
|
@ -1820,14 +1837,16 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
tscDebug("consumer:0x%" PRIx64 " wait for the re-balance, set status to be RECOVER", tmq->consumerId);
|
||||
} else if (pRspWrapper->code == TSDB_CODE_TQ_NO_COMMITTED_OFFSET) {
|
||||
terrno = pRspWrapper->code;
|
||||
tscError("consumer:0x%" PRIx64 " unexpected rsp from poll, code:%s", tmq->consumerId, tstrerror(pRspWrapper->code));
|
||||
tscError("consumer:0x%" PRIx64 " unexpected rsp from poll, code:%s", tmq->consumerId,
|
||||
tstrerror(pRspWrapper->code));
|
||||
taosFreeQitem(pRspWrapper);
|
||||
return NULL;
|
||||
} else {
|
||||
if (pRspWrapper->code == TSDB_CODE_VND_INVALID_VGROUP_ID) { // for vnode transform
|
||||
askEp(tmq, NULL, false, true);
|
||||
}
|
||||
tscError("consumer:0x%" PRIx64 " msg from vgId:%d discarded, since %s", tmq->consumerId, pollRspWrapper->vgId, tstrerror(pRspWrapper->code));
|
||||
tscError("consumer:0x%" PRIx64 " msg from vgId:%d discarded, since %s", tmq->consumerId, pollRspWrapper->vgId,
|
||||
tstrerror(pRspWrapper->code));
|
||||
taosWLockLatch(&tmq->lock);
|
||||
SMqClientVg* pVg = getVgInfo(tmq, pollRspWrapper->topicName, pollRspWrapper->vgId);
|
||||
if (pVg) pVg->emptyBlockReceiveTs = taosGetTimestampMs();
|
||||
|
@ -1861,7 +1880,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
pVg->epSet = *pollRspWrapper->pEpset;
|
||||
}
|
||||
|
||||
updateVgInfo(pVg, &pDataRsp->reqOffset, &pDataRsp->rspOffset, pDataRsp->head.walsver, pDataRsp->head.walever, tmq->consumerId, pDataRsp->blockNum != 0);
|
||||
updateVgInfo(pVg, &pDataRsp->reqOffset, &pDataRsp->rspOffset, pDataRsp->head.walsver, pDataRsp->head.walever,
|
||||
tmq->consumerId, pDataRsp->blockNum != 0);
|
||||
|
||||
char buf[TSDB_OFFSET_LEN] = {0};
|
||||
tFormatOffset(buf, TSDB_OFFSET_LEN, &pDataRsp->rspOffset);
|
||||
|
@ -1920,7 +1940,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
updateVgInfo(pVg, &pollRspWrapper->metaRsp.rspOffset, &pollRspWrapper->metaRsp.rspOffset, pollRspWrapper->metaRsp.head.walsver, pollRspWrapper->metaRsp.head.walever, tmq->consumerId, true);
|
||||
updateVgInfo(pVg, &pollRspWrapper->metaRsp.rspOffset, &pollRspWrapper->metaRsp.rspOffset,
|
||||
pollRspWrapper->metaRsp.head.walsver, pollRspWrapper->metaRsp.head.walever, tmq->consumerId, true);
|
||||
// build rsp
|
||||
SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
|
||||
taosFreeQitem(pRspWrapper);
|
||||
|
@ -1949,7 +1970,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
updateVgInfo(pVg, &pollRspWrapper->taosxRsp.reqOffset, &pollRspWrapper->taosxRsp.rspOffset, pollRspWrapper->taosxRsp.head.walsver, pollRspWrapper->taosxRsp.head.walever, tmq->consumerId, pollRspWrapper->taosxRsp.blockNum != 0);
|
||||
updateVgInfo(pVg, &pollRspWrapper->taosxRsp.reqOffset, &pollRspWrapper->taosxRsp.rspOffset,
|
||||
pollRspWrapper->taosxRsp.head.walsver, pollRspWrapper->taosxRsp.head.walever, tmq->consumerId,
|
||||
pollRspWrapper->taosxRsp.blockNum != 0);
|
||||
|
||||
if (pollRspWrapper->taosxRsp.blockNum == 0) {
|
||||
tscDebug("consumer:0x%" PRIx64 " taosx empty block received, vgId:%d, vg total:%" PRId64 ", reqId:0x%" PRIx64,
|
||||
|
@ -2316,7 +2339,8 @@ static int32_t checkWalRange(SVgOffsetInfo* offset, int64_t value){
|
|||
}
|
||||
|
||||
if (value != -1 && (value < offset->walVerBegin || value > offset->walVerEnd)) {
|
||||
tscError("invalid seek params, offset:%" PRId64 ", valid range:[%" PRId64 ", %" PRId64 "]", value, offset->walVerBegin, offset->walVerEnd);
|
||||
tscError("invalid seek params, offset:%" PRId64 ", valid range:[%" PRId64 ", %" PRId64 "]", value,
|
||||
offset->walVerBegin, offset->walVerEnd);
|
||||
return TSDB_CODE_TMQ_VERSION_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
|
@ -2370,12 +2394,14 @@ int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId,
|
|||
tsem_destroy(&pInfo->sem);
|
||||
taosMemoryFree(pInfo);
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " sync send commit to vgId:%d, offset:%" PRId64" code:%s", tmq->consumerId, vgId, offset, tstrerror(code));
|
||||
tscInfo("consumer:0x%" PRIx64 " sync send commit to vgId:%d, offset:%" PRId64 " code:%s", tmq->consumerId, vgId,
|
||||
offset, tstrerror(code));
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param){
|
||||
void tmq_commit_offset_async(tmq_t* tmq, const char* pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb* cb,
|
||||
void* param) {
|
||||
int32_t code = 0;
|
||||
if (tmq == NULL || pTopicName == NULL) {
|
||||
tscError("invalid tmq handle, null");
|
||||
|
@ -2407,7 +2433,8 @@ void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, i
|
|||
|
||||
code = asyncCommitOffset(tmq, tname, vgId, &offsetVal, cb, param);
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " async send commit to vgId:%d, offset:%" PRId64" code:%s", tmq->consumerId, vgId, offset, tstrerror(code));
|
||||
tscInfo("consumer:0x%" PRIx64 " async send commit to vgId:%d, offset:%" PRId64 " code:%s", tmq->consumerId, vgId,
|
||||
offset, tstrerror(code));
|
||||
|
||||
end:
|
||||
if (code != 0 && cb != NULL) {
|
||||
|
@ -2431,8 +2458,7 @@ int32_t askEpCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
SMqRspHead* head = pMsg->pData;
|
||||
int32_t epoch = atomic_load_32(&tmq->epoch);
|
||||
tscInfo("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d", tmq->consumerId,
|
||||
head->epoch, epoch);
|
||||
tscInfo("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d", tmq->consumerId, head->epoch, epoch);
|
||||
if (pParam->sync) {
|
||||
SMqAskEpRsp rsp = {0};
|
||||
tDecodeSMqAskEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &rsp);
|
||||
|
@ -2578,10 +2604,12 @@ int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet) {
|
|||
void commitRspCountDown(SMqCommitCbParamSet* pParamSet, int64_t consumerId, const char* pTopic, int32_t vgId) {
|
||||
int32_t waitingRspNum = atomic_sub_fetch_32(&pParamSet->waitingRspNum, 1);
|
||||
if (waitingRspNum == 0) {
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s vgId:%d all commit-rsp received, commit completed", consumerId, pTopic, vgId);
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s vgId:%d all commit-rsp received, commit completed", consumerId, pTopic,
|
||||
vgId);
|
||||
tmqCommitDone(pParamSet);
|
||||
} else {
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s vgId:%d commit-rsp received, remain:%d", consumerId, pTopic, vgId, waitingRspNum);
|
||||
tscInfo("consumer:0x%" PRIx64 " topic:%s vgId:%d commit-rsp received, remain:%d", consumerId, pTopic, vgId,
|
||||
waitingRspNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2590,7 +2618,8 @@ SReqResultInfo* tmqGetNextResInfo(TAOS_RES* res, bool convertUcs4) {
|
|||
pRspObj->resIter++;
|
||||
|
||||
if (pRspObj->resIter < pRspObj->rsp.blockNum) {
|
||||
SRetrieveTableRspForTmq* pRetrieveTmq = (SRetrieveTableRspForTmq*)taosArrayGetP(pRspObj->rsp.blockData, pRspObj->resIter);
|
||||
SRetrieveTableRspForTmq* pRetrieveTmq =
|
||||
(SRetrieveTableRspForTmq*)taosArrayGetP(pRspObj->rsp.blockData, pRspObj->resIter);
|
||||
if (pRspObj->rsp.withSchema) {
|
||||
SSchemaWrapper* pSW = (SSchemaWrapper*)taosArrayGetP(pRspObj->rsp.blockSchema, pRspObj->resIter);
|
||||
setResSchemaInfo(&pRspObj->resInfo, pSW->pSchema, pSW->nCols);
|
||||
|
@ -2856,13 +2885,15 @@ int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId){
|
|||
|
||||
SVgOffsetInfo* pOffsetInfo = &pVg->offsetInfo;
|
||||
if (isInSnapshotMode(pOffsetInfo->endOffset.type, tmq->useSnapshot)) {
|
||||
tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, committed error", tmq->consumerId, pOffsetInfo->endOffset.type);
|
||||
tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, committed error", tmq->consumerId,
|
||||
pOffsetInfo->endOffset.type);
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
return TSDB_CODE_TMQ_SNAPSHOT_ERROR;
|
||||
}
|
||||
|
||||
if (isInSnapshotMode(pOffsetInfo->committedOffset.type, tmq->useSnapshot)) {
|
||||
tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, committed error", tmq->consumerId, pOffsetInfo->committedOffset.type);
|
||||
tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, committed error", tmq->consumerId,
|
||||
pOffsetInfo->committedOffset.type);
|
||||
taosWUnLockLatch(&tmq->lock);
|
||||
return TSDB_CODE_TMQ_SNAPSHOT_ERROR;
|
||||
}
|
||||
|
@ -2939,8 +2970,8 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
|
|||
pAssignment->begin = pClientVg->offsetInfo.walVerBegin;
|
||||
pAssignment->end = pClientVg->offsetInfo.walVerEnd;
|
||||
pAssignment->vgId = pClientVg->vgId;
|
||||
tscInfo("consumer:0x%" PRIx64 " get assignment from local:%d->%" PRId64, tmq->consumerId,
|
||||
pAssignment->vgId, pAssignment->currentOffset);
|
||||
tscInfo("consumer:0x%" PRIx64 " get assignment from local:%d->%" PRId64, tmq->consumerId, pAssignment->vgId,
|
||||
pAssignment->currentOffset);
|
||||
}
|
||||
|
||||
if (needFetch) {
|
||||
|
@ -3049,7 +3080,8 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
|
|||
}
|
||||
|
||||
SVgOffsetInfo* pOffsetInfo = &pClientVg->offsetInfo;
|
||||
tscInfo("consumer:0x%" PRIx64 " %s vgId:%d offset is update to:%"PRId64, tmq->consumerId, pTopic->topicName, p->vgId, p->currentOffset);
|
||||
tscInfo("consumer:0x%" PRIx64 " %s vgId:%d offset is update to:%" PRId64, tmq->consumerId, pTopic->topicName,
|
||||
p->vgId, p->currentOffset);
|
||||
|
||||
pOffsetInfo->walVerBegin = p->begin;
|
||||
pOffsetInfo->walVerEnd = p->end;
|
||||
|
@ -3087,7 +3119,8 @@ static int32_t tmqSeekCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// seek interface have to send msg to server to cancel push handle if needed, because consumer may be in wait status if there is no data to poll
|
||||
// seek interface have to send msg to server to cancel push handle if needed, because consumer may be in wait status if
|
||||
// there is no data to poll
|
||||
int32_t tmq_offset_seek(tmq_t* tmq, const char* pTopicName, int32_t vgId, int64_t offset) {
|
||||
if (tmq == NULL || pTopicName == NULL) {
|
||||
tscError("invalid tmq handle, null");
|
||||
|
|
|
@ -1027,9 +1027,9 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
|
|||
* @return
|
||||
*/
|
||||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
|
||||
// | version | total length | total rows | total columns | flag seg| block group id | column schema
|
||||
// | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema
|
||||
// | each column length |
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) +
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) +
|
||||
numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
}
|
||||
|
||||
|
@ -1622,6 +1622,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
pBlock->info.capacity = 0;
|
||||
pBlock->info.rowSize = 0;
|
||||
pBlock->info.id = pDataBlock->info.id;
|
||||
pBlock->info.blankFill = pDataBlock->info.blankFill;
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
|
@ -2468,6 +2469,10 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) {
|
|||
// htonl(colSizes[col]), colSizes[col]);
|
||||
}
|
||||
|
||||
bool* blankFill = (bool*)data;
|
||||
*blankFill = pBlock->info.blankFill;
|
||||
data += sizeof(bool);
|
||||
|
||||
*actualLen = dataLen;
|
||||
*groupId = pBlock->info.id.groupId;
|
||||
ASSERT(dataLen > 0);
|
||||
|
@ -2561,8 +2566,12 @@ const char* blockDecode(SSDataBlock* pBlock, const char* pData) {
|
|||
pStart += colLen[i];
|
||||
}
|
||||
|
||||
bool blankFill = *(bool*)pStart;
|
||||
pStart += sizeof(bool);
|
||||
|
||||
pBlock->info.dataLoad = 1;
|
||||
pBlock->info.rows = numOfRows;
|
||||
pBlock->info.blankFill = blankFill;
|
||||
ASSERT(pStart - pData == dataLen);
|
||||
return pStart;
|
||||
}
|
||||
|
|
|
@ -1606,10 +1606,6 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) {
|
|||
tsTempSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsTempSpace.reserved);
|
||||
matched = true;
|
||||
} else if (strcasecmp("minimalDataDirGB", name) == 0) {
|
||||
tsDataSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsDataSpace.reserved);
|
||||
matched = true;
|
||||
} else if (strcasecmp("minimalLogDirGB", name) == 0) {
|
||||
tsLogSpace.reserved = (int64_t)(((double)pItem->fval) * 1024 * 1024 * 1024);
|
||||
uInfo("%s set to %" PRId64, name, tsLogSpace.reserved);
|
||||
|
@ -1680,10 +1676,6 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) {
|
|||
return -1;
|
||||
}
|
||||
matched = true;
|
||||
} else if (strcasecmp("telemetryServer", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, pItem->str, tsTelemServer);
|
||||
tstrncpy(tsTelemServer, pItem->str, TSDB_FQDN_LEN);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -699,6 +699,7 @@ typedef struct {
|
|||
int64_t checkpointId;
|
||||
|
||||
int32_t indexForMultiAggBalance;
|
||||
int8_t subTableWithoutMd5;
|
||||
char reserve[256];
|
||||
|
||||
} SStreamObj;
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define MND_STREAM_RESERVE_SIZE 64
|
||||
#define MND_STREAM_VER_NUMBER 4
|
||||
#define MND_STREAM_VER_NUMBER 5
|
||||
|
||||
#define MND_STREAM_CREATE_NAME "stream-create"
|
||||
#define MND_STREAM_CHECKPOINT_NAME "stream-checkpoint"
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndConsumer.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndSubscribe.h"
|
||||
#include "mndTopic.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "tcompare.h"
|
||||
#include "tname.h"
|
||||
|
||||
|
@ -71,7 +71,8 @@ void mndCleanupConsumer(SMnode *pMnode) {}
|
|||
void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId, SRpcHandleInfo *info) {
|
||||
SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg));
|
||||
if (pClearMsg == NULL) {
|
||||
mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d", consumerId, (int32_t)sizeof(SMqConsumerClearMsg));
|
||||
mError("consumer:0x%" PRIx64 " failed to clear consumer due to out of memory. alloc size:%d", consumerId,
|
||||
(int32_t)sizeof(SMqConsumerClearMsg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -88,7 +89,8 @@ void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId, SRpcHandleInfo*
|
|||
return;
|
||||
}
|
||||
|
||||
static int32_t validateTopics(STrans *pTrans, const SArray *pTopicList, SMnode *pMnode, const char *pUser, bool enableReplay) {
|
||||
static int32_t validateTopics(STrans *pTrans, const SArray *pTopicList, SMnode *pMnode, const char *pUser,
|
||||
bool enableReplay) {
|
||||
SMqTopicObj *pTopic = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -503,7 +505,6 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
|||
pHead->walsver = 0;
|
||||
pHead->walever = 0;
|
||||
|
||||
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
tEncodeSMqAskEpRsp(&abuf, &rsp);
|
||||
|
||||
|
@ -552,11 +553,6 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
char *msgStr = pMsg->pCont;
|
||||
int32_t code = -1;
|
||||
|
||||
if ((terrno = grantCheck(TSDB_GRANT_SUBSCRIPTION)) < 0) {
|
||||
code = terrno;
|
||||
return code;
|
||||
}
|
||||
|
||||
SCMSubscribeReq subscribe = {0};
|
||||
tDeserializeSCMSubscribeReq(msgStr, &subscribe);
|
||||
|
||||
|
@ -566,7 +562,6 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
SMqConsumerObj *pConsumerNew = NULL;
|
||||
STrans *pTrans = NULL;
|
||||
|
||||
|
||||
SArray *pTopicList = subscribe.topicNames;
|
||||
taosArraySort(pTopicList, taosArrayCompareString);
|
||||
taosArrayRemoveDuplicate(pTopicList, taosArrayCompareString, freeItem);
|
||||
|
@ -792,9 +787,8 @@ CM_DECODE_OVER:
|
|||
}
|
||||
|
||||
static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer) {
|
||||
mInfo("consumer:0x%" PRIx64 " sub insert, cgroup:%s status:%d(%s) epoch:%d",
|
||||
pConsumer->consumerId, pConsumer->cgroup, pConsumer->status, mndConsumerStatusName(pConsumer->status),
|
||||
pConsumer->epoch);
|
||||
mInfo("consumer:0x%" PRIx64 " sub insert, cgroup:%s status:%d(%s) epoch:%d", pConsumer->consumerId, pConsumer->cgroup,
|
||||
pConsumer->status, mndConsumerStatusName(pConsumer->status), pConsumer->epoch);
|
||||
pConsumer->subscribeTime = pConsumer->createTime;
|
||||
return 0;
|
||||
}
|
||||
|
@ -903,9 +897,11 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
|||
//
|
||||
// int32_t prevStatus = pOldConsumer->status;
|
||||
// pOldConsumer->status = MQ_CONSUMER_STATUS_LOST;
|
||||
// mInfo("consumer:0x%" PRIx64 " timer update, timer lost. state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d",
|
||||
// pOldConsumer->consumerId, mndConsumerStatusName(prevStatus), mndConsumerStatusName(pOldConsumer->status),
|
||||
// pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics));
|
||||
// mInfo("consumer:0x%" PRIx64 " timer update, timer lost. state %s -> %s, reb-time:%" PRId64 ",
|
||||
// reb-removed-topics:%d",
|
||||
// pOldConsumer->consumerId, mndConsumerStatusName(prevStatus),
|
||||
// mndConsumerStatusName(pOldConsumer->status), pOldConsumer->rebalanceTime,
|
||||
// (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics));
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE_REC) {
|
||||
int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
|
@ -1091,7 +1087,8 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *
|
|||
tFormatOffset(buf, TSDB_OFFSET_LEN, &pVal);
|
||||
|
||||
char parasStr[64 + TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
sprintf(varDataVal(parasStr), "tbname:%d,commit:%d,interval:%dms,reset:%s", pConsumer->withTbName, pConsumer->autoCommit, pConsumer->autoCommitInterval, buf);
|
||||
sprintf(varDataVal(parasStr), "tbname:%d,commit:%d,interval:%dms,reset:%s", pConsumer->withTbName,
|
||||
pConsumer->autoCommit, pConsumer->autoCommitInterval, buf);
|
||||
varDataSetLen(parasStr, strlen(varDataVal(parasStr)));
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
|
|
|
@ -85,6 +85,7 @@ int32_t tEncodeSStreamObj(SEncoder *pEncoder, const SStreamObj *pObj) {
|
|||
|
||||
// 3.0.50 ver = 3
|
||||
if (tEncodeI64(pEncoder, pObj->checkpointId) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pObj->subTableWithoutMd5) < 0) return -1;
|
||||
|
||||
if (tEncodeCStrWithLen(pEncoder, pObj->reserve, sizeof(pObj->reserve) - 1) < 0) return -1;
|
||||
|
||||
|
@ -168,6 +169,10 @@ int32_t tDecodeSStreamObj(SDecoder *pDecoder, SStreamObj *pObj, int32_t sver) {
|
|||
if (sver >= 3) {
|
||||
if (tDecodeI64(pDecoder, &pObj->checkpointId) < 0) return -1;
|
||||
}
|
||||
|
||||
if (sver >= 5) {
|
||||
if (tDecodeI8(pDecoder, &pObj->subTableWithoutMd5) < 0) return -1;
|
||||
}
|
||||
if (tDecodeCStrTo(pDecoder, pObj->reserve) < 0) return -1;
|
||||
|
||||
tEndDecode(pDecoder);
|
||||
|
|
|
@ -14,19 +14,41 @@
|
|||
*/
|
||||
|
||||
#include "mndScheduler.h"
|
||||
#include "tmisce.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndSnode.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "parser.h"
|
||||
#include "tcompare.h"
|
||||
#include "tmisce.h"
|
||||
#include "tname.h"
|
||||
#include "tuuid.h"
|
||||
|
||||
#define SINK_NODE_LEVEL (0)
|
||||
extern bool tsDeployOnSnode;
|
||||
|
||||
static bool hasCountWindowNode(SPhysiNode* pNode) {
|
||||
if (nodeType(pNode) == QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT) {
|
||||
return true;
|
||||
} else {
|
||||
size_t size = LIST_LENGTH(pNode->pChildren);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SPhysiNode* pChild = (SPhysiNode*)nodesListGetNode(pNode->pChildren, i);
|
||||
if (hasCountWindowNode(pChild)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool countWindowStreamTask(SSubplan* pPlan) {
|
||||
SPhysiNode* pNode = pPlan->pNode;
|
||||
return hasCountWindowNode(pNode);
|
||||
}
|
||||
|
||||
int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64_t uid, int8_t triggerType,
|
||||
int64_t watermark, int64_t deleteMark) {
|
||||
SNode* pAst = NULL;
|
||||
|
@ -217,12 +239,12 @@ SVgObj* mndSchedFetchOneVg(SMnode* pMnode, SStreamObj* pStream) {
|
|||
return pVgroup;
|
||||
}
|
||||
|
||||
static int32_t doAddSinkTask(SStreamObj* pStream, SMnode* pMnode, SVgObj* pVgroup,
|
||||
SEpSet* pEpset, bool isFillhistory) {
|
||||
static int32_t doAddSinkTask(SStreamObj* pStream, SMnode* pMnode, SVgObj* pVgroup, SEpSet* pEpset, bool isFillhistory) {
|
||||
int64_t uid = (isFillhistory) ? pStream->hTaskUid : pStream->uid;
|
||||
SArray** pTaskList = (isFillhistory) ? taosArrayGetLast(pStream->pHTasksList) : taosArrayGetLast(pStream->tasks);
|
||||
|
||||
SStreamTask* pTask = tNewStreamTask(uid, TASK_LEVEL__SINK, pEpset, isFillhistory, 0, *pTaskList, pStream->conf.fillHistory);
|
||||
SStreamTask* pTask = tNewStreamTask(uid, TASK_LEVEL__SINK, pEpset, isFillhistory, 0, *pTaskList,
|
||||
pStream->conf.fillHistory, pStream->subTableWithoutMd5);
|
||||
if (pTask == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return terrno;
|
||||
|
@ -315,19 +337,29 @@ static void streamTaskSetDataRange(SStreamTask* pTask, int64_t skey, SArray* pVe
|
|||
pRange->range.minVer = latestVer + 1;
|
||||
pRange->range.maxVer = INT64_MAX;
|
||||
|
||||
mDebug("add source task 0x%x timeWindow:%" PRId64 "-%" PRId64 " verRange:%" PRId64 "-%" PRId64,
|
||||
pTask->id.taskId, pWindow->skey, pWindow->ekey, pRange->range.minVer, pRange->range.maxVer);
|
||||
mDebug("add source task 0x%x timeWindow:%" PRId64 "-%" PRId64 " verRange:%" PRId64 "-%" PRId64, pTask->id.taskId,
|
||||
pWindow->skey, pWindow->ekey, pRange->range.minVer, pRange->range.maxVer);
|
||||
}
|
||||
}
|
||||
|
||||
static SStreamTask* buildSourceTask(SStreamObj* pStream, SEpSet* pEpset,
|
||||
bool isFillhistory, bool useTriggerParam) {
|
||||
static void haltInitialTaskStatus(SStreamTask* pTask, SSubplan* pPlan) {
|
||||
bool hasCountWindowNode = countWindowStreamTask(pPlan);
|
||||
bool isRelStreamTask = (pTask->hTaskInfo.id.taskId != 0);
|
||||
if (hasCountWindowNode && isRelStreamTask) {
|
||||
SStreamStatus* pStatus = &pTask->status;
|
||||
mDebug("s-task:0x%x status is set to %s from %s for count window agg task with fill-history option set",
|
||||
pTask->id.taskId, streamTaskGetStatusStr(pStatus->taskStatus), streamTaskGetStatusStr(TASK_STATUS__HALT));
|
||||
pStatus->taskStatus = TASK_STATUS__HALT;
|
||||
}
|
||||
}
|
||||
|
||||
static SStreamTask* buildSourceTask(SStreamObj* pStream, SEpSet* pEpset, bool isFillhistory, bool useTriggerParam) {
|
||||
uint64_t uid = (isFillhistory) ? pStream->hTaskUid : pStream->uid;
|
||||
SArray** pTaskList = (isFillhistory) ? taosArrayGetLast(pStream->pHTasksList) : taosArrayGetLast(pStream->tasks);
|
||||
|
||||
SStreamTask* pTask = tNewStreamTask(uid, TASK_LEVEL__SOURCE, pEpset,
|
||||
isFillhistory, useTriggerParam ? pStream->conf.triggerParam : 0,
|
||||
*pTaskList, pStream->conf.fillHistory);
|
||||
SStreamTask* pTask =
|
||||
tNewStreamTask(uid, TASK_LEVEL__SOURCE, pEpset, isFillhistory, useTriggerParam ? pStream->conf.triggerParam : 0,
|
||||
*pTaskList, pStream->conf.fillHistory, pStream->subTableWithoutMd5);
|
||||
if (pTask == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -364,8 +396,8 @@ static void setHTasksId(SStreamObj* pStream) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t doAddSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStream, SEpSet* pEpset,
|
||||
int64_t skey, SArray* pVerList, SVgObj* pVgroup, bool isFillhistory, bool useTriggerParam ){
|
||||
static int32_t doAddSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStream, SEpSet* pEpset, int64_t skey,
|
||||
SArray* pVerList, SVgObj* pVgroup, bool isFillhistory, bool useTriggerParam) {
|
||||
// new stream task
|
||||
SStreamTask* pTask = buildSourceTask(pStream, pEpset, isFillhistory, useTriggerParam);
|
||||
if (pTask == NULL) {
|
||||
|
@ -374,6 +406,8 @@ static int32_t doAddSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStre
|
|||
}
|
||||
mDebug("doAddSourceTask taskId:%s, vgId:%d, isFillHistory:%d", pTask->id.idStr, pVgroup->vgId, isFillhistory);
|
||||
|
||||
haltInitialTaskStatus(pTask, plan);
|
||||
|
||||
streamTaskSetDataRange(pTask, skey, pVerList, pVgroup->vgId);
|
||||
|
||||
int32_t code = mndAssignStreamTaskToVgroup(pMnode, pTask, plan, pVgroup);
|
||||
|
@ -415,8 +449,8 @@ static SSubplan* getAggSubPlan(const SQueryPlan* pPlan, int index){
|
|||
return plan;
|
||||
}
|
||||
|
||||
static int32_t addSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStream,
|
||||
SEpSet* pEpset, int64_t nextWindowSkey, SArray* pVerList, bool useTriggerParam) {
|
||||
static int32_t addSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStream, SEpSet* pEpset,
|
||||
int64_t nextWindowSkey, SArray* pVerList, bool useTriggerParam) {
|
||||
addNewTaskList(pStream);
|
||||
|
||||
void* pIter = NULL;
|
||||
|
@ -433,7 +467,8 @@ static int32_t addSourceTask(SMnode* pMnode, SSubplan* plan, SStreamObj* pStream
|
|||
continue;
|
||||
}
|
||||
|
||||
int code = doAddSourceTask(pMnode, plan, pStream, pEpset, nextWindowSkey, pVerList, pVgroup, false, useTriggerParam);
|
||||
int code =
|
||||
doAddSourceTask(pMnode, plan, pStream, pEpset, nextWindowSkey, pVerList, pVgroup, false, useTriggerParam);
|
||||
if (code != 0) {
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
return code;
|
||||
|
@ -461,9 +496,9 @@ static SStreamTask* buildAggTask(SStreamObj* pStream, SEpSet* pEpset, bool isFil
|
|||
uint64_t uid = (isFillhistory) ? pStream->hTaskUid : pStream->uid;
|
||||
SArray** pTaskList = (isFillhistory) ? taosArrayGetLast(pStream->pHTasksList) : taosArrayGetLast(pStream->tasks);
|
||||
|
||||
SStreamTask* pAggTask = tNewStreamTask(uid, TASK_LEVEL__AGG, pEpset, isFillhistory,
|
||||
useTriggerParam ? pStream->conf.triggerParam : 0,
|
||||
*pTaskList, pStream->conf.fillHistory);
|
||||
SStreamTask* pAggTask =
|
||||
tNewStreamTask(uid, TASK_LEVEL__AGG, pEpset, isFillhistory, useTriggerParam ? pStream->conf.triggerParam : 0,
|
||||
*pTaskList, pStream->conf.fillHistory, pStream->subTableWithoutMd5);
|
||||
if (pAggTask == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
|
@ -472,8 +507,8 @@ static SStreamTask* buildAggTask(SStreamObj* pStream, SEpSet* pEpset, bool isFil
|
|||
return pAggTask;
|
||||
}
|
||||
|
||||
static int32_t doAddAggTask(SStreamObj* pStream, SMnode* pMnode, SSubplan* plan, SEpSet* pEpset,
|
||||
SVgObj* pVgroup, SSnodeObj* pSnode, bool isFillhistory, bool useTriggerParam){
|
||||
static int32_t doAddAggTask(SStreamObj* pStream, SMnode* pMnode, SSubplan* plan, SEpSet* pEpset, SVgObj* pVgroup,
|
||||
SSnodeObj* pSnode, bool isFillhistory, bool useTriggerParam) {
|
||||
int32_t code = 0;
|
||||
SStreamTask* pTask = buildAggTask(pStream, pEpset, isFillhistory, useTriggerParam);
|
||||
if (pTask == NULL) {
|
||||
|
@ -616,8 +651,8 @@ static int32_t doScheduleStream(SStreamObj* pStream, SMnode* pMnode, SQueryPlan*
|
|||
bool multiTarget = (pDbObj->cfg.numOfVgroups > 1);
|
||||
sdbRelease(pSdb, pDbObj);
|
||||
|
||||
mDebug("doScheduleStream numOfPlanLevel:%d, exDb:%d, multiTarget:%d, fix vgId:%d, physicalPlan:%s",
|
||||
numOfPlanLevel, externalTargetDB, multiTarget, pStream->fixedSinkVgId, pStream->physicalPlan);
|
||||
mDebug("doScheduleStream numOfPlanLevel:%d, exDb:%d, multiTarget:%d, fix vgId:%d, physicalPlan:%s", numOfPlanLevel,
|
||||
externalTargetDB, multiTarget, pStream->fixedSinkVgId, pStream->physicalPlan);
|
||||
pStream->tasks = taosArrayInit(numOfPlanLevel + 1, POINTER_BYTES);
|
||||
pStream->pHTasksList = taosArrayInit(numOfPlanLevel + 1, POINTER_BYTES);
|
||||
|
||||
|
|
|
@ -567,6 +567,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
|
|||
streamObj.conf.triggerParam = pCreate->maxDelay;
|
||||
streamObj.ast = taosStrdup(smaObj.ast);
|
||||
streamObj.indexForMultiAggBalance = -1;
|
||||
streamObj.subTableWithoutMd5 = 1;
|
||||
|
||||
// check the maxDelay
|
||||
if (streamObj.conf.triggerParam < TSDB_MIN_ROLLUP_MAX_DELAY) {
|
||||
|
|
|
@ -152,7 +152,7 @@ SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw) {
|
|||
goto STREAM_DECODE_OVER;
|
||||
}
|
||||
|
||||
if (sver != MND_STREAM_VER_NUMBER) {
|
||||
if (sver < 1 || sver > MND_STREAM_VER_NUMBER) {
|
||||
terrno = 0;
|
||||
mError("stream read invalid ver, data ver: %d, curr ver: %d", sver, MND_STREAM_VER_NUMBER);
|
||||
goto STREAM_DECODE_OVER;
|
||||
|
@ -634,7 +634,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((terrno = grantCheck(TSDB_GRANT_STREAMS)) < 0) {
|
||||
goto _OVER;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
SCMCreateStreamReq createReq = {0};
|
||||
|
@ -802,8 +802,7 @@ static int32_t mndProcessStreamCheckpointTmr(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
static int32_t mndBuildStreamCheckpointSourceReq(void **pBuf, int32_t *pLen, int32_t nodeId, int64_t checkpointId,
|
||||
int64_t streamId, int32_t taskId, int32_t transId,
|
||||
int8_t mndTrigger) {
|
||||
int64_t streamId, int32_t taskId, int32_t transId, int8_t mndTrigger) {
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
req.checkpointId = checkpointId;
|
||||
req.nodeId = nodeId;
|
||||
|
@ -882,7 +881,6 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_CHECKPOINT_NAME, lock);
|
||||
if (conflict) {
|
||||
mndAddtoCheckpointWaitingList(pStream, checkpointId);
|
||||
|
|
|
@ -564,6 +564,10 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) {
|
|||
return code;
|
||||
}
|
||||
|
||||
if ((terrno = grantCheck(TSDB_GRANT_SUBSCRIPTION)) < 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (tDeserializeSCMCreateTopicReq(pReq->pCont, pReq->contLen, &createTopicReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto _OVER;
|
||||
|
|
|
@ -85,8 +85,9 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t nextProcessVer
|
|||
|
||||
SCheckpointInfo *pChkInfo = &pTask->chkInfo;
|
||||
// checkpoint ver is the kept version, handled data should be the next version.
|
||||
if (pTask->chkInfo.checkpointId != 0) {
|
||||
pTask->chkInfo.nextProcessVer = pTask->chkInfo.checkpointVer + 1;
|
||||
if (pChkInfo->checkpointId != 0) {
|
||||
pChkInfo->nextProcessVer = pChkInfo->checkpointVer + 1;
|
||||
pChkInfo->processedVer = pChkInfo->checkpointVer;
|
||||
sndInfo("s-task:%s restore from the checkpointId:%" PRId64 " ver:%" PRId64 " nextProcessVer:%" PRId64,
|
||||
pTask->id.idStr, pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer);
|
||||
}
|
||||
|
|
|
@ -67,12 +67,17 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->streamStateSessionPut = streamStateSessionPut;
|
||||
pStore->streamStateSessionGet = streamStateSessionGet;
|
||||
pStore->streamStateSessionDel = streamStateSessionDel;
|
||||
pStore->streamStateSessionReset = streamStateSessionReset;
|
||||
pStore->streamStateSessionClear = streamStateSessionClear;
|
||||
pStore->streamStateSessionGetKVByCur = streamStateSessionGetKVByCur;
|
||||
pStore->streamStateStateAddIfNotExist = streamStateStateAddIfNotExist;
|
||||
pStore->streamStateSessionGetKeyByRange = streamStateSessionGetKeyByRange;
|
||||
pStore->streamStateCountGetKeyByRange = streamStateCountGetKeyByRange;
|
||||
pStore->streamStateSessionAllocWinBuffByNextPosition = streamStateSessionAllocWinBuffByNextPosition;
|
||||
|
||||
pStore->streamStateCountWinAddIfNotExist = streamStateCountWinAddIfNotExist;
|
||||
pStore->streamStateCountWinAdd = streamStateCountWinAdd;
|
||||
|
||||
pStore->updateInfoInit = updateInfoInit;
|
||||
pStore->updateInfoFillBlockData = updateInfoFillBlockData;
|
||||
pStore->updateInfoIsUpdated = updateInfoIsUpdated;
|
||||
|
@ -89,6 +94,7 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->updateInfoDeserialize = updateInfoDeserialize;
|
||||
|
||||
pStore->streamStateSessionSeekKeyNext = streamStateSessionSeekKeyNext;
|
||||
pStore->streamStateCountSeekKeyPrev = streamStateCountSeekKeyPrev;
|
||||
pStore->streamStateSessionSeekKeyCurrentPrev = streamStateSessionSeekKeyCurrentPrev;
|
||||
pStore->streamStateSessionSeekKeyCurrentNext = streamStateSessionSeekKeyCurrentNext;
|
||||
|
||||
|
|
|
@ -214,6 +214,13 @@ int32_t tsdbBegin(STsdb* pTsdb);
|
|||
// int32_t tsdbPrepareCommit(STsdb* pTsdb);
|
||||
// int32_t tsdbCommit(STsdb* pTsdb, SCommitInfo* pInfo);
|
||||
int32_t tsdbCacheCommit(STsdb* pTsdb);
|
||||
int32_t tsdbCacheNewTable(STsdb* pTsdb, int64_t uid, tb_uid_t suid, SSchemaWrapper* pSchemaRow);
|
||||
int32_t tsdbCacheDropTable(STsdb* pTsdb, int64_t uid, tb_uid_t suid, SSchemaWrapper* pSchemaRow);
|
||||
int32_t tsdbCacheDropSubTables(STsdb* pTsdb, SArray* uids, tb_uid_t suid);
|
||||
int32_t tsdbCacheNewSTableColumn(STsdb* pTsdb, SArray* uids, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb* pTsdb, SArray* uids, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheNewNTableColumn(STsdb* pTsdb, int64_t uid, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb* pTsdb, int64_t uid, int16_t cid, int8_t col_type);
|
||||
int32_t tsdbCompact(STsdb* pTsdb, SCompactInfo* pInfo);
|
||||
int32_t tsdbRetention(STsdb* tsdb, int64_t now, int32_t sync);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, SSubmitReq2* pMsg);
|
||||
|
|
|
@ -96,10 +96,6 @@ int32_t metaSnapRead(SMetaSnapReader* pReader, uint8_t** ppData) {
|
|||
continue;
|
||||
}
|
||||
|
||||
tdbTbcMoveToNext(pReader->pTbc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pData || !nData) {
|
||||
metaError("meta/snap: invalide nData: %" PRId32 " meta snap read failed.", nData);
|
||||
goto _exit;
|
||||
|
@ -119,6 +115,10 @@ int32_t metaSnapRead(SMetaSnapReader* pReader, uint8_t** ppData) {
|
|||
metaDebug("vgId:%d, vnode snapshot meta read data, version:%" PRId64 " uid:%" PRId64 " blockLen:%d",
|
||||
TD_VID(pReader->pMeta->pVnode), key.version, key.uid, nData);
|
||||
|
||||
tdbTbcMoveToNext(pReader->pTbc);
|
||||
break;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
|
||||
|
@ -619,7 +619,8 @@ SMetaTableInfo getMetaTableInfoFromSnapshot(SSnapContext* ctx) {
|
|||
|
||||
int32_t ret = MoveToPosition(ctx, idInfo->version, *uidTmp);
|
||||
if (ret != 0) {
|
||||
metaDebug("tmqsnap getMetaTableInfoFromSnapshot not exist uid:%" PRIi64 " version:%" PRIi64, *uidTmp, idInfo->version);
|
||||
metaDebug("tmqsnap getMetaTableInfoFromSnapshot not exist uid:%" PRIi64 " version:%" PRIi64, *uidTmp,
|
||||
idInfo->version);
|
||||
continue;
|
||||
}
|
||||
tdbTbcGet((TBC*)ctx->pCur, (const void**)&pKey, &kLen, (const void**)&pVal, &vLen);
|
||||
|
|
|
@ -303,6 +303,8 @@ int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq, SArray *tb
|
|||
|
||||
tdbTbcClose(pCtbIdxc);
|
||||
|
||||
(void)tsdbCacheDropSubTables(pMeta->pVnode->pTsdb, tbUidList, pReq->suid);
|
||||
|
||||
metaWLock(pMeta);
|
||||
|
||||
for (int32_t iChild = 0; iChild < taosArrayGetSize(tbUidList); iChild++) {
|
||||
|
@ -334,6 +336,40 @@ _exit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void metaGetSubtables(SMeta *pMeta, int64_t suid, SArray *uids) {
|
||||
if (!uids) return;
|
||||
|
||||
int c = 0;
|
||||
void *pKey = NULL;
|
||||
int nKey = 0;
|
||||
TBC *pCtbIdxc = NULL;
|
||||
|
||||
tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, NULL);
|
||||
int rc = tdbTbcMoveTo(pCtbIdxc, &(SCtbIdxKey){.suid = suid, .uid = INT64_MIN}, sizeof(SCtbIdxKey), &c);
|
||||
if (rc < 0) {
|
||||
tdbTbcClose(pCtbIdxc);
|
||||
metaWLock(pMeta);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
rc = tdbTbcNext(pCtbIdxc, &pKey, &nKey, NULL, NULL);
|
||||
if (rc < 0) break;
|
||||
|
||||
if (((SCtbIdxKey *)pKey)->suid < suid) {
|
||||
continue;
|
||||
} else if (((SCtbIdxKey *)pKey)->suid > suid) {
|
||||
break;
|
||||
}
|
||||
|
||||
taosArrayPush(uids, &(((SCtbIdxKey *)pKey)->uid));
|
||||
}
|
||||
|
||||
tdbFree(pKey);
|
||||
|
||||
tdbTbcClose(pCtbIdxc);
|
||||
}
|
||||
|
||||
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
||||
SMetaEntry oStbEntry = {0};
|
||||
SMetaEntry nStbEntry = {0};
|
||||
|
@ -397,9 +433,39 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
nStbEntry.stbEntry.schemaRow = pReq->schemaRow;
|
||||
nStbEntry.stbEntry.schemaTag = pReq->schemaTag;
|
||||
|
||||
int32_t deltaCol = pReq->schemaRow.nCols - oStbEntry.stbEntry.schemaRow.nCols;
|
||||
int nCols = pReq->schemaRow.nCols;
|
||||
int onCols = oStbEntry.stbEntry.schemaRow.nCols;
|
||||
int32_t deltaCol = nCols - onCols;
|
||||
bool updStat = deltaCol != 0 && !metaTbInFilterCache(pMeta, pReq->name, 1);
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
STsdb *pTsdb = pMeta->pVnode->pTsdb;
|
||||
SArray *uids = taosArrayInit(8, sizeof(int64_t));
|
||||
if (deltaCol == 1) {
|
||||
int16_t cid = pReq->schemaRow.pSchema[nCols - 1].colId;
|
||||
int8_t col_type = pReq->schemaRow.pSchema[nCols - 1].type;
|
||||
|
||||
metaGetSubtables(pMeta, pReq->suid, uids);
|
||||
tsdbCacheNewSTableColumn(pTsdb, uids, cid, col_type);
|
||||
} else if (deltaCol == -1) {
|
||||
int16_t cid = -1;
|
||||
int8_t col_type = -1;
|
||||
for (int i = 0, j = 0; i < nCols && j < onCols; ++i, ++j) {
|
||||
if (pReq->schemaRow.pSchema[i].colId != oStbEntry.stbEntry.schemaRow.pSchema[j].colId) {
|
||||
cid = oStbEntry.stbEntry.schemaRow.pSchema[j].colId;
|
||||
col_type = oStbEntry.stbEntry.schemaRow.pSchema[j].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid != -1) {
|
||||
metaGetSubtables(pMeta, pReq->suid, uids);
|
||||
tsdbCacheDropSTableColumn(pTsdb, uids, cid, col_type);
|
||||
}
|
||||
}
|
||||
if (uids) taosArrayDestroy(uids);
|
||||
}
|
||||
|
||||
metaWLock(pMeta);
|
||||
// compare two entry
|
||||
if (oStbEntry.stbEntry.schemaRow.version != pReq->schemaRow.version) {
|
||||
|
@ -822,6 +888,10 @@ int metaCreateTable(SMeta *pMeta, int64_t ver, SVCreateTbReq *pReq, STableMetaRs
|
|||
metaUidCacheClear(pMeta, me.ctbEntry.suid);
|
||||
metaTbGroupCacheClear(pMeta, me.ctbEntry.suid);
|
||||
metaULock(pMeta);
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheNewTable(pMeta->pVnode->pTsdb, me.uid, me.ctbEntry.suid, NULL);
|
||||
}
|
||||
} else {
|
||||
me.ntbEntry.btime = pReq->btime;
|
||||
me.ntbEntry.ttlDays = pReq->ttl;
|
||||
|
@ -832,6 +902,10 @@ int metaCreateTable(SMeta *pMeta, int64_t ver, SVCreateTbReq *pReq, STableMetaRs
|
|||
|
||||
++pStats->numOfNTables;
|
||||
pStats->numOfNTimeSeries += me.ntbEntry.schemaRow.nCols - 1;
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheNewTable(pMeta->pVnode->pTsdb, me.uid, -1, &me.ntbEntry.schemaRow);
|
||||
}
|
||||
}
|
||||
|
||||
if (metaHandleEntry(pMeta, &me) < 0) goto _err;
|
||||
|
@ -896,6 +970,10 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUi
|
|||
|
||||
if ((type == TSDB_CHILD_TABLE || type == TSDB_NORMAL_TABLE) && tbUids) {
|
||||
taosArrayPush(tbUids, &uid);
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheDropTable(pMeta->pVnode->pTsdb, uid, suid, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if ((type == TSDB_CHILD_TABLE) && tbUid) {
|
||||
|
@ -930,6 +1008,11 @@ void metaDropTables(SMeta *pMeta, SArray *tbUids) {
|
|||
}
|
||||
tSimpleHashPut(suidHash, &suid, sizeof(tb_uid_t), &nCtbDropped, sizeof(int64_t));
|
||||
}
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheDropTable(pMeta->pVnode->pTsdb, uid, suid, NULL);
|
||||
}
|
||||
|
||||
metaDebug("batch drop table:%" PRId64, uid);
|
||||
}
|
||||
metaULock(pMeta);
|
||||
|
@ -1172,11 +1255,22 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *p
|
|||
metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1, 0);
|
||||
metaUidCacheClear(pMeta, e.ctbEntry.suid);
|
||||
metaTbGroupCacheClear(pMeta, e.ctbEntry.suid);
|
||||
/*
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, e.ctbEntry.suid, NULL);
|
||||
}
|
||||
*/
|
||||
} else if (e.type == TSDB_NORMAL_TABLE) {
|
||||
// drop schema.db (todo)
|
||||
|
||||
--pMeta->pVnode->config.vndStats.numOfNTables;
|
||||
pMeta->pVnode->config.vndStats.numOfNTimeSeries -= e.ntbEntry.schemaRow.nCols - 1;
|
||||
|
||||
/*
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
tsdbCacheDropTable(pMeta->pVnode->pTsdb, e.uid, -1, &e.ntbEntry.schemaRow);
|
||||
}
|
||||
*/
|
||||
} else if (e.type == TSDB_SUPER_TABLE) {
|
||||
tdbTbDelete(pMeta->pSuidIdx, &e.uid, sizeof(tb_uid_t), pMeta->txn);
|
||||
// drop schema.db (todo)
|
||||
|
@ -1364,6 +1458,12 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
|
||||
++pMeta->pVnode->config.vndStats.numOfNTimeSeries;
|
||||
metaTimeSeriesNotifyCheck(pMeta);
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
int16_t cid = pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].colId;
|
||||
int8_t col_type = pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].type;
|
||||
(void)tsdbCacheNewNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, col_type);
|
||||
}
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_DROP_COLUMN:
|
||||
if (pColumn == NULL) {
|
||||
|
@ -1386,6 +1486,13 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
|
|||
pSchema->nCols--;
|
||||
|
||||
--pMeta->pVnode->config.vndStats.numOfNTimeSeries;
|
||||
|
||||
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
|
||||
int16_t cid = pColumn->colId;
|
||||
int8_t col_type = pColumn->type;
|
||||
|
||||
(void)tsdbCacheDropNTableColumn(pMeta->pVnode->pTsdb, entry.uid, cid, col_type);
|
||||
}
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
|
||||
if (pColumn == NULL) {
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
#include "tq.h"
|
||||
#include "vnd.h"
|
||||
#include "tqCommon.h"
|
||||
#include "vnd.h"
|
||||
|
||||
// 0: not init
|
||||
// 1: already inited
|
||||
|
@ -835,36 +835,37 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t nextProcessVer) {
|
|||
// checkpoint ver is the kept version, handled data should be the next version.
|
||||
if (pChkInfo->checkpointId != 0) {
|
||||
pChkInfo->nextProcessVer = pChkInfo->checkpointVer + 1;
|
||||
pChkInfo->processedVer = pChkInfo->checkpointVer;
|
||||
tqInfo("s-task:%s restore from the checkpointId:%" PRId64 " ver:%" PRId64 " currentVer:%" PRId64, pTask->id.idStr,
|
||||
pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer);
|
||||
}
|
||||
|
||||
char* p = streamTaskGetStatus(pTask)->name;
|
||||
const char* pNext = streamTaskGetStatusStr(pTask->status.taskStatus);
|
||||
|
||||
if (pTask->info.fillHistory) {
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpointId:%" PRId64 " checkpointVer:%" PRId64
|
||||
" nextProcessVer:%" PRId64
|
||||
" child id:%d, level:%d, status:%s fill-history:%d, related stream task:0x%x trigger:%" PRId64
|
||||
" ms, inputVer:%" PRId64,
|
||||
" child id:%d, level:%d, cur-status:%s, next-status:%s fill-history:%d, related stream task:0x%x "
|
||||
"trigger:%" PRId64 " ms, inputVer:%" PRId64,
|
||||
vgId, pTask->id.idStr, pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer,
|
||||
pTask->info.selfChildId, pTask->info.taskLevel, p, pTask->info.fillHistory,
|
||||
pTask->info.selfChildId, pTask->info.taskLevel, p, pNext, pTask->info.fillHistory,
|
||||
(int32_t)pTask->streamTaskId.taskId, pTask->info.triggerParam, nextProcessVer);
|
||||
} else {
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpointId:%" PRId64 " checkpointVer:%" PRId64
|
||||
tqInfo(
|
||||
"vgId:%d expand stream task, s-task:%s, checkpointId:%" PRId64 " checkpointVer:%" PRId64
|
||||
" nextProcessVer:%" PRId64
|
||||
" child id:%d, level:%d, status:%s fill-history:%d, related fill-task:0x%x trigger:%" PRId64
|
||||
" child id:%d, level:%d, cur-status:%s next-status:%s fill-history:%d, related fill-task:0x%x trigger:%" PRId64
|
||||
" ms, inputVer:%" PRId64,
|
||||
vgId, pTask->id.idStr, pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer,
|
||||
pTask->info.selfChildId, pTask->info.taskLevel, p, pTask->info.fillHistory,
|
||||
pTask->info.selfChildId, pTask->info.taskLevel, p, pNext, pTask->info.fillHistory,
|
||||
(int32_t)pTask->hTaskInfo.id.taskId, pTask->info.triggerParam, nextProcessVer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
return tqStreamTaskProcessCheckReq(pTq->pStreamMeta, pMsg);
|
||||
}
|
||||
int32_t tqProcessTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) { return tqStreamTaskProcessCheckReq(pTq->pStreamMeta, pMsg); }
|
||||
|
||||
int32_t tqProcessTaskCheckRsp(STQ* pTq, SRpcMsg* pMsg) {
|
||||
return tqStreamTaskProcessCheckRsp(pTq->pStreamMeta, pMsg, vnodeIsRoleLeader(pTq->pVnode));
|
||||
|
@ -1015,8 +1016,8 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqError("failed to find s-task:0x%" PRIx64 ", it may have been destroyed, drop related fill-history task:%s",
|
||||
pTask->streamTaskId.taskId, pTask->id.idStr);
|
||||
|
||||
tqDebug("s-task:%s fill-history task set status to be dropping", id);
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id);
|
||||
tqDebug("s-task:%s fill-history task set status to be dropping and drop it", id);
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id, 0);
|
||||
|
||||
atomic_store_32(&pTask->status.inScanHistorySentinel, 0);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
@ -1192,8 +1193,8 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
streamProcessCheckpointSourceReq(pTask, &req);
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
qInfo("s-task:%s (vgId:%d) level:%d receive checkpoint-source msg chkpt:%" PRId64 ", transId:%d",
|
||||
pTask->id.idStr, vgId, pTask->info.taskLevel, req.checkpointId, req.transId);
|
||||
qInfo("s-task:%s (vgId:%d) level:%d receive checkpoint-source msg chkpt:%" PRId64 ", transId:%d", pTask->id.idStr,
|
||||
vgId, pTask->info.taskLevel, req.checkpointId, req.transId);
|
||||
|
||||
code = streamAddCheckpointSourceRspMsg(&req, &pMsg->info, pTask, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
|
|
@ -207,8 +207,8 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t
|
|||
goto END;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d, consumer:0x%" PRIx64 " taosx get msg ver %" PRId64 ", type: %s, reqId:0x%" PRIx64" 0x%"PRIx64, vgId,
|
||||
pHandle->consumerId, offset, TMSG_INFO(pHandle->pWalReader->pHead->head.msgType), reqId, id);
|
||||
tqDebug("vgId:%d, consumer:0x%" PRIx64 " taosx get msg ver %" PRId64 ", type: %s, reqId:0x%" PRIx64 " 0x%" PRIx64,
|
||||
vgId, pHandle->consumerId, offset, TMSG_INFO(pHandle->pWalReader->pHead->head.msgType), reqId, id);
|
||||
|
||||
if (pHandle->pWalReader->pHead->head.msgType == TDMT_VND_SUBMIT) {
|
||||
code = walFetchBody(pHandle->pWalReader);
|
||||
|
@ -322,7 +322,8 @@ int32_t extractMsgFromWal(SWalReader* pReader, void** pItem, int64_t maxVer, con
|
|||
|
||||
void* data = taosMemoryMalloc(len);
|
||||
if (data == NULL) {
|
||||
// todo: for all stream in this vnode, keep this offset in the offset files, and wait for a moment, and then retry
|
||||
// todo: for all stream in this vnode, keep this offset in the offset files, and wait for a moment, and then
|
||||
// retry
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
terrno = code;
|
||||
|
||||
|
@ -387,8 +388,8 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id, int sourceExcluded) {
|
|||
pReader->nextBlk = 0;
|
||||
int32_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||
while (pReader->nextBlk < numOfBlocks) {
|
||||
tqTrace("tq reader next data block %d/%d, len:%d %" PRId64, pReader->nextBlk,
|
||||
numOfBlocks, pReader->msg.msgLen, pReader->msg.ver);
|
||||
tqTrace("tq reader next data block %d/%d, len:%d %" PRId64, pReader->nextBlk, numOfBlocks, pReader->msg.msgLen,
|
||||
pReader->msg.ver);
|
||||
|
||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||
if ((pSubmitTbData->source & sourceExcluded) != 0) {
|
||||
|
@ -448,17 +449,11 @@ int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, i
|
|||
return 0;
|
||||
}
|
||||
|
||||
SWalReader* tqGetWalReader(STqReader* pReader) {
|
||||
return pReader->pWalReader;
|
||||
}
|
||||
SWalReader* tqGetWalReader(STqReader* pReader) { return pReader->pWalReader; }
|
||||
|
||||
SSDataBlock* tqGetResultBlock (STqReader* pReader) {
|
||||
return pReader->pResBlock;
|
||||
}
|
||||
SSDataBlock* tqGetResultBlock(STqReader* pReader) { return pReader->pResBlock; }
|
||||
|
||||
int64_t tqGetResultBlockTime(STqReader *pReader){
|
||||
return pReader->lastTs;
|
||||
}
|
||||
int64_t tqGetResultBlockTime(STqReader* pReader) { return pReader->lastTs; }
|
||||
|
||||
bool tqNextBlockImpl(STqReader* pReader, const char* idstr) {
|
||||
if (pReader->msg.msgStr == NULL) {
|
||||
|
@ -1027,9 +1022,7 @@ bool tqReaderIsQueriedTable(STqReader* pReader, uint64_t uid) {
|
|||
return taosHashGet(pReader->tbIdHash, &uid, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
bool tqCurrentBlockConsumed(const STqReader* pReader) {
|
||||
return pReader->msg.msgStr == NULL;
|
||||
}
|
||||
bool tqCurrentBlockConsumed(const STqReader* pReader) { return pReader->msg.msgStr == NULL; }
|
||||
|
||||
int tqReaderRemoveTbUidList(STqReader* pReader, const SArray* tbUidList) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
|
||||
|
@ -1071,9 +1064,11 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
|
|||
} else if (pTqHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
if (isAdd) {
|
||||
SArray* list = NULL;
|
||||
int ret = qGetTableList(pTqHandle->execHandle.execTb.suid, pTq->pVnode, pTqHandle->execHandle.execTb.node, &list, pTqHandle->execHandle.task);
|
||||
int ret = qGetTableList(pTqHandle->execHandle.execTb.suid, pTq->pVnode, pTqHandle->execHandle.execTb.node,
|
||||
&list, pTqHandle->execHandle.task);
|
||||
if (ret != TDB_CODE_SUCCESS) {
|
||||
tqError("qGetTableList in tqUpdateTbUidList error:%d handle %s consumer:0x%" PRIx64, ret, pTqHandle->subKey, pTqHandle->consumerId);
|
||||
tqError("qGetTableList in tqUpdateTbUidList error:%d handle %s consumer:0x%" PRIx64, ret, pTqHandle->subKey,
|
||||
pTqHandle->consumerId);
|
||||
taosArrayDestroy(list);
|
||||
taosHashCancelIterate(pTq->pHandle, pIter);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
|
|
|
@ -250,7 +250,8 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMeta
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded) {
|
||||
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows,
|
||||
int8_t sourceExcluded) {
|
||||
STqExecHandle* pExec = &pHandle->execHandle;
|
||||
SArray* pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
SArray* pSchemas = taosArrayInit(0, sizeof(void*));
|
||||
|
|
|
@ -33,12 +33,15 @@ static int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSData
|
|||
int64_t suid);
|
||||
static int32_t doBuildAndSendSubmitMsg(SVnode* pVnode, SStreamTask* pTask, SSubmitReq2* pReq, int32_t numOfBlocks);
|
||||
static int32_t buildSubmitMsgImpl(SSubmitReq2* pSubmitReq, int32_t vgId, void** pMsg, int32_t* msgLen);
|
||||
static int32_t doConvertRows(SSubmitTbData* pTableData, const STSchema* pTSchema, SSDataBlock* pDataBlock, const char* id);
|
||||
static int32_t doConvertRows(SSubmitTbData* pTableData, const STSchema* pTSchema, SSDataBlock* pDataBlock,
|
||||
const char* id);
|
||||
static int32_t doWaitForDstTableCreated(SVnode* pVnode, SStreamTask* pTask, STableSinkInfo* pTableSinkInfo,
|
||||
const char* dstTableName, int64_t* uid);
|
||||
static int32_t doPutIntoCache(SSHashObj* pSinkTableMap, STableSinkInfo* pTableSinkInfo, uint64_t groupId, const char* id);
|
||||
static int32_t doPutIntoCache(SSHashObj* pSinkTableMap, STableSinkInfo* pTableSinkInfo, uint64_t groupId,
|
||||
const char* id);
|
||||
static bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const char* ctbName, int64_t suid);
|
||||
static int32_t initCreateTableMsg(SVCreateTbReq* pCreateTableReq, uint64_t suid, const char* stbFullName, int32_t numOfTags);
|
||||
static int32_t initCreateTableMsg(SVCreateTbReq* pCreateTableReq, uint64_t suid, const char* stbFullName,
|
||||
int32_t numOfTags);
|
||||
static SArray* createDefaultTagColName();
|
||||
static void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid, bool newSubTableRule);
|
||||
|
@ -68,10 +71,7 @@ int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* p
|
|||
if (varTbName != NULL && varTbName != (void*)-1) {
|
||||
name = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
|
||||
memcpy(name, varDataVal(varTbName), varDataLen(varTbName));
|
||||
if(newSubTableRule &&
|
||||
!isAutoTableName(name) &&
|
||||
!alreadyAddGroupId(name) &&
|
||||
groupId != 0) {
|
||||
if (newSubTableRule && !isAutoTableName(name) && !alreadyAddGroupId(name) && groupId != 0) {
|
||||
buildCtbNameAddGruopId(name, groupId);
|
||||
}
|
||||
} else if (stbFullName) {
|
||||
|
@ -181,10 +181,8 @@ SArray* createDefaultTagColName() {
|
|||
void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid, bool newSubTableRule) {
|
||||
if (pDataBlock->info.parTbName[0]) {
|
||||
if(newSubTableRule &&
|
||||
!isAutoTableName(pDataBlock->info.parTbName) &&
|
||||
!alreadyAddGroupId(pDataBlock->info.parTbName) &&
|
||||
gid != 0) {
|
||||
if (newSubTableRule && !isAutoTableName(pDataBlock->info.parTbName) &&
|
||||
!alreadyAddGroupId(pDataBlock->info.parTbName) && gid != 0) {
|
||||
pCreateTableReq->name = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
|
||||
strcpy(pCreateTableReq->name, pDataBlock->info.parTbName);
|
||||
buildCtbNameAddGruopId(pCreateTableReq->name, gid);
|
||||
|
@ -196,13 +194,14 @@ void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDa
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, SSDataBlock* pDataBlock, SStreamTask* pTask,
|
||||
int64_t suid) {
|
||||
static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, SSDataBlock* pDataBlock,
|
||||
SStreamTask* pTask, int64_t suid) {
|
||||
tqDebug("s-task:%s build create table msg", pTask->id.idStr);
|
||||
|
||||
STSchema* pTSchema = pTask->outputInfo.tbSink.pTSchema;
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
SArray* tagArray = taosArrayInit(4, sizeof(STagVal));;
|
||||
SArray* tagArray = taosArrayInit(4, sizeof(STagVal));
|
||||
;
|
||||
int32_t code = 0;
|
||||
|
||||
SVCreateTbBatchReq reqs = {0};
|
||||
|
@ -262,7 +261,8 @@ static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, S
|
|||
ASSERT(gid == *(int64_t*)pGpIdData);
|
||||
}
|
||||
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid,
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER && pTask->subtableWithoutMd5 != 1);
|
||||
|
||||
taosArrayPush(reqs.pArray, pCreateTbReq);
|
||||
tqDebug("s-task:%s build create table:%s msg complete", pTask->id.idStr, pCreateTbReq->name);
|
||||
|
@ -361,7 +361,8 @@ int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, c
|
|||
pExisted->aRowP = pFinal;
|
||||
|
||||
tqTrace("s-task:%s rows merged, final rows:%d, uid:%" PRId64 ", existed auto-create table:%d, new-block:%d", id,
|
||||
(int32_t)taosArrayGetSize(pFinal), pExisted->uid, (pExisted->pCreateTbReq != NULL), (pNew->pCreateTbReq != NULL));
|
||||
(int32_t)taosArrayGetSize(pFinal), pExisted->uid, (pExisted->pCreateTbReq != NULL),
|
||||
(pNew->pCreateTbReq != NULL));
|
||||
|
||||
tdDestroySVCreateTbReq(pNew->pCreateTbReq);
|
||||
taosMemoryFree(pNew->pCreateTbReq);
|
||||
|
@ -373,7 +374,7 @@ int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSDataBlock*
|
|||
SBatchDeleteReq deleteReq = {.suid = suid, .deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq))};
|
||||
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr,
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER && pTask->subtableWithoutMd5 != 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -416,8 +417,8 @@ bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const char* ctbNam
|
|||
}
|
||||
|
||||
if (pReader->me.ctbEntry.suid != suid) {
|
||||
tqError("vgId:%d, failed to write into %s, since suid mismatch, expect suid:%" PRId64 ", actual:%" PRId64,
|
||||
vgId, ctbName, suid, pReader->me.ctbEntry.suid);
|
||||
tqError("vgId:%d, failed to write into %s, since suid mismatch, expect suid:%" PRId64 ", actual:%" PRId64, vgId,
|
||||
ctbName, suid, pReader->me.ctbEntry.suid);
|
||||
terrno = TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE;
|
||||
return false;
|
||||
}
|
||||
|
@ -667,10 +668,8 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
memset(dstTableName, 0, TSDB_TABLE_NAME_LEN);
|
||||
buildCtbNameByGroupIdImpl(stbFullName, groupId, dstTableName);
|
||||
} else {
|
||||
if(pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER &&
|
||||
!isAutoTableName(dstTableName) &&
|
||||
!alreadyAddGroupId(dstTableName) &&
|
||||
groupId != 0) {
|
||||
if (pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER && pTask->subtableWithoutMd5 != 1 &&
|
||||
!isAutoTableName(dstTableName) && !alreadyAddGroupId(dstTableName) && groupId != 0) {
|
||||
buildCtbNameAddGruopId(dstTableName, groupId);
|
||||
}
|
||||
}
|
||||
|
@ -714,7 +713,8 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
|
||||
pTableData->flags = SUBMIT_REQ_AUTO_CREATE_TABLE;
|
||||
pTableData->pCreateTbReq =
|
||||
buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray,
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER && pTask->subtableWithoutMd5 != 1);
|
||||
taosArrayDestroy(pTagArray);
|
||||
|
||||
if (pTableData->pCreateTbReq == NULL) {
|
||||
|
@ -750,8 +750,8 @@ int32_t tqSetDstTableDataPayload(uint64_t suid, const STSchema *pTSchema, int32_
|
|||
SSubmitTbData* pTableData, const char* id) {
|
||||
int32_t numOfRows = pDataBlock->info.rows;
|
||||
|
||||
tqDebug("s-task:%s sink data pipeline, build submit msg from %dth resBlock, including %d rows, dst suid:%" PRId64,
|
||||
id, blockIndex + 1, numOfRows, suid);
|
||||
tqDebug("s-task:%s sink data pipeline, build submit msg from %dth resBlock, including %d rows, dst suid:%" PRId64, id,
|
||||
blockIndex + 1, numOfRows, suid);
|
||||
char* dstTableName = pDataBlock->info.parTbName;
|
||||
|
||||
// convert all rows
|
||||
|
@ -832,7 +832,8 @@ void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data) {
|
|||
}
|
||||
} else {
|
||||
tqDebug("vgId:%d, s-task:%s write %d stream resBlock(s) into table, merge submit msg", vgId, id, numOfBlocks);
|
||||
SHashObj* pTableIndexMap = taosHashInit(numOfBlocks, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
SHashObj* pTableIndexMap =
|
||||
taosHashInit(numOfBlocks, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
|
||||
SSubmitReq2 submitReq = {.aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData))};
|
||||
if (submitReq.aSubmitTbData == NULL) {
|
||||
|
|
|
@ -72,7 +72,8 @@ static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, STqOffsetVal pOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, bool* pBlockReturned) {
|
||||
static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest,
|
||||
SRpcMsg* pMsg, bool* pBlockReturned) {
|
||||
uint64_t consumerId = pRequest->consumerId;
|
||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, pRequest->subKey);
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
@ -218,7 +219,9 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
|
||||
if (tqFetchLog(pTq, pHandle, &fetchVer, pRequest->reqId) < 0) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
code = tqSendDataRsp(
|
||||
pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp,
|
||||
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -230,7 +233,9 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
if (pHead->msgType != TDMT_VND_SUBMIT) {
|
||||
if (totalRows > 0) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
code = tqSendDataRsp(
|
||||
pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp,
|
||||
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -257,9 +262,11 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (totalRows >= 4096 || taosxRsp.createTableNum > 0 || (taosGetTimestampMs() - st > 1000)) {
|
||||
if (totalRows >= 4096 || (taosGetTimestampMs() - st > 1000)) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
code = tqSendDataRsp(
|
||||
pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp,
|
||||
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
|
||||
goto end;
|
||||
} else {
|
||||
fetchVer++;
|
||||
|
|
|
@ -317,7 +317,7 @@ int32_t tqStreamTaskProcessRetrieveReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
|||
if (pTask == NULL) {
|
||||
tqError("vgId:%d process retrieve req, failed to acquire task:0x%x, it may have been dropped already", pMeta->vgId,
|
||||
req.dstTaskId);
|
||||
taosMemoryFree(req.pRetrieve);
|
||||
tDeleteStreamRetrieveReq(&req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,7 @@ int32_t tqStreamTaskProcessRetrieveReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
|||
sendRetrieveRsp(&req, &rsp);
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
taosMemoryFree(req.pRetrieve);
|
||||
tDeleteStreamRetrieveReq(&req);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -612,6 +612,10 @@ int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen
|
|||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
streamTaskClearHTaskAttr(pTask, pReq->resetRelHalt, false);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// drop the stream task now
|
||||
streamMetaUnregisterTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#define ROCKS_BATCH_SIZE (4096)
|
||||
|
||||
#if 0
|
||||
static int32_t tsdbOpenBICache(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
SLRUCache *pCache = taosLRUCacheInit(10 * 1024 * 1024, 0, .5);
|
||||
|
@ -52,6 +53,7 @@ static void tsdbCloseBICache(STsdb *pTsdb) {
|
|||
taosThreadMutexDestroy(&pTsdb->biMutex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32_t tsdbOpenBCache(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
|
@ -431,25 +433,6 @@ int32_t tsdbCacheCommit(STsdb *pTsdb) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheLookup(STsdb *pTsdb, tb_uid_t uid, int16_t cid, int8_t ltype) {
|
||||
SLastCol *pLastCol = NULL;
|
||||
|
||||
char *err = NULL;
|
||||
size_t vlen = 0;
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
size_t klen = ROCKS_KEY_LEN;
|
||||
char *value = NULL;
|
||||
value = rocksdb_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, (char *)key, klen, &vlen, &err);
|
||||
if (NULL != err) {
|
||||
tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err);
|
||||
rocksdb_free(err);
|
||||
}
|
||||
|
||||
pLastCol = tsdbCacheDeserialize(value);
|
||||
|
||||
return pLastCol;
|
||||
}
|
||||
|
||||
static void reallocVarData(SColVal *pColVal) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
|
@ -476,6 +459,355 @@ static void tsdbCacheDeleter(const void *key, size_t klen, void *value, void *ud
|
|||
taosMemoryFree(value);
|
||||
}
|
||||
|
||||
static int32_t tsdbCacheNewTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type, int8_t ltype) {
|
||||
int32_t code = 0;
|
||||
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch;
|
||||
SLastCol noneCol = {.ts = TSKEY_MIN, .colVal = COL_VAL_NONE(cid, col_type), .dirty = 1};
|
||||
SLastCol *pLastCol = &noneCol;
|
||||
|
||||
SLastCol *pTmpLastCol = taosMemoryCalloc(1, sizeof(SLastCol));
|
||||
*pTmpLastCol = *pLastCol;
|
||||
pLastCol = pTmpLastCol;
|
||||
|
||||
reallocVarData(&pLastCol->colVal);
|
||||
size_t charge = sizeof(*pLastCol);
|
||||
if (IS_VAR_DATA_TYPE(pLastCol->colVal.type)) {
|
||||
charge += pLastCol->colVal.value.nData;
|
||||
}
|
||||
|
||||
SLastKey *pLastKey = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
LRUStatus status = taosLRUCacheInsert(pCache, pLastKey, ROCKS_KEY_LEN, pLastCol, charge, tsdbCacheDeleter, NULL,
|
||||
TAOS_LRU_PRIORITY_LOW, &pTsdb->flushState);
|
||||
if (status != TAOS_LRU_STATUS_OK) {
|
||||
code = -1;
|
||||
}
|
||||
/*
|
||||
// store result back to rocks cache
|
||||
char *value = NULL;
|
||||
size_t vlen = 0;
|
||||
tsdbCacheSerialize(pLastCol, &value, &vlen);
|
||||
|
||||
SLastKey *key = pLastKey;
|
||||
size_t klen = ROCKS_KEY_LEN;
|
||||
rocksdb_writebatch_put(wb, (char *)key, klen, value, vlen);
|
||||
taosMemoryFree(value);
|
||||
*/
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheCommitNoLock(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
char *err = NULL;
|
||||
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch;
|
||||
|
||||
taosLRUCacheApply(pCache, tsdbCacheFlushDirty, &pTsdb->flushState);
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, false);
|
||||
rocksMayWrite(pTsdb, true, true, false);
|
||||
rocksdb_flush(pTsdb->rCache.db, pTsdb->rCache.flushoptions, &err);
|
||||
|
||||
if (NULL != err) {
|
||||
tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err);
|
||||
rocksdb_free(err);
|
||||
code = -1;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCacheDropTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type, int8_t ltype) {
|
||||
int32_t code = 0;
|
||||
|
||||
// build keys & multi get from rocks
|
||||
char **keys_list = taosMemoryCalloc(2, sizeof(char *));
|
||||
size_t *keys_list_sizes = taosMemoryCalloc(2, sizeof(size_t));
|
||||
const size_t klen = ROCKS_KEY_LEN;
|
||||
|
||||
char *keys = taosMemoryCalloc(2, sizeof(SLastKey));
|
||||
((SLastKey *)keys)[0] = (SLastKey){.ltype = 1, .uid = uid, .cid = cid};
|
||||
((SLastKey *)keys)[1] = (SLastKey){.ltype = 0, .uid = uid, .cid = cid};
|
||||
|
||||
keys_list[0] = keys;
|
||||
keys_list[1] = keys + sizeof(SLastKey);
|
||||
keys_list_sizes[0] = klen;
|
||||
keys_list_sizes[1] = klen;
|
||||
|
||||
char **values_list = taosMemoryCalloc(2, sizeof(char *));
|
||||
size_t *values_list_sizes = taosMemoryCalloc(2, sizeof(size_t));
|
||||
char **errs = taosMemoryCalloc(2, sizeof(char *));
|
||||
|
||||
// rocksMayWrite(pTsdb, true, false, false);
|
||||
rocksdb_multi_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, 2, (const char *const *)keys_list, keys_list_sizes,
|
||||
values_list, values_list_sizes, errs);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (errs[i]) {
|
||||
rocksdb_free(errs[i]);
|
||||
}
|
||||
}
|
||||
taosMemoryFree(errs);
|
||||
|
||||
rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch;
|
||||
{
|
||||
SLastCol *pLastCol = tsdbCacheDeserialize(values_list[0]);
|
||||
if (NULL != pLastCol) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[0], klen);
|
||||
}
|
||||
pLastCol = tsdbCacheDeserialize(values_list[1]);
|
||||
if (NULL != pLastCol) {
|
||||
rocksdb_writebatch_delete(wb, keys_list[1], klen);
|
||||
}
|
||||
|
||||
rocksdb_free(values_list[0]);
|
||||
rocksdb_free(values_list[1]);
|
||||
|
||||
bool erase = false;
|
||||
LRUHandle *h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[0], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
erase = true;
|
||||
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
}
|
||||
if (erase) {
|
||||
taosLRUCacheErase(pTsdb->lruCache, keys_list[0], klen);
|
||||
}
|
||||
|
||||
erase = false;
|
||||
h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[1], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
erase = true;
|
||||
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
}
|
||||
if (erase) {
|
||||
taosLRUCacheErase(pTsdb->lruCache, keys_list[1], klen);
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFree(keys_list[0]);
|
||||
|
||||
taosMemoryFree(keys_list);
|
||||
taosMemoryFree(keys_list_sizes);
|
||||
taosMemoryFree(values_list);
|
||||
taosMemoryFree(values_list_sizes);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheNewTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWrapper *pSchemaRow) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
if (suid < 0) {
|
||||
int nCols = pSchemaRow->nCols;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pSchemaRow->pSchema[i].colId;
|
||||
int8_t col_type = pSchemaRow->pSchema[i].type;
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
} else {
|
||||
STSchema *pTSchema = NULL;
|
||||
code = metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, uid, -1, &pTSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropTable(STsdb *pTsdb, tb_uid_t uid, tb_uid_t suid, SSchemaWrapper *pSchemaRow) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
if (suid < 0) {
|
||||
int nCols = pSchemaRow->nCols;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pSchemaRow->pSchema[i].colId;
|
||||
int8_t col_type = pSchemaRow->pSchema[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
} else {
|
||||
STSchema *pTSchema = NULL;
|
||||
code = metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, uid, -1, &pTSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
}
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, false);
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropSubTables(STsdb *pTsdb, SArray *uids, tb_uid_t suid) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
STSchema *pTSchema = NULL;
|
||||
code = metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, suid, -1, &pTSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < TARRAY_SIZE(uids); ++i) {
|
||||
int64_t uid = ((tb_uid_t *)TARRAY_DATA(uids))[i];
|
||||
|
||||
int nCols = pTSchema->numOfCols;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
int16_t cid = pTSchema->columns[i].colId;
|
||||
int8_t col_type = pTSchema->columns[i].type;
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSchema);
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, false);
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheNewNTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
|
||||
// rocksMayWrite(pTsdb, true, false, false);
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
//(void)tsdbCacheCommit(pTsdb);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropNTableColumn(STsdb *pTsdb, int64_t uid, int16_t cid, int8_t col_type) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, true);
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheNewSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, int8_t col_type) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(uids); ++i) {
|
||||
tb_uid_t uid = ((tb_uid_t *)TARRAY_DATA(uids))[i];
|
||||
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheNewTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
|
||||
// rocksMayWrite(pTsdb, true, false, false);
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
//(void)tsdbCacheCommit(pTsdb);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCacheDropSTableColumn(STsdb *pTsdb, SArray *uids, int16_t cid, int8_t col_type) {
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&pTsdb->lruMutex);
|
||||
|
||||
(void)tsdbCacheCommitNoLock(pTsdb);
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(uids); ++i) {
|
||||
int64_t uid = ((tb_uid_t *)TARRAY_DATA(uids))[i];
|
||||
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 0);
|
||||
(void)tsdbCacheDropTableColumn(pTsdb, uid, cid, col_type, 1);
|
||||
}
|
||||
|
||||
rocksMayWrite(pTsdb, true, false, true);
|
||||
|
||||
taosThreadMutexUnlock(&pTsdb->lruMutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static SLastCol *tsdbCacheLookup(STsdb *pTsdb, tb_uid_t uid, int16_t cid, int8_t ltype) {
|
||||
SLastCol *pLastCol = NULL;
|
||||
|
||||
char *err = NULL;
|
||||
size_t vlen = 0;
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
size_t klen = ROCKS_KEY_LEN;
|
||||
char *value = NULL;
|
||||
value = rocksdb_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, (char *)key, klen, &vlen, &err);
|
||||
if (NULL != err) {
|
||||
tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err);
|
||||
rocksdb_free(err);
|
||||
}
|
||||
|
||||
pLastCol = tsdbCacheDeserialize(value);
|
||||
|
||||
return pLastCol;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
SLastKey key;
|
||||
|
@ -1297,11 +1629,13 @@ int32_t tsdbOpenCache(STsdb *pTsdb) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
#if 0
|
||||
code = tsdbOpenBICache(pTsdb);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
#endif
|
||||
|
||||
code = tsdbOpenBCache(pTsdb);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1343,7 +1677,9 @@ void tsdbCloseCache(STsdb *pTsdb) {
|
|||
taosThreadMutexDestroy(&pTsdb->lruMutex);
|
||||
}
|
||||
|
||||
#if 0
|
||||
tsdbCloseBICache(pTsdb);
|
||||
#endif
|
||||
tsdbCloseBCache(pTsdb);
|
||||
tsdbClosePgCache(pTsdb);
|
||||
tsdbCloseRocksCache(pTsdb);
|
||||
|
@ -3117,6 +3453,7 @@ int32_t tsdbCacheGetElems(SVnode *pVnode) {
|
|||
return elems;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void getBICacheKey(int32_t fid, int64_t commitID, char *key, int *len) {
|
||||
struct {
|
||||
int32_t fid;
|
||||
|
@ -3193,7 +3530,6 @@ int32_t tsdbCacheGetBlockIdx(SLRUCache *pCache, SDataFReader *pFileReader, LRUHa
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t tsdbBICacheRelease(SLRUCache *pCache, LRUHandle *h) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
|
|
@ -433,10 +433,12 @@ static int32_t vnodeAsyncLaunchWorker(SVAsync *async) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t vnodeAsync(SVAsync *async, EVAPriority priority, int32_t (*execute)(void *), void (*complete)(void *),
|
||||
void *arg, int64_t *taskId) {
|
||||
return vnodeAsyncC(async, 0, priority, execute, complete, arg, taskId);
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t vnodeAsyncC(SVAsync *async, int64_t channelId, EVAPriority priority, int32_t (*execute)(void *),
|
||||
void (*complete)(void *), void *arg, int64_t *taskId) {
|
||||
|
|
|
@ -181,12 +181,17 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->streamStateSessionPut = streamStateSessionPut;
|
||||
pStore->streamStateSessionGet = streamStateSessionGet;
|
||||
pStore->streamStateSessionDel = streamStateSessionDel;
|
||||
pStore->streamStateSessionReset = streamStateSessionReset;
|
||||
pStore->streamStateSessionClear = streamStateSessionClear;
|
||||
pStore->streamStateSessionGetKVByCur = streamStateSessionGetKVByCur;
|
||||
pStore->streamStateStateAddIfNotExist = streamStateStateAddIfNotExist;
|
||||
pStore->streamStateSessionGetKeyByRange = streamStateSessionGetKeyByRange;
|
||||
pStore->streamStateCountGetKeyByRange = streamStateCountGetKeyByRange;
|
||||
pStore->streamStateSessionAllocWinBuffByNextPosition = streamStateSessionAllocWinBuffByNextPosition;
|
||||
|
||||
pStore->streamStateCountWinAddIfNotExist = streamStateCountWinAddIfNotExist;
|
||||
pStore->streamStateCountWinAdd = streamStateCountWinAdd;
|
||||
|
||||
pStore->updateInfoInit = updateInfoInit;
|
||||
pStore->updateInfoFillBlockData = updateInfoFillBlockData;
|
||||
pStore->updateInfoIsUpdated = updateInfoIsUpdated;
|
||||
|
@ -203,6 +208,7 @@ void initStateStoreAPI(SStateStore* pStore) {
|
|||
pStore->updateInfoDeserialize = updateInfoDeserialize;
|
||||
|
||||
pStore->streamStateSessionSeekKeyNext = streamStateSessionSeekKeyNext;
|
||||
pStore->streamStateCountSeekKeyPrev = streamStateCountSeekKeyPrev;
|
||||
pStore->streamStateSessionSeekKeyCurrentPrev = streamStateSessionSeekKeyCurrentPrev;
|
||||
pStore->streamStateSessionSeekKeyCurrentNext = streamStateSessionSeekKeyCurrentNext;
|
||||
|
||||
|
|
|
@ -848,6 +848,7 @@ typedef struct SCtgCacheItemInfo {
|
|||
do { \
|
||||
CTG_UNLOCK(CTG_READ, &gCtgMgmt.lock); \
|
||||
CTG_API_DEBUG("CTG API leave %s", __FUNCTION__); \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
#define CTG_API_ENTER() \
|
||||
|
|
|
@ -2851,7 +2851,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
|
|||
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
|
||||
taosHashRelease(dbCache->tbCache, pCache);
|
||||
|
||||
ctgDebug("Got tb %s meta from cache, type:%d, dbFName:%s", pName->tname, tbMeta->tableType, dbFName);
|
||||
ctgDebug("Got tb %s meta from cache, type:%d, dbFName:%s", pName->tname, pTableMeta->tableType, dbFName);
|
||||
|
||||
res.pRes = pTableMeta;
|
||||
taosArrayPush(ctx->pResList, &res);
|
||||
|
@ -2868,7 +2868,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
|
|||
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
|
||||
taosHashRelease(dbCache->tbCache, pCache);
|
||||
|
||||
ctgDebug("Got tb %s meta from cache, type:%d, dbFName:%s", pName->tname, tbMeta->tableType, dbFName);
|
||||
ctgDebug("Got tb %s meta from cache, type:%d, dbFName:%s", pName->tname, pTableMeta->tableType, dbFName);
|
||||
|
||||
res.pRes = pTableMeta;
|
||||
taosArrayPush(ctx->pResList, &res);
|
||||
|
|
|
@ -69,6 +69,10 @@ extern "C" {
|
|||
#define EXPLAIN_EVENT_END_FORMAT "End Cond: "
|
||||
#define EXPLAIN_GROUP_CACHE_FORMAT "Group Cache"
|
||||
#define EXPLAIN_DYN_QRY_CTRL_FORMAT "Dynamic Query Control for %s"
|
||||
#define EXPLAIN_COUNT_FORMAT "Count"
|
||||
#define EXPLAIN_COUNT_INFO_FORMAT "Window Count Info"
|
||||
#define EXPLAIN_COUNT_NUM_FORMAT "Window Count=%" PRId64
|
||||
#define EXPLAIN_COUNT_SLIDING_FORMAT "Window Sliding=%" PRId64
|
||||
|
||||
#define EXPLAIN_PLANNING_TIME_FORMAT "Planning Time: %.3f ms"
|
||||
#define EXPLAIN_EXEC_TIME_FORMAT "Execution Time: %.3f ms"
|
||||
|
|
|
@ -1740,6 +1740,31 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT: {
|
||||
SCountWinodwPhysiNode *pCountNode = (SCountWinodwPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_COUNT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pCountNode->window.pFuncs->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pCountNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_NUM_FORMAT, pCountNode->windowCount);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_COUNT_SLIDING_FORMAT, pCountNode->windowSliding);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("not supported physical node type %d", pNode->type);
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
|
|
|
@ -371,6 +371,8 @@ typedef struct SStreamAggSupporter {
|
|||
STimeWindow winRange;
|
||||
SStorageAPI* pSessionAPI;
|
||||
struct SUpdateInfo* pUpdateInfo;
|
||||
int32_t windowCount;
|
||||
int32_t windowSliding;
|
||||
} SStreamAggSupporter;
|
||||
|
||||
typedef struct SWindowSupporter {
|
||||
|
@ -663,6 +665,27 @@ typedef struct SStreamEventAggOperatorInfo {
|
|||
SFilterInfo* pEndCondInfo;
|
||||
} SStreamEventAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamCountAggOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SStreamAggSupporter streamAggSup;
|
||||
SExprSupp scalarSupp; // supporter for perform scalar function
|
||||
SGroupResInfo groupResInfo;
|
||||
int32_t primaryTsIndex; // primary timestamp slot id
|
||||
STimeWindowAggSupp twAggSup;
|
||||
SSDataBlock* pDelRes;
|
||||
SSHashObj* pStDeleted;
|
||||
void* pDelIterator;
|
||||
bool ignoreExpiredData;
|
||||
bool ignoreExpiredDataSaved;
|
||||
SArray* pUpdated;
|
||||
SSHashObj* pStUpdated;
|
||||
int64_t dataVersion;
|
||||
SArray* historyWins;
|
||||
bool reCkBlock;
|
||||
bool recvGetAll;
|
||||
SSDataBlock* pCheckpointRes;
|
||||
} SStreamCountAggOperatorInfo;
|
||||
|
||||
typedef struct SStreamPartitionOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SPartitionBySupporter partitionSup;
|
||||
|
@ -800,6 +823,9 @@ bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, ST
|
|||
SStateStore* pStore);
|
||||
void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
|
||||
uint64_t* pGp, void* pTbName);
|
||||
void appendAllColumnToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, TSKEY* pCalStartTs,
|
||||
TSKEY* pCalEndTs, uint64_t* pUid, uint64_t* pGp, void* pTbName);
|
||||
|
||||
uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
|
||||
|
||||
int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPosition, SExprSupp* pSup,
|
||||
|
@ -881,11 +907,18 @@ void freeExchangeGetBasicOperatorParam(void* pParam);
|
|||
void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type);
|
||||
void freeResetOperatorParams(struct SOperatorInfo* pOperator, SOperatorParamType type, bool allFree);
|
||||
SSDataBlock* getNextBlockFromDownstreamImpl(struct SOperatorInfo* pOperator, int32_t idx, bool clearParam);
|
||||
void getCountWinRange(SStreamAggSupporter* pAggSup, const SSessionKey* pKey, EStreamType mode, SSessionKey* pDelRange);
|
||||
bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey);
|
||||
|
||||
void saveDeleteInfo(SArray* pWins, SSessionKey key);
|
||||
void removeSessionResults(SStreamAggSupporter* pAggSup, SSHashObj* pHashMap, SArray* pWins);
|
||||
void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted);
|
||||
|
||||
bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo);
|
||||
bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd, EStreamType blockType);
|
||||
bool compareVal(const char* v, const SStateKeys* pKey);
|
||||
bool inWinRange(STimeWindow* range, STimeWindow* cur);
|
||||
void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result);
|
||||
|
||||
int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo,
|
||||
TSKEY* primaryKeys, int32_t prevPosition, int32_t order);
|
||||
|
|
|
@ -154,10 +154,14 @@ SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFi
|
|||
|
||||
SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle);
|
||||
|
||||
SOperatorInfo* createStreamCountAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle);
|
||||
|
||||
SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createCountwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SGroupCachePhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo);
|
||||
|
|
|
@ -64,8 +64,6 @@ typedef struct {
|
|||
SSchemaWrapper* schema;
|
||||
char tbName[TSDB_TABLE_NAME_LEN]; // this is the current scan table: todo refactor
|
||||
int8_t recoverStep;
|
||||
// bool recoverStep1Finished;
|
||||
// bool recoverStep2Finished;
|
||||
int8_t recoverScanFinished;
|
||||
SQueryTableDataCond tableCond;
|
||||
SVersionRange fillHistoryVer;
|
||||
|
@ -84,7 +82,6 @@ struct SExecTaskInfo {
|
|||
int64_t version; // used for stream to record wal version, why not move to sschemainfo
|
||||
SStreamTaskInfo streamInfo;
|
||||
SArray* schemaInfos;
|
||||
SSchemaInfo schemaInfo;
|
||||
const char* sql; // query sql string
|
||||
jmp_buf env; // jump to this position when error happens.
|
||||
EOPTR_EXEC_MODEL execModel; // operator execution model [batch model|stream model]
|
||||
|
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "executorInt.h"
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tcommon.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "ttime.h"
|
||||
|
||||
typedef struct SCountWindowResult {
|
||||
int32_t winRows;
|
||||
SResultRow row;
|
||||
} SCountWindowResult;
|
||||
|
||||
typedef struct SCountWindowSupp {
|
||||
SArray* pWinStates;
|
||||
int32_t stateIndex;
|
||||
} SCountWindowSupp;
|
||||
|
||||
typedef struct SCountWindowOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SAggSupporter aggSup;
|
||||
SExprSupp scalarSup;
|
||||
int32_t tsSlotId; // primary timestamp column slot id
|
||||
STimeWindowAggSupp twAggSup;
|
||||
uint64_t groupId; // current group id, used to identify the data block from different groups
|
||||
SResultRow* pRow;
|
||||
int32_t windowCount;
|
||||
int32_t windowSliding;
|
||||
SCountWindowSupp countSup;
|
||||
} SCountWindowOperatorInfo;
|
||||
|
||||
void destroyCountWindowOperatorInfo(void* param) {
|
||||
SCountWindowOperatorInfo* pInfo = (SCountWindowOperatorInfo*)param;
|
||||
if (pInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
cleanupBasicInfo(&pInfo->binfo);
|
||||
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||
|
||||
cleanupAggSup(&pInfo->aggSup);
|
||||
cleanupExprSupp(&pInfo->scalarSup);
|
||||
taosArrayDestroy(pInfo->countSup.pWinStates);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
static void clearWinStateBuff(SCountWindowResult* pBuff) {
|
||||
pBuff->winRows = 0;
|
||||
}
|
||||
|
||||
static SCountWindowResult* getCountWinStateInfo(SCountWindowSupp* pCountSup) {
|
||||
SCountWindowResult* pBuffInfo = taosArrayGet(pCountSup->pWinStates, pCountSup->stateIndex);
|
||||
pCountSup->stateIndex = (pCountSup->stateIndex + 1) % taosArrayGetSize(pCountSup->pWinStates);
|
||||
return pBuffInfo;
|
||||
}
|
||||
|
||||
static SCountWindowResult* setCountWindowOutputBuff(SExprSupp* pExprSup, SCountWindowSupp* pCountSup, SResultRow** pResult) {
|
||||
SCountWindowResult* pBuff = getCountWinStateInfo(pCountSup);
|
||||
(*pResult) = &pBuff->row;
|
||||
setResultRowInitCtx(*pResult, pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||
return pBuff;
|
||||
}
|
||||
|
||||
static int32_t updateCountWindowInfo(int32_t start, int32_t blockRows, int32_t countWinRows, int32_t* pCurrentRows) {
|
||||
int32_t rows = TMIN(countWinRows - (*pCurrentRows), blockRows - start);
|
||||
(*pCurrentRows) += rows;
|
||||
return rows;
|
||||
}
|
||||
|
||||
int32_t doCountWindowAggImpl(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||
SCountWindowOperatorInfo* pInfo = pOperator->info;
|
||||
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||
TSKEY* tsCols = (TSKEY*)pColInfoData->pData;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
for (int32_t i = 0; i < pBlock->info.rows;) {
|
||||
int32_t step = pInfo->windowSliding;
|
||||
SCountWindowResult* pBuffInfo = setCountWindowOutputBuff(pExprSup, &pInfo->countSup, &pInfo->pRow);
|
||||
int32_t prevRows = pBuffInfo->winRows;
|
||||
int32_t num = updateCountWindowInfo(i, pBlock->info.rows, pInfo->windowCount, &pBuffInfo->winRows);
|
||||
if (prevRows == 0) {
|
||||
pInfo->pRow->win.skey = tsCols[i];
|
||||
}
|
||||
pInfo->pRow->win.ekey = tsCols[num + i - 1];
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->pRow->win, 0);
|
||||
applyAggFunctionOnPartialTuples(pTaskInfo, pExprSup->pCtx, &pInfo->twAggSup.timeWindowData, i, num,
|
||||
pBlock->info.rows, pExprSup->numOfExprs);
|
||||
if (pBuffInfo->winRows == pInfo->windowCount) {
|
||||
doUpdateNumOfRows(pExprSup->pCtx, pInfo->pRow, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||
copyResultrowToDataBlock(pExprSup->pExprInfo, pExprSup->numOfExprs, pInfo->pRow, pExprSup->pCtx, pRes,
|
||||
pExprSup->rowEntryInfoOffset, pTaskInfo);
|
||||
pRes->info.rows += pInfo->pRow->numOfRows;
|
||||
clearWinStateBuff(pBuffInfo);
|
||||
clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
|
||||
}
|
||||
if (pInfo->windowCount != pInfo->windowSliding) {
|
||||
if (prevRows <= pInfo->windowSliding) {
|
||||
if (pBuffInfo->winRows > pInfo->windowSliding) {
|
||||
step = pInfo->windowSliding - prevRows;
|
||||
}
|
||||
} else {
|
||||
step = 0;
|
||||
}
|
||||
}
|
||||
i += step;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static void buildCountResult(SExprSupp* pExprSup, SCountWindowSupp* pCountSup, SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock) {
|
||||
SResultRow* pResultRow = NULL;
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pCountSup->pWinStates); i++) {
|
||||
SCountWindowResult* pBuff = setCountWindowOutputBuff(pExprSup, pCountSup, &pResultRow);
|
||||
if (pBuff->winRows == 0) {
|
||||
continue;;
|
||||
}
|
||||
doUpdateNumOfRows(pExprSup->pCtx, pResultRow, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||
copyResultrowToDataBlock(pExprSup->pExprInfo, pExprSup->numOfExprs, pResultRow, pExprSup->pCtx, pBlock,
|
||||
pExprSup->rowEntryInfoOffset, pTaskInfo);
|
||||
pBlock->info.rows += pResultRow->numOfRows;
|
||||
clearWinStateBuff(pBuff);
|
||||
clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* countWindowAggregate(SOperatorInfo* pOperator) {
|
||||
SCountWindowOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||
int32_t order = pInfo->binfo.inputTsOrder;
|
||||
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
|
||||
blockDataCleanup(pRes);
|
||||
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = getNextBlockFromDownstream(pOperator, 0);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
pRes->info.scanFlag = pBlock->info.scanFlag;
|
||||
setInputDataBlock(pExprSup, pBlock, order, MAIN_SCAN, true);
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId);
|
||||
|
||||
// there is an scalar expression that needs to be calculated right before apply the group aggregation.
|
||||
if (pInfo->scalarSup.pExprInfo != NULL) {
|
||||
pTaskInfo->code = projectApplyFunctions(pInfo->scalarSup.pExprInfo, pBlock, pBlock, pInfo->scalarSup.pCtx,
|
||||
pInfo->scalarSup.numOfExprs, NULL);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||
}
|
||||
}
|
||||
|
||||
if (pInfo->groupId == 0) {
|
||||
pInfo->groupId = pBlock->info.id.groupId;
|
||||
} else if (pInfo->groupId != pBlock->info.id.groupId) {
|
||||
buildCountResult(pExprSup, &pInfo->countSup, pTaskInfo, pRes);
|
||||
pInfo->groupId = pBlock->info.id.groupId;
|
||||
}
|
||||
|
||||
doCountWindowAggImpl(pOperator, pBlock);
|
||||
if (pRes->info.rows >= pOperator->resultInfo.threshold) {
|
||||
return pRes;
|
||||
}
|
||||
}
|
||||
|
||||
buildCountResult(pExprSup, &pInfo->countSup, pTaskInfo, pRes);
|
||||
return pRes->info.rows == 0 ? NULL : pRes;
|
||||
}
|
||||
|
||||
SOperatorInfo* createCountwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SCountWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SCountWindowOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SCountWinodwPhysiNode* pCountWindowNode = (SCountWinodwPhysiNode*)physiNode;
|
||||
|
||||
pInfo->tsSlotId = ((SColumnNode*)pCountWindowNode->window.pTspk)->slotId;
|
||||
|
||||
if (pCountWindowNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalarExpr = 0;
|
||||
SExprInfo* pScalarExprInfo = createExprInfo(pCountWindowNode->window.pExprs, NULL, &numOfScalarExpr);
|
||||
code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, numOfScalarExpr, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
size_t keyBufSize = 0;
|
||||
int32_t num = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pCountWindowNode->window.pFuncs, NULL, &num);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
|
||||
code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, num, keyBufSize, pTaskInfo->id.str,
|
||||
pTaskInfo->streamInfo.pState, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SSDataBlock* pResBlock = createDataBlockFromDescNode(pCountWindowNode->window.node.pOutputDataBlockDesc);
|
||||
blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
|
||||
|
||||
initBasicInfo(&pInfo->binfo, pResBlock);
|
||||
initResultRowInfo(&pInfo->binfo.resultRowInfo);
|
||||
pInfo->binfo.inputTsOrder = physiNode->inputTsOrder;
|
||||
pInfo->binfo.outputTsOrder = physiNode->outputTsOrder;
|
||||
pInfo->windowCount = pCountWindowNode->windowCount;
|
||||
pInfo->windowSliding = pCountWindowNode->windowSliding;
|
||||
//sizeof(SCountWindowResult)
|
||||
int32_t itemSize = sizeof(int32_t) + pInfo->aggSup.resultRowSize;
|
||||
int32_t numOfItem = 1;
|
||||
if (pInfo->windowCount != pInfo->windowSliding) {
|
||||
numOfItem = pInfo->windowCount / pInfo->windowSliding + 1;
|
||||
}
|
||||
pInfo->countSup.pWinStates = taosArrayInit_s(itemSize, numOfItem);
|
||||
if (!pInfo->countSup.pWinStates) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->countSup.stateIndex = 0;
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
setOperatorInfo(pOperator, "CountWindowOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT, true, OP_NOT_OPENED, pInfo,
|
||||
pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, countWindowAggregate, NULL, destroyCountWindowOperatorInfo,
|
||||
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroyCountWindowOperatorInfo(pInfo);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pOperator);
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
|
@ -2245,6 +2245,8 @@ char* getStreamOpName(uint16_t opType) {
|
|||
return "stream partitionby";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
return "stream event";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
return "stream count";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -1027,52 +1027,6 @@ int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t qRestoreStreamOperatorOption(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
const char* id = GET_TASKID(pTaskInfo);
|
||||
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
||||
|
||||
while (1) {
|
||||
uint16_t type = pOperator->operatorType;
|
||||
if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
pInfo->twAggSup.calTrigger = pInfo->twAggSup.calTriggerSaved;
|
||||
pInfo->twAggSup.deleteMark = pInfo->twAggSup.deleteMarkSaved;
|
||||
pInfo->ignoreExpiredData = pInfo->ignoreExpiredDataSaved;
|
||||
qInfo("%s restore stream agg executors param for interval: %d, %" PRId64, id, pInfo->twAggSup.calTrigger,
|
||||
pInfo->twAggSup.deleteMark);
|
||||
} else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) {
|
||||
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
|
||||
pInfo->twAggSup.calTrigger = pInfo->twAggSup.calTriggerSaved;
|
||||
pInfo->twAggSup.deleteMark = pInfo->twAggSup.deleteMarkSaved;
|
||||
pInfo->ignoreExpiredData = pInfo->ignoreExpiredDataSaved;
|
||||
qInfo("%s restore stream agg executor param for session: %d, %" PRId64, id, pInfo->twAggSup.calTrigger,
|
||||
pInfo->twAggSup.deleteMark);
|
||||
} else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE) {
|
||||
SStreamStateAggOperatorInfo* pInfo = pOperator->info;
|
||||
pInfo->twAggSup.calTrigger = pInfo->twAggSup.calTriggerSaved;
|
||||
pInfo->twAggSup.deleteMark = pInfo->twAggSup.deleteMarkSaved;
|
||||
pInfo->ignoreExpiredData = pInfo->ignoreExpiredDataSaved;
|
||||
qInfo("%s restore stream agg executor param for state: %d, %" PRId64, id, pInfo->twAggSup.calTrigger,
|
||||
pInfo->twAggSup.deleteMark);
|
||||
}
|
||||
|
||||
// iterate operator tree
|
||||
if (pOperator->numOfDownstream != 1 || pOperator->pDownstream[0] == NULL) {
|
||||
if (pOperator->numOfDownstream > 1) {
|
||||
qError("unexpected stream, multiple downstream");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
pOperator = pOperator->pDownstream[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool qStreamScanhistoryFinished(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
return pTaskInfo->streamInfo.recoverScanFinished;
|
||||
|
|
|
@ -542,6 +542,10 @@ SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SR
|
|||
pOptr = createGroupCacheOperatorInfo(ops, size, (SGroupCachePhysiNode*)pPhyNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL == type) {
|
||||
pOptr = createDynQueryCtrlOperatorInfo(ops, size, (SDynQueryCtrlPhysiNode*)pPhyNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT == type) {
|
||||
pOptr = createStreamCountAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT == type) {
|
||||
pOptr = createCountwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo);
|
||||
} else {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
pTaskInfo->code = terrno;
|
||||
|
|
|
@ -1284,6 +1284,14 @@ static bool isSlidingWindow(SStreamScanInfo* pInfo) {
|
|||
return isIntervalWindow(pInfo) && pInfo->interval.interval != pInfo->interval.sliding;
|
||||
}
|
||||
|
||||
static bool isCountSlidingWindow(SStreamScanInfo* pInfo) {
|
||||
return pInfo->windowSup.pStreamAggSup && (pInfo->windowSup.pStreamAggSup->windowCount != pInfo->windowSup.pStreamAggSup->windowSliding);
|
||||
}
|
||||
|
||||
static bool isCountWindow(SStreamScanInfo* pInfo) {
|
||||
return pInfo->windowSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT;
|
||||
}
|
||||
|
||||
static void setGroupId(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t groupColIndex, int32_t rowIndex) {
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, groupColIndex);
|
||||
uint64_t* groupCol = (uint64_t*)pColInfo->pData;
|
||||
|
@ -1394,7 +1402,7 @@ static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_
|
|||
TSKEY* calEndData = (TSKEY*)pCalEndTsCol->pData;
|
||||
|
||||
setGroupId(pInfo, pBlock, GROUPID_COLUMN_INDEX, *pRowIndex);
|
||||
if (isSlidingWindow(pInfo)) {
|
||||
if (isSlidingWindow(pInfo) || isCountSlidingWindow(pInfo)) {
|
||||
pInfo->updateWin.skey = calStartData[*pRowIndex];
|
||||
pInfo->updateWin.ekey = calEndData[*pRowIndex];
|
||||
}
|
||||
|
@ -1588,6 +1596,47 @@ static int32_t generateSessionScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSr
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t generateCountScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock, EStreamType mode) {
|
||||
blockDataCleanup(pDestBlock);
|
||||
if (pSrcBlock->info.rows == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t code = blockDataEnsureCapacity(pDestBlock, pSrcBlock->info.rows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
ASSERT(taosArrayGetSize(pSrcBlock->pDataBlock) >= 3);
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
TSKEY* startData = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
TSKEY* endData = (TSKEY*)pEndTsCol->pData;
|
||||
SColumnInfoData* pUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX);
|
||||
uint64_t* uidCol = (uint64_t*)pUidCol->pData;
|
||||
|
||||
SColumnInfoData* pDestStartCol = taosArrayGet(pDestBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pDestEndCol = taosArrayGet(pDestBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pDestUidCol = taosArrayGet(pDestBlock->pDataBlock, UID_COLUMN_INDEX);
|
||||
SColumnInfoData* pDestGpCol = taosArrayGet(pDestBlock->pDataBlock, GROUPID_COLUMN_INDEX);
|
||||
SColumnInfoData* pDestCalStartTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pDestCalEndTsCol = taosArrayGet(pDestBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
|
||||
int64_t ver = pSrcBlock->info.version - 1;
|
||||
for (int32_t i = 0; i < pSrcBlock->info.rows; i++) {
|
||||
uint64_t groupId = getGroupIdByData(pInfo, uidCol[i], startData[i], ver);
|
||||
SSessionKey startWin = {.win.skey = startData[i], .win.ekey = endData[i], .groupId = groupId};
|
||||
SSessionKey range = {0};
|
||||
getCountWinRange(pInfo->windowSup.pStreamAggSup, &startWin, mode, &range);
|
||||
colDataSetVal(pDestStartCol, i, (const char*)&range.win.skey, false);
|
||||
colDataSetVal(pDestEndCol, i, (const char*)&range.win.ekey, false);
|
||||
|
||||
colDataSetNULL(pDestUidCol, i);
|
||||
colDataSetVal(pDestGpCol, i, (const char*)&groupId, false);
|
||||
colDataSetVal(pDestCalStartTsCol, i, (const char*)&range.win.skey, false);
|
||||
colDataSetVal(pDestCalEndTsCol, i, (const char*)&range.win.ekey, false);
|
||||
pDestBlock->info.rows++;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
|
||||
blockDataCleanup(pDestBlock);
|
||||
int32_t rows = pSrcBlock->info.rows;
|
||||
|
@ -1724,12 +1773,14 @@ static int32_t generateDeleteResultBlock(SStreamScanInfo* pInfo, SSDataBlock* pS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t generateScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock) {
|
||||
static int32_t generateScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock, SSDataBlock* pDestBlock, EStreamType type) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (isIntervalWindow(pInfo)) {
|
||||
code = generateIntervalScanRange(pInfo, pSrcBlock, pDestBlock);
|
||||
} else if (isSessionWindow(pInfo) || isStateWindow(pInfo)) {
|
||||
code = generateSessionScanRange(pInfo, pSrcBlock, pDestBlock);
|
||||
} else if (isCountWindow(pInfo)) {
|
||||
code = generateCountScanRange(pInfo, pSrcBlock, pDestBlock, type);
|
||||
} else {
|
||||
code = generateDeleteResultBlock(pInfo, pSrcBlock, pDestBlock);
|
||||
}
|
||||
|
@ -1742,6 +1793,11 @@ static int32_t generateScanRange(SStreamScanInfo* pInfo, SSDataBlock* pSrcBlock,
|
|||
|
||||
void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
|
||||
uint64_t* pGp, void* pTbName) {
|
||||
appendAllColumnToStreamSpecialBlock(pBlock, pStartTs, pEndTs, pStartTs, pEndTs, pUid, pGp, pTbName);
|
||||
}
|
||||
|
||||
void appendAllColumnToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, TSKEY* pCalStartTs,
|
||||
TSKEY* pCalEndTs, uint64_t* pUid, uint64_t* pGp, void* pTbName) {
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX);
|
||||
|
@ -1753,8 +1809,8 @@ void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKE
|
|||
colDataSetVal(pEndTsCol, pBlock->info.rows, (const char*)pEndTs, false);
|
||||
colDataSetVal(pUidCol, pBlock->info.rows, (const char*)pUid, false);
|
||||
colDataSetVal(pGpCol, pBlock->info.rows, (const char*)pGp, false);
|
||||
colDataSetVal(pCalStartCol, pBlock->info.rows, (const char*)pStartTs, false);
|
||||
colDataSetVal(pCalEndCol, pBlock->info.rows, (const char*)pEndTs, false);
|
||||
colDataSetVal(pCalStartCol, pBlock->info.rows, (const char*)pCalStartTs, false);
|
||||
colDataSetVal(pCalEndCol, pBlock->info.rows, (const char*)pCalEndTs, false);
|
||||
colDataSetVal(pTableCol, pBlock->info.rows, (const char*)pTbName, pTbName == NULL);
|
||||
pBlock->info.rows++;
|
||||
}
|
||||
|
@ -2159,6 +2215,14 @@ void streamScanOperatorDecode(void* pBuff, int32_t len, SStreamScanInfo* pInfo)
|
|||
taosMemoryFree(pUpInfo);
|
||||
}
|
||||
}
|
||||
static bool hasScanRange(SStreamScanInfo* pInfo) {
|
||||
SStreamAggSupporter* pSup = pInfo->windowSup.pStreamAggSup;
|
||||
return pSup && pSup->pScanBlock->info.rows > 0 && (isStateWindow(pInfo) || isCountWindow(pInfo));
|
||||
}
|
||||
|
||||
static bool isStreamWindow(SStreamScanInfo* pInfo) {
|
||||
return isIntervalWindow(pInfo) || isSessionWindow(pInfo) || isStateWindow(pInfo) || isCountWindow(pInfo);
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
||||
// NOTE: this operator does never check if current status is done or not
|
||||
|
@ -2307,7 +2371,7 @@ FETCH_NEXT_BLOCK:
|
|||
goto FETCH_NEXT_BLOCK;
|
||||
}
|
||||
|
||||
if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) {
|
||||
if (!isStreamWindow(pInfo)) {
|
||||
generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes);
|
||||
pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT;
|
||||
printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete result", GET_TASKID(pTaskInfo));
|
||||
|
@ -2321,7 +2385,7 @@ FETCH_NEXT_BLOCK:
|
|||
} else {
|
||||
pInfo->blockType = STREAM_INPUT__DATA_SUBMIT;
|
||||
pInfo->updateResIndex = 0;
|
||||
generateScanRange(pInfo, pDelBlock, pInfo->pUpdateRes);
|
||||
generateScanRange(pInfo, pDelBlock, pInfo->pUpdateRes, STREAM_DELETE_DATA);
|
||||
prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
|
||||
copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes);
|
||||
pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA;
|
||||
|
@ -2359,7 +2423,7 @@ FETCH_NEXT_BLOCK:
|
|||
}
|
||||
} break;
|
||||
case STREAM_SCAN_FROM_DELETE_DATA: {
|
||||
generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes);
|
||||
generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes, STREAM_DELETE_DATA);
|
||||
prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
|
||||
copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes);
|
||||
|
@ -2367,7 +2431,7 @@ FETCH_NEXT_BLOCK:
|
|||
return pInfo->pDeleteDataRes;
|
||||
} break;
|
||||
case STREAM_SCAN_FROM_UPDATERES: {
|
||||
generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes);
|
||||
generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes, STREAM_CLEAR);
|
||||
prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
|
||||
return pInfo->pUpdateRes;
|
||||
|
@ -2392,10 +2456,10 @@ FETCH_NEXT_BLOCK:
|
|||
break;
|
||||
}
|
||||
|
||||
SStreamAggSupporter* pSup = pInfo->windowSup.pStreamAggSup;
|
||||
if (isStateWindow(pInfo) && pSup->pScanBlock->info.rows > 0) {
|
||||
if (hasScanRange(pInfo)) {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE;
|
||||
pInfo->updateResIndex = 0;
|
||||
SStreamAggSupporter* pSup = pInfo->windowSup.pStreamAggSup;
|
||||
copyDataBlock(pInfo->pUpdateRes, pSup->pScanBlock);
|
||||
blockDataCleanup(pSup->pScanBlock);
|
||||
prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex);
|
||||
|
|
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "executorInt.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tchecksum.h"
|
||||
#include "tcommon.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tglobal.h"
|
||||
#include "tlog.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#define IS_FINAL_COUNT_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_COUNT)
|
||||
#define STREAM_COUNT_OP_STATE_NAME "StreamCountHistoryState"
|
||||
#define STREAM_COUNT_OP_CHECKPOINT_NAME "StreamCountOperator_Checkpoint"
|
||||
|
||||
typedef struct SCountWindowInfo {
|
||||
SResultWindowInfo winInfo;
|
||||
COUNT_TYPE* pWindowCount;
|
||||
} SCountWindowInfo;
|
||||
|
||||
typedef enum {
|
||||
NONE_WINDOW = 0,
|
||||
CREATE_NEW_WINDOW,
|
||||
MOVE_NEXT_WINDOW,
|
||||
} BuffOp;
|
||||
typedef struct SBuffInfo {
|
||||
bool rebuildWindow;
|
||||
BuffOp winBuffOp;
|
||||
SStreamStateCur* pCur;
|
||||
} SBuffInfo;
|
||||
|
||||
void destroyStreamCountAggOperatorInfo(void* param) {
|
||||
SStreamCountAggOperatorInfo* pInfo = (SStreamCountAggOperatorInfo*)param;
|
||||
cleanupBasicInfo(&pInfo->binfo);
|
||||
destroyStreamAggSupporter(&pInfo->streamAggSup);
|
||||
cleanupExprSupp(&pInfo->scalarSupp);
|
||||
clearGroupResInfo(&pInfo->groupResInfo);
|
||||
|
||||
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||
blockDataDestroy(pInfo->pDelRes);
|
||||
tSimpleHashCleanup(pInfo->pStUpdated);
|
||||
tSimpleHashCleanup(pInfo->pStDeleted);
|
||||
pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated);
|
||||
cleanupGroupResInfo(&pInfo->groupResInfo);
|
||||
|
||||
taosArrayDestroy(pInfo->historyWins);
|
||||
blockDataDestroy(pInfo->pCheckpointRes);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
bool isSlidingCountWindow(SStreamAggSupporter* pAggSup) {
|
||||
return pAggSup->windowCount != pAggSup->windowSliding;
|
||||
}
|
||||
|
||||
void setCountOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, SCountWindowInfo* pCurWin,
|
||||
SBuffInfo* pBuffInfo) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t size = pAggSup->resultRowSize;
|
||||
pCurWin->winInfo.sessionWin.groupId = groupId;
|
||||
pCurWin->winInfo.sessionWin.win.skey = ts;
|
||||
pCurWin->winInfo.sessionWin.win.ekey = ts;
|
||||
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
if (pBuffInfo->winBuffOp == CREATE_NEW_WINDOW) {
|
||||
pAggSup->stateStore.streamStateCountWinAdd(pAggSup->pState, &pCurWin->winInfo.sessionWin,
|
||||
(void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
code = TSDB_CODE_FAILED;
|
||||
} else if (pBuffInfo->winBuffOp == MOVE_NEXT_WINDOW) {
|
||||
ASSERT(pBuffInfo->pCur);
|
||||
pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pBuffInfo->pCur);
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pBuffInfo->pCur, &pCurWin->winInfo.sessionWin,
|
||||
(void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
if (code == TSDB_CODE_FAILED) {
|
||||
pAggSup->stateStore.streamStateCountWinAdd(pAggSup->pState, &pCurWin->winInfo.sessionWin,
|
||||
(void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
}
|
||||
} else {
|
||||
pBuffInfo->pCur = pAggSup->stateStore.streamStateCountSeekKeyPrev(pAggSup->pState, &pCurWin->winInfo.sessionWin, pAggSup->windowCount);
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pBuffInfo->pCur, &pCurWin->winInfo.sessionWin,
|
||||
(void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
if (code == TSDB_CODE_FAILED) {
|
||||
pAggSup->stateStore.streamStateCountWinAdd(pAggSup->pState, &pCurWin->winInfo.sessionWin,
|
||||
(void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code = pAggSup->stateStore.streamStateCountWinAddIfNotExist(
|
||||
pAggSup->pState, &pCurWin->winInfo.sessionWin, pAggSup->windowCount, (void**)&pCurWin->winInfo.pStatePos, &size);
|
||||
}
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
pCurWin->winInfo.isOutput = true;
|
||||
}
|
||||
pCurWin->pWindowCount=
|
||||
(COUNT_TYPE*) ((char*)pCurWin->winInfo.pStatePos->pRowBuff + (pAggSup->resultRowSize - sizeof(COUNT_TYPE)));
|
||||
|
||||
if (*pCurWin->pWindowCount == pAggSup->windowCount) {
|
||||
pBuffInfo->rebuildWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t updateCountWindowInfo(SStreamAggSupporter* pAggSup, SCountWindowInfo* pWinInfo, TSKEY* pTs, int32_t start, int32_t rows, int32_t maxRows,
|
||||
SSHashObj* pStDeleted, bool* pRebuild) {
|
||||
SSessionKey sWinKey = pWinInfo->winInfo.sessionWin;
|
||||
int32_t num = 0;
|
||||
for (int32_t i = start; i < rows; i++) {
|
||||
if (pTs[i] < pWinInfo->winInfo.sessionWin.win.ekey) {
|
||||
num++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int32_t maxNum = TMIN(maxRows - *pWinInfo->pWindowCount, rows - start);
|
||||
if (num > maxNum) {
|
||||
*pRebuild = true;
|
||||
}
|
||||
*pWinInfo->pWindowCount += maxNum;
|
||||
bool needDelState = false;
|
||||
if (pWinInfo->winInfo.sessionWin.win.skey > pTs[start]) {
|
||||
needDelState = true;
|
||||
if (pStDeleted && pWinInfo->winInfo.isOutput) {
|
||||
saveDeleteRes(pStDeleted, pWinInfo->winInfo.sessionWin);
|
||||
}
|
||||
|
||||
pWinInfo->winInfo.sessionWin.win.skey = pTs[start];
|
||||
}
|
||||
|
||||
if (pWinInfo->winInfo.sessionWin.win.ekey < pTs[maxNum + start - 1]) {
|
||||
needDelState = true;
|
||||
pWinInfo->winInfo.sessionWin.win.ekey = pTs[maxNum + start - 1];
|
||||
}
|
||||
|
||||
if (needDelState) {
|
||||
memcpy(pWinInfo->winInfo.pStatePos->pKey, &pWinInfo->winInfo.sessionWin, sizeof(SSessionKey));
|
||||
if (pWinInfo->winInfo.pStatePos->needFree) {
|
||||
pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &sWinKey);
|
||||
}
|
||||
}
|
||||
|
||||
return maxNum;
|
||||
}
|
||||
|
||||
void getCountWinRange(SStreamAggSupporter* pAggSup, const SSessionKey* pKey, EStreamType mode, SSessionKey* pDelRange) {
|
||||
*pDelRange = *pKey;
|
||||
SStreamStateCur* pCur = NULL;
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
pCur = pAggSup->stateStore.streamStateCountSeekKeyPrev(pAggSup->pState, pKey, pAggSup->windowCount);
|
||||
} else {
|
||||
pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pAggSup->pState, pKey);
|
||||
}
|
||||
SSessionKey tmpKey = {0};
|
||||
int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &tmpKey, NULL, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
return;
|
||||
}
|
||||
pDelRange->win = tmpKey.win;
|
||||
while (mode == STREAM_DELETE_DATA) {
|
||||
pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur);
|
||||
code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &tmpKey, NULL, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
pDelRange->win.ekey = TMAX(pDelRange->win.ekey, tmpKey.win.ekey);
|
||||
}
|
||||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
}
|
||||
|
||||
static void destroySBuffInfo(SStreamAggSupporter* pAggSup, SBuffInfo* pBuffInfo) {
|
||||
pAggSup->stateStore.streamStateFreeCur(pBuffInfo->pCur);
|
||||
}
|
||||
|
||||
bool inCountCalSlidingWindow(SStreamAggSupporter* pAggSup, STimeWindow* pWin, TSKEY sKey, TSKEY eKey) {
|
||||
if (pAggSup->windowCount == pAggSup->windowSliding) {
|
||||
return true;
|
||||
}
|
||||
if (sKey <= pWin->skey && pWin->ekey <= eKey) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool inCountSlidingWindow(SStreamAggSupporter* pAggSup, STimeWindow* pWin, SDataBlockInfo* pBlockInfo) {
|
||||
return inCountCalSlidingWindow(pAggSup, pWin, pBlockInfo->calWin.skey, pBlockInfo->calWin.ekey);
|
||||
}
|
||||
|
||||
static void doStreamCountAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated,
|
||||
SSHashObj* pStDeleted) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||
uint64_t groupId = pSDataBlock->info.id.groupId;
|
||||
int64_t code = TSDB_CODE_SUCCESS;
|
||||
SResultRow* pResult = NULL;
|
||||
int32_t rows = pSDataBlock->info.rows;
|
||||
int32_t winRows = 0;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
SBuffInfo buffInfo = {.rebuildWindow = false, .winBuffOp = NONE_WINDOW, .pCur = NULL};
|
||||
|
||||
pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version);
|
||||
pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow;
|
||||
if (pAggSup->winRange.ekey <= 0) {
|
||||
pAggSup->winRange.ekey = INT64_MAX;
|
||||
}
|
||||
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
TSKEY* startTsCols = (int64_t*)pStartTsCol->pData;
|
||||
blockDataEnsureCapacity(pAggSup->pScanBlock, rows * 2);
|
||||
SStreamStateCur* pCur = NULL;
|
||||
COUNT_TYPE slidingRows = 0;
|
||||
|
||||
for (int32_t i = 0; i < rows;) {
|
||||
if (pInfo->ignoreExpiredData &&
|
||||
checkExpiredData(&pInfo->streamAggSup.stateStore, pInfo->streamAggSup.pUpdateInfo, &pInfo->twAggSup,
|
||||
pSDataBlock->info.id.uid, startTsCols[i])) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
SCountWindowInfo curWin = {0};
|
||||
buffInfo.rebuildWindow = false;
|
||||
setCountOutputBuf(pAggSup, startTsCols[i], groupId, &curWin, &buffInfo);
|
||||
if (!inCountSlidingWindow(pAggSup, &curWin.winInfo.sessionWin.win, &pSDataBlock->info)) {
|
||||
buffInfo.winBuffOp = MOVE_NEXT_WINDOW;
|
||||
continue;
|
||||
}
|
||||
setSessionWinOutputInfo(pStUpdated, &curWin.winInfo);
|
||||
slidingRows = *curWin.pWindowCount;
|
||||
if (!buffInfo.rebuildWindow) {
|
||||
winRows = updateCountWindowInfo(pAggSup, &curWin, startTsCols, i, rows, pAggSup->windowCount, pStDeleted, &buffInfo.rebuildWindow);
|
||||
}
|
||||
if (buffInfo.rebuildWindow) {
|
||||
SSessionKey range = {0};
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
curWin.winInfo.sessionWin.win.skey = startTsCols[i];
|
||||
curWin.winInfo.sessionWin.win.ekey = startTsCols[i];
|
||||
}
|
||||
getCountWinRange(pAggSup, &curWin.winInfo.sessionWin, STREAM_DELETE_DATA, &range);
|
||||
range.win.skey = TMIN(startTsCols[i], range.win.skey);
|
||||
range.win.ekey = TMAX(startTsCols[rows-1], range.win.ekey);
|
||||
uint64_t uid = 0;
|
||||
appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &range.win.skey, &range.win.ekey, &uid, &range.groupId, NULL);
|
||||
break;
|
||||
}
|
||||
code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput,
|
||||
pOperator, 0);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
qError("%s do stream count aggregate impl error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
saveSessionOutputBuf(pAggSup, &curWin.winInfo);
|
||||
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) {
|
||||
code = saveResult(curWin.winInfo, pStUpdated);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s do stream count aggregate impl, set result error, code %s", GET_TASKID(pTaskInfo),
|
||||
tstrerror(code));
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
SSessionKey key = {0};
|
||||
getSessionHashKey(&curWin.winInfo.sessionWin, &key);
|
||||
tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
if (slidingRows <= pAggSup->windowSliding) {
|
||||
if (slidingRows + winRows > pAggSup->windowSliding) {
|
||||
buffInfo.winBuffOp = CREATE_NEW_WINDOW;
|
||||
winRows = pAggSup->windowSliding - slidingRows;
|
||||
ASSERT(i >= 0);
|
||||
}
|
||||
} else {
|
||||
buffInfo.winBuffOp = MOVE_NEXT_WINDOW;
|
||||
winRows = 0;
|
||||
}
|
||||
}
|
||||
i += winRows;
|
||||
}
|
||||
destroySBuffInfo(pAggSup, &buffInfo);
|
||||
}
|
||||
|
||||
static SSDataBlock* buildCountResult(SOperatorInfo* pOperator) {
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
|
||||
if (pInfo->pDelRes->info.rows > 0) {
|
||||
printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pDelRes;
|
||||
}
|
||||
|
||||
doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes);
|
||||
if (pBInfo->pRes->info.rows > 0) {
|
||||
printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pBInfo->pRes;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t doStreamCountEncodeOpState(void** buf, int32_t len, SOperatorInfo* pOperator, bool isParent) {
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
if (!pInfo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* pData = (buf == NULL) ? NULL : *buf;
|
||||
|
||||
// 1.streamAggSup.pResultRows
|
||||
int32_t tlen = 0;
|
||||
int32_t mapSize = tSimpleHashGetSize(pInfo->streamAggSup.pResultRows);
|
||||
tlen += taosEncodeFixedI32(buf, mapSize);
|
||||
void* pIte = NULL;
|
||||
size_t keyLen = 0;
|
||||
int32_t iter = 0;
|
||||
while ((pIte = tSimpleHashIterate(pInfo->streamAggSup.pResultRows, pIte, &iter)) != NULL) {
|
||||
void* key = taosHashGetKey(pIte, &keyLen);
|
||||
tlen += encodeSSessionKey(buf, key);
|
||||
tlen += encodeSResultWindowInfo(buf, pIte, pInfo->streamAggSup.resultRowSize);
|
||||
}
|
||||
|
||||
// 2.twAggSup
|
||||
tlen += encodeSTimeWindowAggSupp(buf, &pInfo->twAggSup);
|
||||
|
||||
// 3.dataVersion
|
||||
tlen += taosEncodeFixedI32(buf, pInfo->dataVersion);
|
||||
|
||||
// 4.checksum
|
||||
if (isParent) {
|
||||
if (buf) {
|
||||
uint32_t cksum = taosCalcChecksum(0, pData, len - sizeof(uint32_t));
|
||||
tlen += taosEncodeFixedU32(buf, cksum);
|
||||
} else {
|
||||
tlen += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void* doStreamCountDecodeOpState(void* buf, int32_t len, SOperatorInfo* pOperator, bool isParent) {
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
if (!pInfo) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
// 4.checksum
|
||||
if (isParent) {
|
||||
int32_t dataLen = len - sizeof(uint32_t);
|
||||
void* pCksum = POINTER_SHIFT(buf, dataLen);
|
||||
if (taosCheckChecksum(buf, dataLen, *(uint32_t*)pCksum) != TSDB_CODE_SUCCESS) {
|
||||
qError("stream count state is invalid");
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
// 1.streamAggSup.pResultRows
|
||||
int32_t mapSize = 0;
|
||||
buf = taosDecodeFixedI32(buf, &mapSize);
|
||||
for (int32_t i = 0; i < mapSize; i++) {
|
||||
SSessionKey key = {0};
|
||||
SResultWindowInfo winfo = {0};
|
||||
buf = decodeSSessionKey(buf, &key);
|
||||
buf = decodeSResultWindowInfo(buf, &winfo, pInfo->streamAggSup.resultRowSize);
|
||||
tSimpleHashPut(pInfo->streamAggSup.pResultRows, &key, sizeof(SSessionKey), &winfo, sizeof(SResultWindowInfo));
|
||||
}
|
||||
|
||||
// 2.twAggSup
|
||||
buf = decodeSTimeWindowAggSupp(buf, &pInfo->twAggSup);
|
||||
|
||||
// 3.dataVersion
|
||||
buf = taosDecodeFixedI64(buf, &pInfo->dataVersion);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void doStreamCountSaveCheckpoint(SOperatorInfo* pOperator) {
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t len = doStreamCountEncodeOpState(NULL, 0, pOperator, true);
|
||||
void* buf = taosMemoryCalloc(1, len);
|
||||
void* pBuf = buf;
|
||||
len = doStreamCountEncodeOpState(&pBuf, len, pOperator, true);
|
||||
pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_COUNT_OP_CHECKPOINT_NAME,
|
||||
strlen(STREAM_COUNT_OP_CHECKPOINT_NAME), buf, len);
|
||||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
void doResetCountWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock) {
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
TSKEY* startDatas = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
TSKEY* endDatas = (TSKEY*)pEndTsCol->pData;
|
||||
SColumnInfoData* pCalStartTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
|
||||
TSKEY* calStartDatas = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pCalEndTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
|
||||
TSKEY* calEndDatas = (TSKEY*)pEndTsCol->pData;
|
||||
SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
|
||||
uint64_t* gpDatas = (uint64_t*)pGroupCol->pData;
|
||||
|
||||
SRowBuffPos* pPos = NULL;
|
||||
int32_t size = 0;
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
SSessionKey key = {.groupId = gpDatas[i], .win.skey = startDatas[i], .win.ekey = endDatas[i]};
|
||||
SStreamStateCur* pCur = NULL;
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
pCur = pAggSup->stateStore.streamStateCountSeekKeyPrev(pAggSup->pState, &key, pAggSup->windowCount);
|
||||
} else {
|
||||
pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pAggSup->pState, &key);
|
||||
}
|
||||
while (1) {
|
||||
SSessionKey tmpKey = {0};
|
||||
int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &tmpKey, (void **)&pPos, &size);
|
||||
if (code != TSDB_CODE_SUCCESS || tmpKey.win.skey > endDatas[i]) {
|
||||
pAggSup->stateStore.streamStateFreeCur(pCur);
|
||||
break;
|
||||
}
|
||||
if (!inCountCalSlidingWindow(pAggSup, &tmpKey.win, calStartDatas[i], calEndDatas[i])) {
|
||||
pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur);
|
||||
continue;
|
||||
}
|
||||
pAggSup->stateStore.streamStateSessionReset(pAggSup->pState, pPos->pRowBuff);
|
||||
pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void doDeleteCountWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) {
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
TSKEY* startDatas = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
TSKEY* endDatas = (TSKEY*)pEndTsCol->pData;
|
||||
SColumnInfoData* pCalStartTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
|
||||
TSKEY* calStartDatas = (TSKEY*)pStartTsCol->pData;
|
||||
SColumnInfoData* pCalEndTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
|
||||
TSKEY* calEndDatas = (TSKEY*)pEndTsCol->pData;
|
||||
SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
|
||||
uint64_t* gpDatas = (uint64_t*)pGroupCol->pData;
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
SSessionKey key = {.win.skey = startDatas[i], .win.ekey = endDatas[i], .groupId = gpDatas[i]};
|
||||
while (1) {
|
||||
SSessionKey curWin = {0};
|
||||
int32_t code = pAggSup->stateStore.streamStateCountGetKeyByRange(pAggSup->pState, &key, &curWin);
|
||||
if (code == TSDB_CODE_FAILED) {
|
||||
break;
|
||||
}
|
||||
doDeleteSessionWindow(pAggSup, &curWin);
|
||||
if (result) {
|
||||
saveDeleteInfo(result, curWin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deleteCountWinState(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SSHashObj* pMapUpdate,
|
||||
SSHashObj* pMapDelete) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SSessionKey));
|
||||
if (isSlidingCountWindow(pAggSup)) {
|
||||
doDeleteCountWindows(pAggSup, pBlock, pWins);
|
||||
} else {
|
||||
doDeleteTimeWindows(pAggSup, pBlock, pWins);
|
||||
}
|
||||
removeSessionResults(pAggSup, pMapUpdate, pWins);
|
||||
copyDeleteWindowInfo(pWins, pMapDelete);
|
||||
taosArrayDestroy(pWins);
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamCountAgg(SOperatorInfo* pOperator) {
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status);
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
} else if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
SSDataBlock* opRes = buildCountResult(pOperator);
|
||||
if (opRes) {
|
||||
return opRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (!pInfo->pUpdated) {
|
||||
pInfo->pUpdated = taosArrayInit(16, sizeof(SResultWindowInfo));
|
||||
}
|
||||
if (!pInfo->pStUpdated) {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pStUpdated = tSimpleHashInit(64, hashFn);
|
||||
}
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo));
|
||||
|
||||
if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
|
||||
deleteCountWinState(&pInfo->streamAggSup, pBlock, pInfo->pStUpdated, pInfo->pStDeleted);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_CLEAR) {
|
||||
doResetCountWindows(&pInfo->streamAggSup, pBlock);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
pInfo->recvGetAll = true;
|
||||
getAllSessionWindow(pAggSup->pResultRows, pInfo->pStUpdated);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) {
|
||||
return pBlock;
|
||||
} else if (pBlock->info.type == STREAM_CHECKPOINT) {
|
||||
pAggSup->stateStore.streamStateCommit(pAggSup->pState);
|
||||
doStreamCountSaveCheckpoint(pOperator);
|
||||
copyDataBlock(pInfo->pCheckpointRes, pBlock);
|
||||
continue;
|
||||
} else {
|
||||
ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type");
|
||||
}
|
||||
|
||||
if (pInfo->scalarSupp.pExprInfo != NULL) {
|
||||
SExprSupp* pExprSup = &pInfo->scalarSupp;
|
||||
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||
}
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
|
||||
doStreamCountAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark);
|
||||
}
|
||||
// restore the value
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
|
||||
closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pInfo->pStUpdated);
|
||||
copyUpdateResult(&pInfo->pStUpdated, pInfo->pUpdated, sessionKeyCompareAsc);
|
||||
removeSessionDeleteResults(pInfo->pStDeleted, pInfo->pUpdated);
|
||||
initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated);
|
||||
pInfo->pUpdated = NULL;
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
SSDataBlock* opRes = buildCountResult(pOperator);
|
||||
if (opRes) {
|
||||
return opRes;
|
||||
}
|
||||
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void streamCountReleaseState(SOperatorInfo* pOperator) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
int32_t resSize = sizeof(TSKEY);
|
||||
char* pBuff = taosMemoryCalloc(1, resSize);
|
||||
memcpy(pBuff, &pInfo->twAggSup.maxTs, sizeof(TSKEY));
|
||||
qDebug("===stream=== count window operator relase state. ");
|
||||
pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_COUNT_OP_STATE_NAME,
|
||||
strlen(STREAM_COUNT_OP_STATE_NAME), pBuff, resSize);
|
||||
pInfo->streamAggSup.stateStore.streamStateCommit(pInfo->streamAggSup.pState);
|
||||
taosMemoryFreeClear(pBuff);
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (downstream->fpSet.releaseStreamStateFn) {
|
||||
downstream->fpSet.releaseStreamStateFn(downstream);
|
||||
}
|
||||
}
|
||||
|
||||
void streamCountReloadState(SOperatorInfo* pOperator) {
|
||||
SStreamCountAggOperatorInfo* pInfo = pOperator->info;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
int32_t size = 0;
|
||||
void* pBuf = NULL;
|
||||
|
||||
int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_COUNT_OP_STATE_NAME,
|
||||
strlen(STREAM_COUNT_OP_STATE_NAME), &pBuf, &size);
|
||||
TSKEY ts = *(TSKEY*)pBuf;
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts);
|
||||
taosMemoryFree(pBuf);
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
reloadAggSupFromDownStream(downstream, &pInfo->streamAggSup);
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamCountAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) {
|
||||
SCountWinodwPhysiNode* pCountNode = (SCountWinodwPhysiNode*)pPhyNode;
|
||||
int32_t numOfCols = 0;
|
||||
int32_t code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
SStreamCountAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamCountAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
if (pCountNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalar = 0;
|
||||
SExprInfo* pScalarExprInfo = createExprInfo(pCountNode->window.pExprs, NULL, &numOfScalar);
|
||||
code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
SExprSupp* pExpSup = &pOperator->exprSupp;
|
||||
|
||||
SExprInfo* pExprInfo = createExprInfo(pCountNode->window.pFuncs, NULL, &numOfCols);
|
||||
SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
|
||||
code = initBasicInfoEx(&pInfo->binfo, pExpSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, 0,
|
||||
pTaskInfo->streamInfo.pState, sizeof(COUNT_TYPE), 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
pInfo->streamAggSup.windowCount = pCountNode->windowCount;
|
||||
pInfo->streamAggSup.windowSliding = pCountNode->windowSliding;
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pCountNode->window.watermark,
|
||||
.calTrigger = pCountNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pCountNode->window.pTspk)->slotId;
|
||||
|
||||
pInfo->binfo.pRes = pResBlock;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pStDeleted = tSimpleHashInit(64, hashFn);
|
||||
pInfo->pDelIterator = NULL;
|
||||
pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
|
||||
pInfo->ignoreExpiredData = pCountNode->window.igExpired;
|
||||
pInfo->ignoreExpiredDataSaved = false;
|
||||
pInfo->pUpdated = NULL;
|
||||
pInfo->pStUpdated = NULL;
|
||||
pInfo->dataVersion = 0;
|
||||
pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey));
|
||||
if (!pInfo->historyWins) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pCheckpointRes = createSpecialDataBlock(STREAM_CHECKPOINT);
|
||||
pInfo->recvGetAll = false;
|
||||
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT;
|
||||
// for stream
|
||||
void* buff = NULL;
|
||||
int32_t len = 0;
|
||||
int32_t res =
|
||||
pInfo->streamAggSup.stateStore.streamStateGetInfo(pInfo->streamAggSup.pState, STREAM_COUNT_OP_CHECKPOINT_NAME,
|
||||
strlen(STREAM_COUNT_OP_CHECKPOINT_NAME), &buff, &len);
|
||||
if (res == TSDB_CODE_SUCCESS) {
|
||||
doStreamCountDecodeOpState(buff, len, pOperator, true);
|
||||
taosMemoryFree(buff);
|
||||
}
|
||||
setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT, true,
|
||||
OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamCountAgg, NULL, destroyStreamCountAggOperatorInfo,
|
||||
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
||||
setOperatorStreamStateFn(pOperator, streamCountReleaseState, streamCountReloadState);
|
||||
|
||||
if (downstream) {
|
||||
initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup);
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
}
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroyStreamCountAggOperatorInfo(pInfo);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pOperator);
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1945,7 +1945,7 @@ int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) {
|
||||
bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) {
|
||||
pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey);
|
||||
SSessionKey hashKey = {0};
|
||||
getSessionHashKey(pKey, &hashKey);
|
||||
|
@ -2343,7 +2343,7 @@ int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) {
|
||||
void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) {
|
||||
int32_t size = taosArrayGetSize(pResWins);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
SSessionKey* pWinKey = taosArrayGet(pResWins, i);
|
||||
|
|
|
@ -1043,7 +1043,7 @@ static int32_t sortBlocksToExtSource(SSortHandle* pHandle, SArray* aBlk, SBlockO
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SSDataBlock* getRowsBlockWithinMergeLimit(const SSortHandle* pHandle, SSHashObj* mTableNumRows, SSDataBlock* pOrigBlk, bool* pExtractedBlock) {
|
||||
static SSDataBlock* getRowsBlockWithinMergeLimit(const SSortHandle* pHandle, SSHashObj* mTableNumRows, SSDataBlock* pOrigBlk, bool* pExtractedBlock, bool *pSkipBlock) {
|
||||
int64_t nRows = 0;
|
||||
int64_t prevRows = 0;
|
||||
void* pNum = tSimpleHashGet(mTableNumRows, &pOrigBlk->info.id.uid, sizeof(pOrigBlk->info.id.uid));
|
||||
|
@ -1062,9 +1062,15 @@ static SSDataBlock* getRowsBlockWithinMergeLimit(const SSortHandle* pHandle, SSH
|
|||
if (pHandle->mergeLimitReachedFn) {
|
||||
pHandle->mergeLimitReachedFn(pOrigBlk->info.id.uid, pHandle->mergeLimitReachedParam);
|
||||
}
|
||||
keepRows = pHandle->mergeLimit - prevRows;
|
||||
keepRows = pHandle->mergeLimit > prevRows ? (pHandle->mergeLimit - prevRows) : 0;
|
||||
}
|
||||
|
||||
if (keepRows == 0) {
|
||||
*pSkipBlock = true;
|
||||
return pOrigBlk;
|
||||
}
|
||||
|
||||
*pSkipBlock = false;
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (keepRows != pOrigBlk->info.rows) {
|
||||
pBlock = blockDataExtractBlock(pOrigBlk, 0, keepRows);
|
||||
|
@ -1106,8 +1112,12 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
|||
|
||||
int64_t p = taosGetTimestampUs();
|
||||
bool bExtractedBlock = false;
|
||||
bool bSkipBlock = false;
|
||||
if (pBlk != NULL && pHandle->mergeLimit > 0) {
|
||||
pBlk = getRowsBlockWithinMergeLimit(pHandle, mTableNumRows, pBlk, &bExtractedBlock);
|
||||
pBlk = getRowsBlockWithinMergeLimit(pHandle, mTableNumRows, pBlk, &bExtractedBlock, &bSkipBlock);
|
||||
if (bSkipBlock) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlk != NULL) {
|
||||
|
@ -1121,7 +1131,6 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
|||
|
||||
if (pBlk != NULL) {
|
||||
szSort += blockDataGetSize(pBlk);
|
||||
|
||||
void* ppBlk = tSimpleHashGet(mUidBlk, &pBlk->info.id.uid, sizeof(pBlk->info.id.uid));
|
||||
if (ppBlk != NULL) {
|
||||
SSDataBlock* tBlk = *(SSDataBlock**)(ppBlk);
|
||||
|
@ -1138,7 +1147,6 @@ static int32_t createBlocksMergeSortInitialSources(SSortHandle* pHandle) {
|
|||
|
||||
if ((pBlk != NULL && szSort > maxBufSize) || (pBlk == NULL && szSort > 0)) {
|
||||
tSimpleHashClear(mUidBlk);
|
||||
|
||||
code = sortBlocksToExtSource(pHandle, aBlkSort, pOrder, aExtSrc);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tSimpleHashCleanup(mUidBlk);
|
||||
|
|
|
@ -330,6 +330,13 @@ static int32_t eventWindowNodeCopy(const SEventWindowNode* pSrc, SEventWindowNod
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t countWindowNodeCopy(const SCountWindowNode* pSrc, SCountWindowNode* pDst) {
|
||||
CLONE_NODE_FIELD(pCol);
|
||||
COPY_SCALAR_FIELD(windowCount);
|
||||
COPY_SCALAR_FIELD(windowSliding);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sessionWindowNodeCopy(const SSessionWindowNode* pSrc, SSessionWindowNode* pDst) {
|
||||
CLONE_NODE_FIELD_EX(pCol, SColumnNode*);
|
||||
CLONE_NODE_FIELD_EX(pGap, SValueNode*);
|
||||
|
@ -565,6 +572,8 @@ static int32_t logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* p
|
|||
COPY_SCALAR_FIELD(igExpired);
|
||||
COPY_SCALAR_FIELD(igCheckUpdate);
|
||||
COPY_SCALAR_FIELD(windowAlgo);
|
||||
COPY_SCALAR_FIELD(windowCount);
|
||||
COPY_SCALAR_FIELD(windowSliding);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -867,6 +876,9 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
|||
case QUERY_NODE_EVENT_WINDOW:
|
||||
code = eventWindowNodeCopy((const SEventWindowNode*)pNode, (SEventWindowNode*)pDst);
|
||||
break;
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
code = countWindowNodeCopy((const SCountWindowNode*)pNode, (SCountWindowNode*)pDst);
|
||||
break;
|
||||
case QUERY_NODE_SESSION_WINDOW:
|
||||
code = sessionWindowNodeCopy((const SSessionWindowNode*)pNode, (SSessionWindowNode*)pDst);
|
||||
break;
|
||||
|
|
|
@ -93,6 +93,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "EventWindow";
|
||||
case QUERY_NODE_WINDOW_OFFSET:
|
||||
return "WindowOffset";
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return "CountWindow";
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return "SetOperator";
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -345,6 +347,10 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "PhysiMergeEventWindow";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
return "PhysiStreamEventWindow";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
return "PhysiMergeCountWindow";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
return "PhysiStreamCountWindow";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
return "PhysiProject";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN:
|
||||
|
@ -2839,6 +2845,36 @@ static int32_t jsonToPhysiEventWindowNode(const SJson* pJson, void* pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static const char* jkCountWindowPhysiPlanWindowCount = "WindowCount";
|
||||
static const char* jkCountWindowPhysiPlanWindowSliding = "WindowSliding";
|
||||
|
||||
static int32_t physiCountWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SCountWinodwPhysiNode* pNode = (const SCountWinodwPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physiWindowNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkCountWindowPhysiPlanWindowCount, pNode->windowCount);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkCountWindowPhysiPlanWindowSliding, pNode->windowSliding);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToPhysiCountWindowNode(const SJson* pJson, void* pObj) {
|
||||
SCountWinodwPhysiNode* pNode = (SCountWinodwPhysiNode*)pObj;
|
||||
|
||||
int32_t code = jsonToPhysiWindowNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkCountWindowPhysiPlanWindowCount, &pNode->windowCount);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkCountWindowPhysiPlanWindowSliding, &pNode->windowSliding);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkPartitionPhysiPlanExprs = "Exprs";
|
||||
static const char* jkPartitionPhysiPlanPartitionKeys = "PartitionKeys";
|
||||
static const char* jkPartitionPhysiPlanTargets = "Targets";
|
||||
|
@ -4509,6 +4545,36 @@ static int32_t jsonToEventWindowNode(const SJson* pJson, void* pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static const char* jkCountWindowTsPrimaryKey = "CountTsPrimaryKey";
|
||||
static const char* jkCountWindowCount = "CountWindowCount";
|
||||
static const char* jkCountWindowSliding = "CountWindowSliding";
|
||||
|
||||
static int32_t countWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SCountWindowNode* pNode = (const SCountWindowNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddObject(pJson, jkCountWindowTsPrimaryKey, nodeToJson, pNode->pCol);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkCountWindowCount, pNode->windowCount);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkCountWindowSliding, pNode->windowSliding);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToCountWindowNode(const SJson* pJson, void* pObj) {
|
||||
SCountWindowNode* pNode = (SCountWindowNode*)pObj;
|
||||
|
||||
int32_t code = jsonToNodeObject(pJson, jkCountWindowTsPrimaryKey, &pNode->pCol);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkCountWindowCount, &pNode->windowCount);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkCountWindowSliding, &pNode->windowSliding);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkIntervalWindowInterval = "Interval";
|
||||
static const char* jkIntervalWindowOffset = "Offset";
|
||||
static const char* jkIntervalWindowSliding = "Sliding";
|
||||
|
@ -7111,6 +7177,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
return eventWindowNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_WINDOW_OFFSET:
|
||||
return windowOffsetNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return countWindowNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return setOperatorToJson(pObj, pJson);
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -7350,6 +7418,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
return physiEventWindowNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
return physiCountWindowNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
return physiPartitionNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||
|
@ -7445,6 +7516,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
return jsonToEventWindowNode(pJson, pObj);
|
||||
case QUERY_NODE_WINDOW_OFFSET:
|
||||
return jsonToWindowOffsetNode(pJson, pObj);
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return jsonToCountWindowNode(pJson, pObj);
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return jsonToSetOperator(pJson, pObj);
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -7692,6 +7765,9 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
return jsonToPhysiEventWindowNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
return jsonToPhysiCountWindowNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
return jsonToPhysiPartitionNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||
|
|
|
@ -3336,6 +3336,46 @@ static int32_t msgToPhysiEventWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
enum { PHY_COUNT_CODE_WINDOW = 1, PHY_COUNT_CODE_WINDOW_COUNT, PHY_COUNT_CODE_WINDOW_SLIDING };
|
||||
|
||||
static int32_t physiCountWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
const SCountWinodwPhysiNode* pNode = (const SCountWinodwPhysiNode*)pObj;
|
||||
|
||||
int32_t code = tlvEncodeObj(pEncoder, PHY_COUNT_CODE_WINDOW, physiWindowNodeToMsg, &pNode->window);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI64(pEncoder, PHY_COUNT_CODE_WINDOW_COUNT, pNode->windowCount);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI64(pEncoder, PHY_COUNT_CODE_WINDOW_SLIDING, pNode->windowSliding);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t msgToPhysiCountWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
||||
SCountWinodwPhysiNode* pNode = (SCountWinodwPhysiNode*)pObj;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
STlv* pTlv = NULL;
|
||||
tlvForEach(pDecoder, pTlv, code) {
|
||||
switch (pTlv->type) {
|
||||
case PHY_COUNT_CODE_WINDOW:
|
||||
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiWindowNode, &pNode->window);
|
||||
break;
|
||||
case PHY_COUNT_CODE_WINDOW_COUNT:
|
||||
code = tlvDecodeI64(pTlv, &pNode->windowCount);
|
||||
break;
|
||||
case PHY_COUNT_CODE_WINDOW_SLIDING:
|
||||
code = tlvDecodeI64(pTlv, &pNode->windowSliding);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
enum {
|
||||
PHY_PARTITION_CODE_BASE_NODE = 1,
|
||||
PHY_PARTITION_CODE_EXPR,
|
||||
|
@ -4329,6 +4369,10 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
code = physiEventWindowNodeToMsg(pObj, pEncoder);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
code = physiCountWindowNodeToMsg(pObj, pEncoder);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
code = physiPartitionNodeToMsg(pObj, pEncoder);
|
||||
break;
|
||||
|
@ -4487,6 +4531,10 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
code = msgToPhysiEventWindowNode(pDecoder, pObj);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
code = msgToPhysiCountWindowNode(pDecoder, pObj);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
code = msgToPhysiPartitionNode(pDecoder, pObj);
|
||||
break;
|
||||
|
|
|
@ -176,6 +176,11 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COUNT_WINDOW: {
|
||||
SCountWindowNode* pEvent = (SCountWindowNode*)pNode;
|
||||
res = walkExpr(pEvent->pCol, order, walker, pContext);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -375,6 +380,11 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COUNT_WINDOW: {
|
||||
SCountWindowNode* pEvent = (SCountWindowNode*)pNode;
|
||||
res = rewriteExpr(&pEvent->pCol, order, rewriter, pContext);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -371,6 +371,8 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SCaseWhenNode));
|
||||
case QUERY_NODE_EVENT_WINDOW:
|
||||
return makeNode(type, sizeof(SEventWindowNode));
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return makeNode(type, sizeof(SCountWindowNode));
|
||||
case QUERY_NODE_HINT:
|
||||
return makeNode(type, sizeof(SHintNode));
|
||||
case QUERY_NODE_VIEW:
|
||||
|
@ -656,6 +658,10 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SEventWinodwPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT:
|
||||
return makeNode(type, sizeof(SStreamEventWinodwPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
return makeNode(type, sizeof(SCountWinodwPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||
return makeNode(type, sizeof(SStreamCountWinodwPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||
return makeNode(type, sizeof(SPartitionPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||
|
@ -924,6 +930,11 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyNode(pEvent->pEndCond);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COUNT_WINDOW: {
|
||||
SCountWindowNode* pEvent = (SCountWindowNode*)pNode;
|
||||
nodesDestroyNode(pEvent->pCol);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_HINT: {
|
||||
SHintNode* pHint = (SHintNode*)pNode;
|
||||
destroyHintValue(pHint->option, pHint->value);
|
||||
|
@ -1518,6 +1529,12 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyNode(pPhyNode->pEndCond);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT: {
|
||||
SCountWinodwPhysiNode* pPhyNode = (SCountWinodwPhysiNode*)pNode;
|
||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
|
||||
destroyPartitionPhysiNode((SPartitionPhysiNode*)pNode);
|
||||
break;
|
||||
|
|
|
@ -132,6 +132,7 @@ SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order
|
|||
SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap);
|
||||
SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr);
|
||||
SNode* createEventWindowNode(SAstCreateContext* pCxt, SNode* pStartCond, SNode* pEndCond);
|
||||
SNode* createCountWindowNode(SAstCreateContext* pCxt, const SToken* pCountToken, const SToken* pSlidingToken);
|
||||
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
||||
SNode* pFill);
|
||||
SNode* createWindowOffsetNode(SAstCreateContext* pCxt, SNode* pStartOffset, SNode* pEndOffset);
|
||||
|
|
|
@ -516,7 +516,7 @@ cmd ::= SHOW VNODES.
|
|||
// show alive
|
||||
cmd ::= SHOW db_name_cond_opt(A) ALIVE. { pCxt->pRootNode = createShowAliveStmt(pCxt, A, QUERY_NODE_SHOW_DB_ALIVE_STMT); }
|
||||
cmd ::= SHOW CLUSTER ALIVE. { pCxt->pRootNode = createShowAliveStmt(pCxt, NULL, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT); }
|
||||
cmd ::= SHOW db_name_cond_opt(A) VIEWS. { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VIEWS_STMT, A, NULL, OP_TYPE_LIKE); }
|
||||
cmd ::= SHOW db_name_cond_opt(A) VIEWS like_pattern_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VIEWS_STMT, A, B, OP_TYPE_LIKE); }
|
||||
cmd ::= SHOW CREATE VIEW full_table_name(A). { pCxt->pRootNode = createShowCreateViewStmt(pCxt, QUERY_NODE_SHOW_CREATE_VIEW_STMT, A); }
|
||||
cmd ::= SHOW COMPACTS. { pCxt->pRootNode = createShowCompactsStmt(pCxt, QUERY_NODE_SHOW_COMPACTS_STMT); }
|
||||
cmd ::= SHOW COMPACT NK_INTEGER(A). { pCxt->pRootNode = createShowCompactDetailsStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &A)); }
|
||||
|
@ -1193,6 +1193,10 @@ twindow_clause_opt(A) ::=
|
|||
sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), D, E); }
|
||||
twindow_clause_opt(A) ::=
|
||||
EVENT_WINDOW START WITH search_condition(B) END WITH search_condition(C). { A = createEventWindowNode(pCxt, B, C); }
|
||||
twindow_clause_opt(A) ::=
|
||||
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_RP. { A = createCountWindowNode(pCxt, &B, &B); }
|
||||
twindow_clause_opt(A) ::=
|
||||
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createCountWindowNode(pCxt, &B, &C); }
|
||||
|
||||
sliding_opt(A) ::= . { A = NULL; }
|
||||
sliding_opt(A) ::= SLIDING NK_LP interval_sliding_duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||
|
|
|
@ -928,6 +928,20 @@ SNode* createEventWindowNode(SAstCreateContext* pCxt, SNode* pStartCond, SNode*
|
|||
return (SNode*)pEvent;
|
||||
}
|
||||
|
||||
SNode* createCountWindowNode(SAstCreateContext* pCxt, const SToken* pCountToken, const SToken* pSlidingToken) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
SCountWindowNode* pCount = (SCountWindowNode*)nodesMakeNode(QUERY_NODE_COUNT_WINDOW);
|
||||
CHECK_OUT_OF_MEM(pCount);
|
||||
pCount->pCol = createPrimaryKeyCol(pCxt, NULL);
|
||||
if (NULL == pCount->pCol) {
|
||||
nodesDestroyNode((SNode*)pCount);
|
||||
CHECK_OUT_OF_MEM(NULL);
|
||||
}
|
||||
pCount->windowCount = taosStr2Int64(pCountToken->z, NULL, 10);
|
||||
pCount->windowSliding = taosStr2Int64(pSlidingToken->z, NULL, 10);
|
||||
return (SNode*)pCount;
|
||||
}
|
||||
|
||||
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
||||
SNode* pFill) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
|
|
|
@ -663,7 +663,7 @@ int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreate
|
|||
}
|
||||
|
||||
char* p = (char*)data;
|
||||
// | version | total length | total rows | total columns | flag seg| block group id | column schema | each column
|
||||
// | version | total length | total rows | blankFill | total columns | flag seg| block group id | column schema | each column
|
||||
// length |
|
||||
int32_t version = *(int32_t*)data;
|
||||
p += sizeof(int32_t);
|
||||
|
|
|
@ -75,6 +75,7 @@ static SKeyword keywordTable[] = {
|
|||
{"CONSUMERS", TK_CONSUMERS},
|
||||
{"CONTAINS", TK_CONTAINS},
|
||||
{"COUNT", TK_COUNT},
|
||||
{"COUNT_WINDOW", TK_COUNT_WINDOW},
|
||||
{"CREATE", TK_CREATE},
|
||||
{"CURRENT_USER", TK_CURRENT_USER},
|
||||
{"DATABASE", TK_DATABASE},
|
||||
|
|
|
@ -4222,6 +4222,15 @@ static int32_t translateEventWindow(STranslateContext* pCxt, SSelectStmt* pSelec
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateCountWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||
!isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_QUERY,
|
||||
"COUNT_WINDOW requires valid time series input");
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
switch (nodeType(pSelect->pWindow)) {
|
||||
case QUERY_NODE_STATE_WINDOW:
|
||||
|
@ -4232,6 +4241,8 @@ static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSe
|
|||
return translateIntervalWindow(pCxt, pSelect);
|
||||
case QUERY_NODE_EVENT_WINDOW:
|
||||
return translateEventWindow(pCxt, pSelect);
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return translateCountWindow(pCxt, pSelect);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -8007,6 +8018,53 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm
|
|||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"The trigger mode of non window query can only be AT_ONCE");
|
||||
}
|
||||
|
||||
if (pSelect->pWindow != NULL && pSelect->pWindow->type == QUERY_NODE_COUNT_WINDOW) {
|
||||
if ( (SRealTableNode*)pSelect->pFromTable && ((SRealTableNode*)pSelect->pFromTable)->pMeta
|
||||
&& TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType
|
||||
&& !hasPartitionByTbname(pSelect->pPartitionByList) ) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Count window for stream on super table must patitioned by table name");
|
||||
}
|
||||
|
||||
int64_t watermark = 0;
|
||||
if (pStmt->pOptions->pWatermark) {
|
||||
translateValue(pCxt, (SValueNode*)pStmt->pOptions->pWatermark);
|
||||
watermark =((SValueNode*)pStmt->pOptions->pWatermark)->datum.i;
|
||||
}
|
||||
if (watermark <= 0) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Watermark of Count window must exceed 0.");
|
||||
}
|
||||
|
||||
if (pStmt->pOptions->ignoreExpired != 1) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Ignore expired data of Count window must be 1.");
|
||||
}
|
||||
|
||||
SCountWindowNode* pCountWin = (SCountWindowNode*)pSelect->pWindow;
|
||||
if (pCountWin->windowCount <= 1) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Size of Count window must exceed 1.");
|
||||
}
|
||||
|
||||
if (pCountWin->windowSliding <= 0) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Size of Count window must exceed 0.");
|
||||
}
|
||||
|
||||
if (pCountWin->windowSliding > pCountWin->windowCount) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"sliding value no larger than the count value.");
|
||||
}
|
||||
|
||||
if (pCountWin->windowCount > INT32_MAX) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||
"Size of Count window must less than 2147483647(INT32_MAX).");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -9619,7 +9677,20 @@ static int32_t createOperatorNode(EOperatorType opType, const char* pColName, SN
|
|||
}
|
||||
|
||||
static const char* getTbNameColName(ENodeType type) {
|
||||
return (QUERY_NODE_SHOW_STABLES_STMT == type ? "stable_name" : "table_name");
|
||||
const char* colName;
|
||||
switch (type)
|
||||
{
|
||||
case QUERY_NODE_SHOW_VIEWS_STMT:
|
||||
colName = "view_name";
|
||||
break;
|
||||
case QUERY_NODE_SHOW_STABLES_STMT:
|
||||
colName = "stable_name";
|
||||
break;
|
||||
default:
|
||||
colName = "table_name";
|
||||
break;
|
||||
}
|
||||
return colName;
|
||||
}
|
||||
|
||||
static int32_t createLogicCondNode(SNode* pCond1, SNode* pCond2, SNode** pCond, ELogicConditionType logicCondType) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1041,6 +1041,29 @@ static int32_t createWindowLogicNodeByEvent(SLogicPlanContext* pCxt, SEventWindo
|
|||
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
||||
}
|
||||
|
||||
static int32_t createWindowLogicNodeByCount(SLogicPlanContext* pCxt, SCountWindowNode* pCount, SSelectStmt* pSelect,
|
||||
SLogicNode** pLogicNode) {
|
||||
SWindowLogicNode* pWindow = (SWindowLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
|
||||
if (NULL == pWindow) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pWindow->winType = WINDOW_TYPE_COUNT;
|
||||
pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pWindow->node.requireDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
|
||||
pWindow->node.resultDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
|
||||
pWindow->windowCount = pCount->windowCount;
|
||||
pWindow->windowSliding = pCount->windowSliding;
|
||||
pWindow->pTspk = nodesCloneNode(pCount->pCol);
|
||||
if (NULL == pWindow->pTspk) {
|
||||
nodesDestroyNode((SNode*)pWindow);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
||||
}
|
||||
|
||||
static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||
if (NULL == pSelect->pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1054,6 +1077,8 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
return createWindowLogicNodeByInterval(pCxt, (SIntervalWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||
case QUERY_NODE_EVENT_WINDOW:
|
||||
return createWindowLogicNodeByEvent(pCxt, (SEventWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||
case QUERY_NODE_COUNT_WINDOW:
|
||||
return createWindowLogicNodeByCount(pCxt, (SCountWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1893,6 +1893,27 @@ static int32_t createEventWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pC
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t createCountWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
||||
SWindowLogicNode* pWindowLogicNode, SPhysiNode** pPhyNode) {
|
||||
SCountWinodwPhysiNode* pCount = (SCountWinodwPhysiNode*)makePhysiNode(
|
||||
pCxt, (SLogicNode*)pWindowLogicNode,
|
||||
(pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT : QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT));
|
||||
if (NULL == pCount) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCount->windowCount = pWindowLogicNode->windowCount;
|
||||
pCount->windowSliding = pWindowLogicNode->windowSliding;
|
||||
|
||||
int32_t code = createWindowPhysiNodeFinalize(pCxt, pChildren, &pCount->window, pWindowLogicNode);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPhyNode = (SPhysiNode*)pCount;
|
||||
} else {
|
||||
nodesDestroyNode((SNode*)pCount);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowLogicNode* pWindowLogicNode,
|
||||
SPhysiNode** pPhyNode) {
|
||||
switch (pWindowLogicNode->winType) {
|
||||
|
@ -1904,6 +1925,8 @@ static int32_t createWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildr
|
|||
return createStateWindowPhysiNode(pCxt, pChildren, pWindowLogicNode, pPhyNode);
|
||||
case WINDOW_TYPE_EVENT:
|
||||
return createEventWindowPhysiNode(pCxt, pChildren, pWindowLogicNode, pPhyNode);
|
||||
case WINDOW_TYPE_COUNT:
|
||||
return createCountWindowPhysiNode(pCxt, pChildren, pWindowLogicNode, pPhyNode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -872,6 +872,18 @@ static int32_t stbSplSplitEvent(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t stbSplSplitCountForStream(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
static int32_t stbSplSplitCount(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
if (pCxt->pPlanCxt->streamQuery) {
|
||||
return stbSplSplitCountForStream(pCxt, pInfo);
|
||||
} else {
|
||||
return stbSplSplitSessionOrStateForBatch(pCxt, pInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t stbSplSplitWindowForCrossTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
switch (((SWindowLogicNode*)pInfo->pSplitNode)->winType) {
|
||||
case WINDOW_TYPE_INTERVAL:
|
||||
|
@ -882,6 +894,8 @@ static int32_t stbSplSplitWindowForCrossTable(SSplitContext* pCxt, SStableSplitI
|
|||
return stbSplSplitState(pCxt, pInfo);
|
||||
case WINDOW_TYPE_EVENT:
|
||||
return stbSplSplitEvent(pCxt, pInfo);
|
||||
case WINDOW_TYPE_COUNT:
|
||||
return stbSplSplitCount(pCxt, pInfo);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -237,6 +237,15 @@ static int32_t adjustEventDataRequirement(SWindowLogicNode* pWindow, EDataOrderL
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t adjustCountDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
|
||||
if (requirement <= pWindow->node.resultDataOrder) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pWindow->node.resultDataOrder = requirement;
|
||||
pWindow->node.requireDataOrder = requirement;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t adjustWindowDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
|
||||
switch (pWindow->winType) {
|
||||
case WINDOW_TYPE_INTERVAL:
|
||||
|
@ -247,6 +256,8 @@ static int32_t adjustWindowDataRequirement(SWindowLogicNode* pWindow, EDataOrder
|
|||
return adjustStateDataRequirement(pWindow, requirement);
|
||||
case WINDOW_TYPE_EVENT:
|
||||
return adjustEventDataRequirement(pWindow, requirement);
|
||||
case WINDOW_TYPE_COUNT:
|
||||
return adjustCountDataRequirement(pWindow, requirement);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((*pJob->chkKillFp)(pJob->chkKillParam)) {
|
||||
if (pJob->chkKillFp && (*pJob->chkKillFp)(pJob->chkKillParam)) {
|
||||
schUpdateJobErrCode(pJob, TSDB_CODE_TSC_QUERY_KILLED);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -263,6 +263,7 @@ void schCloseJobRef(void) {
|
|||
|
||||
uint64_t schGenTaskId(void) { return atomic_add_fetch_64(&schMgmt.taskId, 1); }
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
uint64_t schGenUUID(void) {
|
||||
static uint64_t hashId = 0;
|
||||
static int32_t requestSerialId = 0;
|
||||
|
@ -284,6 +285,7 @@ uint64_t schGenUUID(void) {
|
|||
uint64_t id = ((hashId & 0x0FFF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF);
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void schFreeRpcCtxVal(const void *arg) {
|
||||
if (NULL == arg) {
|
||||
|
|
|
@ -25,4 +25,9 @@ IF(NOT TD_DARWIN)
|
|||
PUBLIC "${TD_SOURCE_DIR}/include/libs/scheduler/"
|
||||
PRIVATE "${TD_SOURCE_DIR}/source/libs/scheduler/inc"
|
||||
)
|
||||
add_test(
|
||||
NAME schedulerTest
|
||||
COMMAND schedulerTest
|
||||
)
|
||||
|
||||
ENDIF()
|
|
@ -54,20 +54,20 @@
|
|||
|
||||
namespace {
|
||||
|
||||
extern "C" int32_t schHandleResponseMsg(SSchJob *job, SSchTask *task, int32_t msgType, char *msg, int32_t msgSize,
|
||||
int32_t rspCode);
|
||||
extern "C" int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t msgType, int32_t rspCode);
|
||||
extern "C" int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t execId, SDataBuf *pMsg, int32_t rspCode);
|
||||
extern "C" int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t rspCode);
|
||||
|
||||
int64_t insertJobRefId = 0;
|
||||
int64_t queryJobRefId = 0;
|
||||
|
||||
bool schtJobDone = false;
|
||||
uint64_t schtMergeTemplateId = 0x4;
|
||||
uint64_t schtFetchTaskId = 0;
|
||||
uint64_t schtQueryId = 1;
|
||||
|
||||
bool schtTestStop = false;
|
||||
bool schtTestDeadLoop = false;
|
||||
int32_t schtTestMTRunSec = 10;
|
||||
int32_t schtTestMTRunSec = 1;
|
||||
int32_t schtTestPrintNum = 1000;
|
||||
int32_t schtStartFetch = 0;
|
||||
|
||||
|
@ -85,10 +85,69 @@ void schtInitLogFile() {
|
|||
}
|
||||
|
||||
void schtQueryCb(SExecResult *pResult, void *param, int32_t code) {
|
||||
assert(TSDB_CODE_SUCCESS == code);
|
||||
*(int32_t *)param = 1;
|
||||
}
|
||||
|
||||
int32_t schtBuildQueryRspMsg(uint32_t *msize, void** rspMsg) {
|
||||
SQueryTableRsp rsp = {0};
|
||||
rsp.code = 0;
|
||||
rsp.affectedRows = 0;
|
||||
rsp.tbVerInfo = NULL;
|
||||
|
||||
int32_t msgSize = tSerializeSQueryTableRsp(NULL, 0, &rsp);
|
||||
if (msgSize < 0) {
|
||||
qError("tSerializeSQueryTableRsp failed");
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
void *pRsp = taosMemoryCalloc(msgSize, 1);
|
||||
if (NULL == pRsp) {
|
||||
qError("rpcMallocCont %d failed", msgSize);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (tSerializeSQueryTableRsp(pRsp, msgSize, &rsp) < 0) {
|
||||
qError("tSerializeSQueryTableRsp %d failed", msgSize);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*rspMsg = pRsp;
|
||||
*msize = msgSize;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schtBuildFetchRspMsg(uint32_t *msize, void** rspMsg) {
|
||||
SRetrieveTableRsp* rsp = (SRetrieveTableRsp*)taosMemoryCalloc(sizeof(SRetrieveTableRsp), 1);
|
||||
rsp->completed = 1;
|
||||
rsp->numOfRows = 10;
|
||||
rsp->compLen = 0;
|
||||
|
||||
*rspMsg = rsp;
|
||||
*msize = sizeof(SRetrieveTableRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t schtBuildSubmitRspMsg(uint32_t *msize, void** rspMsg) {
|
||||
SSubmitRsp2 submitRsp = {0};
|
||||
int32_t msgSize = 0, ret = 0;
|
||||
SEncoder ec = {0};
|
||||
|
||||
tEncodeSize(tEncodeSSubmitRsp2, &submitRsp, msgSize, ret);
|
||||
void* msg = taosMemoryCalloc(1, msgSize);
|
||||
tEncoderInit(&ec, (uint8_t*)msg, msgSize);
|
||||
tEncodeSSubmitRsp2(&ec, &submitRsp);
|
||||
tEncoderClear(&ec);
|
||||
|
||||
*rspMsg = msg;
|
||||
*msize = msgSize;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void schtBuildQueryDag(SQueryPlan *dag) {
|
||||
uint64_t qId = schtQueryId;
|
||||
|
||||
|
@ -98,8 +157,8 @@ void schtBuildQueryDag(SQueryPlan *dag) {
|
|||
SNodeListNode *scan = (SNodeListNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
SNodeListNode *merge = (SNodeListNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
|
||||
SSubplan *scanPlan = (SSubplan *)taosMemoryCalloc(1, sizeof(SSubplan));
|
||||
SSubplan *mergePlan = (SSubplan *)taosMemoryCalloc(1, sizeof(SSubplan));
|
||||
SSubplan *scanPlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
SSubplan *mergePlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
|
||||
scanPlan->id.queryId = qId;
|
||||
scanPlan->id.groupId = 0x0000000000000002;
|
||||
|
@ -113,7 +172,7 @@ void schtBuildQueryDag(SQueryPlan *dag) {
|
|||
scanPlan->pChildren = NULL;
|
||||
scanPlan->level = 1;
|
||||
scanPlan->pParents = nodesMakeList();
|
||||
scanPlan->pNode = (SPhysiNode *)taosMemoryCalloc(1, sizeof(SPhysiNode));
|
||||
scanPlan->pNode = (SPhysiNode *)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN);
|
||||
scanPlan->msgType = TDMT_SCH_QUERY;
|
||||
|
||||
mergePlan->id.queryId = qId;
|
||||
|
@ -125,7 +184,7 @@ void schtBuildQueryDag(SQueryPlan *dag) {
|
|||
|
||||
mergePlan->pChildren = nodesMakeList();
|
||||
mergePlan->pParents = NULL;
|
||||
mergePlan->pNode = (SPhysiNode *)taosMemoryCalloc(1, sizeof(SPhysiNode));
|
||||
mergePlan->pNode = (SPhysiNode *)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_MERGE);
|
||||
mergePlan->msgType = TDMT_SCH_QUERY;
|
||||
|
||||
merge->pNodeList = nodesMakeList();
|
||||
|
@ -151,8 +210,7 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
|
|||
SNodeListNode *scan = (SNodeListNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
SNodeListNode *merge = (SNodeListNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
|
||||
SSubplan *scanPlan = (SSubplan *)taosMemoryCalloc(scanPlanNum, sizeof(SSubplan));
|
||||
SSubplan *mergePlan = (SSubplan *)taosMemoryCalloc(1, sizeof(SSubplan));
|
||||
SSubplan *mergePlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
|
||||
merge->pNodeList = nodesMakeList();
|
||||
scan->pNodeList = nodesMakeList();
|
||||
|
@ -160,29 +218,30 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
|
|||
mergePlan->pChildren = nodesMakeList();
|
||||
|
||||
for (int32_t i = 0; i < scanPlanNum; ++i) {
|
||||
scanPlan[i].id.queryId = qId;
|
||||
scanPlan[i].id.groupId = 0x0000000000000002;
|
||||
scanPlan[i].id.subplanId = 0x0000000000000003 + i;
|
||||
scanPlan[i].subplanType = SUBPLAN_TYPE_SCAN;
|
||||
SSubplan *scanPlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
scanPlan->id.queryId = qId;
|
||||
scanPlan->id.groupId = 0x0000000000000002;
|
||||
scanPlan->id.subplanId = 0x0000000000000003 + i;
|
||||
scanPlan->subplanType = SUBPLAN_TYPE_SCAN;
|
||||
|
||||
scanPlan[i].execNode.nodeId = 1 + i;
|
||||
scanPlan[i].execNode.epSet.inUse = 0;
|
||||
scanPlan[i].execNodeStat.tableNum = taosRand() % 30;
|
||||
addEpIntoEpSet(&scanPlan[i].execNode.epSet, "ep0", 6030);
|
||||
addEpIntoEpSet(&scanPlan[i].execNode.epSet, "ep1", 6030);
|
||||
addEpIntoEpSet(&scanPlan[i].execNode.epSet, "ep2", 6030);
|
||||
scanPlan[i].execNode.epSet.inUse = taosRand() % 3;
|
||||
scanPlan->execNode.nodeId = 1 + i;
|
||||
scanPlan->execNode.epSet.inUse = 0;
|
||||
scanPlan->execNodeStat.tableNum = taosRand() % 30;
|
||||
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep0", 6030);
|
||||
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep1", 6030);
|
||||
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep2", 6030);
|
||||
scanPlan->execNode.epSet.inUse = taosRand() % 3;
|
||||
|
||||
scanPlan[i].pChildren = NULL;
|
||||
scanPlan[i].level = 1;
|
||||
scanPlan[i].pParents = nodesMakeList();
|
||||
scanPlan[i].pNode = (SPhysiNode *)taosMemoryCalloc(1, sizeof(SPhysiNode));
|
||||
scanPlan[i].msgType = TDMT_SCH_QUERY;
|
||||
scanPlan->pChildren = NULL;
|
||||
scanPlan->level = 1;
|
||||
scanPlan->pParents = nodesMakeList();
|
||||
scanPlan->pNode = (SPhysiNode *)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN);
|
||||
scanPlan->msgType = TDMT_SCH_QUERY;
|
||||
|
||||
nodesListAppend(scanPlan[i].pParents, (SNode *)mergePlan);
|
||||
nodesListAppend(mergePlan->pChildren, (SNode *)(scanPlan + i));
|
||||
nodesListAppend(scanPlan->pParents, (SNode *)mergePlan);
|
||||
nodesListAppend(mergePlan->pChildren, (SNode *)scanPlan);
|
||||
|
||||
nodesListAppend(scan->pNodeList, (SNode *)(scanPlan + i));
|
||||
nodesListAppend(scan->pNodeList, (SNode *)scanPlan);
|
||||
}
|
||||
|
||||
mergePlan->id.queryId = qId;
|
||||
|
@ -193,7 +252,7 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
|
|||
mergePlan->execNode.epSet.numOfEps = 0;
|
||||
|
||||
mergePlan->pParents = NULL;
|
||||
mergePlan->pNode = (SPhysiNode *)taosMemoryCalloc(1, sizeof(SPhysiNode));
|
||||
mergePlan->pNode = (SPhysiNode *)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_MERGE);
|
||||
mergePlan->msgType = TDMT_SCH_QUERY;
|
||||
|
||||
nodesListAppend(merge->pNodeList, (SNode *)mergePlan);
|
||||
|
@ -211,45 +270,50 @@ void schtBuildInsertDag(SQueryPlan *dag) {
|
|||
dag->numOfSubplans = 2;
|
||||
dag->pSubplans = nodesMakeList();
|
||||
SNodeListNode *inserta = (SNodeListNode *)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
|
||||
SSubplan *insertPlan = (SSubplan *)taosMemoryCalloc(2, sizeof(SSubplan));
|
||||
|
||||
insertPlan[0].id.queryId = qId;
|
||||
insertPlan[0].id.groupId = 0x0000000000000003;
|
||||
insertPlan[0].id.subplanId = 0x0000000000000004;
|
||||
insertPlan[0].subplanType = SUBPLAN_TYPE_MODIFY;
|
||||
insertPlan[0].level = 0;
|
||||
|
||||
insertPlan[0].execNode.nodeId = 1;
|
||||
insertPlan[0].execNode.epSet.inUse = 0;
|
||||
addEpIntoEpSet(&insertPlan[0].execNode.epSet, "ep0", 6030);
|
||||
|
||||
insertPlan[0].pChildren = NULL;
|
||||
insertPlan[0].pParents = NULL;
|
||||
insertPlan[0].pNode = NULL;
|
||||
insertPlan[0].pDataSink = (SDataSinkNode *)taosMemoryCalloc(1, sizeof(SDataSinkNode));
|
||||
insertPlan[0].msgType = TDMT_VND_SUBMIT;
|
||||
|
||||
insertPlan[1].id.queryId = qId;
|
||||
insertPlan[1].id.groupId = 0x0000000000000003;
|
||||
insertPlan[1].id.subplanId = 0x0000000000000005;
|
||||
insertPlan[1].subplanType = SUBPLAN_TYPE_MODIFY;
|
||||
insertPlan[1].level = 0;
|
||||
|
||||
insertPlan[1].execNode.nodeId = 1;
|
||||
insertPlan[1].execNode.epSet.inUse = 0;
|
||||
addEpIntoEpSet(&insertPlan[1].execNode.epSet, "ep0", 6030);
|
||||
|
||||
insertPlan[1].pChildren = NULL;
|
||||
insertPlan[1].pParents = NULL;
|
||||
insertPlan[1].pNode = NULL;
|
||||
insertPlan[1].pDataSink = (SDataSinkNode *)taosMemoryCalloc(1, sizeof(SDataSinkNode));
|
||||
insertPlan[1].msgType = TDMT_VND_SUBMIT;
|
||||
|
||||
inserta->pNodeList = nodesMakeList();
|
||||
|
||||
SSubplan *insertPlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
|
||||
insertPlan->id.queryId = qId;
|
||||
insertPlan->id.groupId = 0x0000000000000003;
|
||||
insertPlan->id.subplanId = 0x0000000000000004;
|
||||
insertPlan->subplanType = SUBPLAN_TYPE_MODIFY;
|
||||
insertPlan->level = 0;
|
||||
|
||||
insertPlan->execNode.nodeId = 1;
|
||||
insertPlan->execNode.epSet.inUse = 0;
|
||||
addEpIntoEpSet(&insertPlan->execNode.epSet, "ep0", 6030);
|
||||
|
||||
insertPlan->pChildren = NULL;
|
||||
insertPlan->pParents = NULL;
|
||||
insertPlan->pNode = NULL;
|
||||
insertPlan->pDataSink = (SDataSinkNode*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_INSERT);
|
||||
((SDataInserterNode*)insertPlan->pDataSink)->size = 1;
|
||||
((SDataInserterNode*)insertPlan->pDataSink)->pData = taosMemoryCalloc(1, 1);
|
||||
insertPlan->msgType = TDMT_VND_SUBMIT;
|
||||
|
||||
nodesListAppend(inserta->pNodeList, (SNode *)insertPlan);
|
||||
insertPlan += 1;
|
||||
|
||||
insertPlan = (SSubplan*)nodesMakeNode(QUERY_NODE_PHYSICAL_SUBPLAN);
|
||||
|
||||
insertPlan->id.queryId = qId;
|
||||
insertPlan->id.groupId = 0x0000000000000003;
|
||||
insertPlan->id.subplanId = 0x0000000000000005;
|
||||
insertPlan->subplanType = SUBPLAN_TYPE_MODIFY;
|
||||
insertPlan->level = 0;
|
||||
|
||||
insertPlan->execNode.nodeId = 1;
|
||||
insertPlan->execNode.epSet.inUse = 0;
|
||||
addEpIntoEpSet(&insertPlan->execNode.epSet, "ep0", 6030);
|
||||
|
||||
insertPlan->pChildren = NULL;
|
||||
insertPlan->pParents = NULL;
|
||||
insertPlan->pNode = NULL;
|
||||
insertPlan->pDataSink = (SDataSinkNode*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_INSERT);
|
||||
((SDataInserterNode*)insertPlan->pDataSink)->size = 1;
|
||||
((SDataInserterNode*)insertPlan->pDataSink)->pData = taosMemoryCalloc(1, 1);
|
||||
insertPlan->msgType = TDMT_VND_SUBMIT;
|
||||
|
||||
nodesListAppend(inserta->pNodeList, (SNode *)insertPlan);
|
||||
|
||||
nodesListAppend(dag->pSubplans, (SNode *)inserta);
|
||||
|
@ -325,7 +389,7 @@ void schtSetRpcSendRequest() {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t schtAsyncSendMsgToServer(void *pTransporter, SEpSet *epSet, int64_t *pTransporterId, SMsgSendInfo *pInfo) {
|
||||
int32_t schtAsyncSendMsgToServer(void *pTransporter, SEpSet *epSet, int64_t *pTransporterId, SMsgSendInfo *pInfo, bool persistHandle, void* rpcCtx) {
|
||||
if (pInfo) {
|
||||
taosMemoryFreeClear(pInfo->param);
|
||||
taosMemoryFreeClear(pInfo->msgInfo.pData);
|
||||
|
@ -336,17 +400,17 @@ int32_t schtAsyncSendMsgToServer(void *pTransporter, SEpSet *epSet, int64_t *pTr
|
|||
|
||||
void schtSetAsyncSendMsgToServer() {
|
||||
static Stub stub;
|
||||
stub.set(asyncSendMsgToServer, schtAsyncSendMsgToServer);
|
||||
stub.set(asyncSendMsgToServerExt, schtAsyncSendMsgToServer);
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
AddrAny any;
|
||||
std::map<std::string, void *> result;
|
||||
any.get_func_addr("asyncSendMsgToServer", result);
|
||||
any.get_func_addr("asyncSendMsgToServerExt", result);
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
AddrAny any("libtransport.so");
|
||||
std::map<std::string, void *> result;
|
||||
any.get_global_func_addr_dynsym("^asyncSendMsgToServer$", result);
|
||||
any.get_global_func_addr_dynsym("^asyncSendMsgToServerExt$", result);
|
||||
#endif
|
||||
for (const auto &f : result) {
|
||||
stub.set(f.second, schtAsyncSendMsgToServer);
|
||||
|
@ -374,15 +438,21 @@ void *schtSendRsp(void *param) {
|
|||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
|
||||
SSubmitRsp rsp = {0};
|
||||
rsp.affectedRows = 10;
|
||||
schHandleResponseMsg(pJob, task, TDMT_VND_SUBMIT_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildSubmitRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_VND_SUBMIT_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
}
|
||||
|
||||
schReleaseJob(job);
|
||||
|
||||
schtJobDone = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -393,11 +463,13 @@ void *schtCreateFetchRspThread(void *param) {
|
|||
taosSsleep(1);
|
||||
|
||||
int32_t code = 0;
|
||||
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, sizeof(SRetrieveTableRsp));
|
||||
rsp->completed = 1;
|
||||
rsp->numOfRows = 10;
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildFetchRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_MERGE_FETCH_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleResponseMsg(pJob, pJob->fetchTask, TDMT_SCH_FETCH_RSP, (char *)rsp, sizeof(*rsp), 0);
|
||||
code = schHandleResponseMsg(pJob, pJob->fetchTask, pJob->fetchTask->execId, &msg, 0);
|
||||
|
||||
schReleaseJob(job);
|
||||
|
||||
|
@ -414,7 +486,7 @@ void *schtFetchRspThread(void *aa) {
|
|||
continue;
|
||||
}
|
||||
|
||||
taosUsleep(1);
|
||||
taosUsleep(100);
|
||||
|
||||
param = (SSchTaskCallbackParam *)taosMemoryCalloc(1, sizeof(*param));
|
||||
|
||||
|
@ -426,10 +498,11 @@ void *schtFetchRspThread(void *aa) {
|
|||
rsp->completed = 1;
|
||||
rsp->numOfRows = 10;
|
||||
|
||||
dataBuf.msgType = TDMT_SCH_FETCH_RSP;
|
||||
dataBuf.pData = rsp;
|
||||
dataBuf.len = sizeof(*rsp);
|
||||
|
||||
code = schHandleCallback(param, &dataBuf, TDMT_SCH_FETCH_RSP, 0);
|
||||
code = schHandleCallback(param, &dataBuf, 0);
|
||||
|
||||
assert(code == 0 || code);
|
||||
}
|
||||
|
@ -456,7 +529,7 @@ void *schtRunJobThread(void *aa) {
|
|||
char *dbname = "1.db1";
|
||||
char *tablename = "table1";
|
||||
SVgroupInfo vgInfo = {0};
|
||||
SQueryPlan dag;
|
||||
SQueryPlan* dag = (SQueryPlan*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN);
|
||||
|
||||
schtInitLogFile();
|
||||
|
||||
|
@ -470,19 +543,19 @@ void *schtRunJobThread(void *aa) {
|
|||
SSchJob *pJob = NULL;
|
||||
SSchTaskCallbackParam *param = NULL;
|
||||
SHashObj *execTasks = NULL;
|
||||
SDataBuf dataBuf = {0};
|
||||
uint32_t jobFinished = 0;
|
||||
int32_t queryDone = 0;
|
||||
|
||||
while (!schtTestStop) {
|
||||
schtBuildQueryDag(&dag);
|
||||
schtBuildQueryDag(dag);
|
||||
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SEp));
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
|
||||
|
||||
SEp qnodeAddr = {0};
|
||||
strcpy(qnodeAddr.fqdn, "qnode0.ep");
|
||||
qnodeAddr.port = 6031;
|
||||
taosArrayPush(qnodeList, &qnodeAddr);
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.epSet.numOfEps = 1;
|
||||
strcpy(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
|
||||
load.addr.epSet.eps[0].port = 6031;
|
||||
taosArrayPush(qnodeList, &load);
|
||||
|
||||
queryDone = 0;
|
||||
|
||||
|
@ -492,7 +565,7 @@ void *schtRunJobThread(void *aa) {
|
|||
req.syncReq = false;
|
||||
req.pConn = &conn;
|
||||
req.pNodeList = qnodeList;
|
||||
req.pDag = &dag;
|
||||
req.pDag = dag;
|
||||
req.sql = "select * from tb";
|
||||
req.execFp = schtQueryCb;
|
||||
req.cbParam = &queryDone;
|
||||
|
@ -503,7 +576,7 @@ void *schtRunJobThread(void *aa) {
|
|||
pJob = schAcquireJob(queryJobRefId);
|
||||
if (NULL == pJob) {
|
||||
taosArrayDestroy(qnodeList);
|
||||
schtFreeQueryDag(&dag);
|
||||
schtFreeQueryDag(dag);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -526,11 +599,14 @@ void *schtRunJobThread(void *aa) {
|
|||
SSchTask *task = (SSchTask *)pIter;
|
||||
|
||||
param->taskId = task->taskId;
|
||||
SQueryTableRsp rsp = {0};
|
||||
dataBuf.pData = &rsp;
|
||||
dataBuf.len = sizeof(rsp);
|
||||
|
||||
code = schHandleCallback(param, &dataBuf, TDMT_SCH_QUERY_RSP, 0);
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleCallback(param, &msg, 0);
|
||||
assert(code == 0 || code);
|
||||
|
||||
pIter = taosHashIterate(execTasks, pIter);
|
||||
|
@ -545,11 +621,13 @@ void *schtRunJobThread(void *aa) {
|
|||
SSchTask *task = (SSchTask *)pIter;
|
||||
|
||||
param->taskId = task->taskId - 1;
|
||||
SQueryTableRsp rsp = {0};
|
||||
dataBuf.pData = &rsp;
|
||||
dataBuf.len = sizeof(rsp);
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleCallback(param, &dataBuf, TDMT_SCH_QUERY_RSP, 0);
|
||||
code = schHandleCallback(param, &msg, 0);
|
||||
assert(code == 0 || code);
|
||||
|
||||
pIter = taosHashIterate(execTasks, pIter);
|
||||
|
@ -575,7 +653,6 @@ void *schtRunJobThread(void *aa) {
|
|||
if (0 == code) {
|
||||
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)data;
|
||||
assert(pRsp->completed == 1);
|
||||
assert(pRsp->numOfRows == 10);
|
||||
}
|
||||
|
||||
data = NULL;
|
||||
|
@ -587,7 +664,7 @@ void *schtRunJobThread(void *aa) {
|
|||
taosHashCleanup(execTasks);
|
||||
taosArrayDestroy(qnodeList);
|
||||
|
||||
schtFreeQueryDag(&dag);
|
||||
schtFreeQueryDag(dag);
|
||||
|
||||
if (++jobFinished % schtTestPrintNum == 0) {
|
||||
printf("jobFinished:%d\n", jobFinished);
|
||||
|
@ -609,6 +686,7 @@ void *schtFreeJobThread(void *aa) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(queryTest, normalCase) {
|
||||
|
@ -618,21 +696,20 @@ TEST(queryTest, normalCase) {
|
|||
char *tablename = "table1";
|
||||
SVgroupInfo vgInfo = {0};
|
||||
int64_t job = 0;
|
||||
SQueryPlan dag;
|
||||
SQueryPlan* dag = (SQueryPlan*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN);
|
||||
|
||||
memset(&dag, 0, sizeof(dag));
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
|
||||
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SEp));
|
||||
|
||||
SEp qnodeAddr = {0};
|
||||
strcpy(qnodeAddr.fqdn, "qnode0.ep");
|
||||
qnodeAddr.port = 6031;
|
||||
taosArrayPush(qnodeList, &qnodeAddr);
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.epSet.numOfEps = 1;
|
||||
strcpy(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
|
||||
load.addr.epSet.eps[0].port = 6031;
|
||||
taosArrayPush(qnodeList, &load);
|
||||
|
||||
int32_t code = schedulerInit();
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
schtBuildQueryDag(&dag);
|
||||
schtBuildQueryDag(dag);
|
||||
|
||||
schtSetPlanToString();
|
||||
schtSetExecNode();
|
||||
|
@ -645,7 +722,7 @@ TEST(queryTest, normalCase) {
|
|||
SSchedulerReq req = {0};
|
||||
req.pConn = &conn;
|
||||
req.pNodeList = qnodeList;
|
||||
req.pDag = &dag;
|
||||
req.pDag = dag;
|
||||
req.sql = "select * from tb";
|
||||
req.execFp = schtQueryCb;
|
||||
req.cbParam = &queryDone;
|
||||
|
@ -659,8 +736,13 @@ TEST(queryTest, normalCase) {
|
|||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
|
||||
SQueryTableRsp rsp = {0};
|
||||
code = schHandleResponseMsg(pJob, task, TDMT_SCH_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
ASSERT_EQ(code, 0);
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
|
@ -669,11 +751,18 @@ TEST(queryTest, normalCase) {
|
|||
pIter = taosHashIterate(pJob->execTasks, NULL);
|
||||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
if (JOB_TASK_STATUS_EXEC == task->status) {
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
SQueryTableRsp rsp = {0};
|
||||
code = schHandleResponseMsg(pJob, task, TDMT_SCH_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
code = schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
ASSERT_EQ(code, 0);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
}
|
||||
|
||||
|
@ -703,18 +792,12 @@ TEST(queryTest, normalCase) {
|
|||
ASSERT_EQ(pRsp->numOfRows, 10);
|
||||
taosMemoryFreeClear(data);
|
||||
|
||||
data = NULL;
|
||||
code = schedulerFetchRows(job, &req);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_TRUE(data == NULL);
|
||||
|
||||
schReleaseJob(job);
|
||||
|
||||
schedulerDestroy();
|
||||
|
||||
schedulerFreeJob(&job, 0);
|
||||
|
||||
schtFreeQueryDag(&dag);
|
||||
|
||||
schedulerDestroy();
|
||||
}
|
||||
|
||||
TEST(queryTest, readyFirstCase) {
|
||||
|
@ -724,21 +807,20 @@ TEST(queryTest, readyFirstCase) {
|
|||
char *tablename = "table1";
|
||||
SVgroupInfo vgInfo = {0};
|
||||
int64_t job = 0;
|
||||
SQueryPlan dag;
|
||||
SQueryPlan* dag = (SQueryPlan*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN);
|
||||
|
||||
memset(&dag, 0, sizeof(dag));
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
|
||||
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SEp));
|
||||
|
||||
SEp qnodeAddr = {0};
|
||||
strcpy(qnodeAddr.fqdn, "qnode0.ep");
|
||||
qnodeAddr.port = 6031;
|
||||
taosArrayPush(qnodeList, &qnodeAddr);
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.epSet.numOfEps = 1;
|
||||
strcpy(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
|
||||
load.addr.epSet.eps[0].port = 6031;
|
||||
taosArrayPush(qnodeList, &load);
|
||||
|
||||
int32_t code = schedulerInit();
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
schtBuildQueryDag(&dag);
|
||||
schtBuildQueryDag(dag);
|
||||
|
||||
schtSetPlanToString();
|
||||
schtSetExecNode();
|
||||
|
@ -751,7 +833,7 @@ TEST(queryTest, readyFirstCase) {
|
|||
SSchedulerReq req = {0};
|
||||
req.pConn = &conn;
|
||||
req.pNodeList = qnodeList;
|
||||
req.pDag = &dag;
|
||||
req.pDag = dag;
|
||||
req.sql = "select * from tb";
|
||||
req.execFp = schtQueryCb;
|
||||
req.cbParam = &queryDone;
|
||||
|
@ -764,8 +846,13 @@ TEST(queryTest, readyFirstCase) {
|
|||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
|
||||
SQueryTableRsp rsp = {0};
|
||||
code = schHandleResponseMsg(pJob, task, TDMT_SCH_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
ASSERT_EQ(code, 0);
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
|
@ -775,10 +862,18 @@ TEST(queryTest, readyFirstCase) {
|
|||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
|
||||
SQueryTableRsp rsp = {0};
|
||||
code = schHandleResponseMsg(pJob, task, TDMT_SCH_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
if (JOB_TASK_STATUS_EXEC == task->status) {
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
code = schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
ASSERT_EQ(code, 0);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
}
|
||||
|
||||
|
@ -807,18 +902,11 @@ TEST(queryTest, readyFirstCase) {
|
|||
ASSERT_EQ(pRsp->numOfRows, 10);
|
||||
taosMemoryFreeClear(data);
|
||||
|
||||
data = NULL;
|
||||
code = schedulerFetchRows(job, &req);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_TRUE(data == NULL);
|
||||
|
||||
schReleaseJob(job);
|
||||
|
||||
schedulerFreeJob(&job, 0);
|
||||
|
||||
schtFreeQueryDag(&dag);
|
||||
|
||||
schedulerDestroy();
|
||||
|
||||
schedulerFreeJob(&job, 0);
|
||||
}
|
||||
|
||||
TEST(queryTest, flowCtrlCase) {
|
||||
|
@ -828,35 +916,39 @@ TEST(queryTest, flowCtrlCase) {
|
|||
char *tablename = "table1";
|
||||
SVgroupInfo vgInfo = {0};
|
||||
int64_t job = 0;
|
||||
SQueryPlan dag;
|
||||
SQueryPlan* dag = (SQueryPlan*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN);
|
||||
|
||||
schtInitLogFile();
|
||||
|
||||
taosSeedRand(taosGetTimestampSec());
|
||||
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SEp));
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
|
||||
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.epSet.numOfEps = 1;
|
||||
strcpy(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
|
||||
load.addr.epSet.eps[0].port = 6031;
|
||||
taosArrayPush(qnodeList, &load);
|
||||
|
||||
SEp qnodeAddr = {0};
|
||||
strcpy(qnodeAddr.fqdn, "qnode0.ep");
|
||||
qnodeAddr.port = 6031;
|
||||
taosArrayPush(qnodeList, &qnodeAddr);
|
||||
|
||||
int32_t code = schedulerInit();
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
schtBuildQueryFlowCtrlDag(&dag);
|
||||
schtBuildQueryFlowCtrlDag(dag);
|
||||
|
||||
schtSetPlanToString();
|
||||
schtSetExecNode();
|
||||
schtSetAsyncSendMsgToServer();
|
||||
|
||||
initTaskQueue();
|
||||
|
||||
int32_t queryDone = 0;
|
||||
SRequestConnInfo conn = {0};
|
||||
conn.pTrans = mockPointer;
|
||||
SSchedulerReq req = {0};
|
||||
req.pConn = &conn;
|
||||
req.pNodeList = qnodeList;
|
||||
req.pDag = &dag;
|
||||
req.pDag = dag;
|
||||
req.sql = "select * from tb";
|
||||
req.execFp = schtQueryCb;
|
||||
req.cbParam = &queryDone;
|
||||
|
@ -866,41 +958,27 @@ TEST(queryTest, flowCtrlCase) {
|
|||
|
||||
SSchJob *pJob = schAcquireJob(job);
|
||||
|
||||
bool qDone = false;
|
||||
|
||||
while (!qDone) {
|
||||
while (!queryDone) {
|
||||
void *pIter = taosHashIterate(pJob->execTasks, NULL);
|
||||
if (NULL == pIter) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (pIter) {
|
||||
SSchTask *task = *(SSchTask **)pIter;
|
||||
|
||||
taosHashCancelIterate(pJob->execTasks, pIter);
|
||||
if (JOB_TASK_STATUS_EXEC == task->status && 0 != task->lastMsgType) {
|
||||
SDataBuf msg = {0};
|
||||
void* rmsg = NULL;
|
||||
schtBuildQueryRspMsg(&msg.len, &rmsg);
|
||||
msg.msgType = TDMT_SCH_QUERY_RSP;
|
||||
msg.pData = rmsg;
|
||||
|
||||
if (task->lastMsgType == TDMT_SCH_QUERY) {
|
||||
SQueryTableRsp rsp = {0};
|
||||
code = schHandleResponseMsg(pJob, task, TDMT_SCH_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0);
|
||||
code = schHandleResponseMsg(pJob, task, task->execId, &msg, 0);
|
||||
|
||||
ASSERT_EQ(code, 0);
|
||||
} else {
|
||||
qDone = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pIter = NULL;
|
||||
pIter = taosHashIterate(pJob->execTasks, pIter);
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (queryDone) {
|
||||
break;
|
||||
}
|
||||
|
||||
taosUsleep(10000);
|
||||
}
|
||||
|
||||
TdThreadAttr thattr;
|
||||
taosThreadAttrInit(&thattr);
|
||||
|
||||
|
@ -918,18 +996,11 @@ TEST(queryTest, flowCtrlCase) {
|
|||
ASSERT_EQ(pRsp->numOfRows, 10);
|
||||
taosMemoryFreeClear(data);
|
||||
|
||||
data = NULL;
|
||||
code = schedulerFetchRows(job, &req);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_TRUE(data == NULL);
|
||||
|
||||
schReleaseJob(job);
|
||||
|
||||
schedulerFreeJob(&job, 0);
|
||||
|
||||
schtFreeQueryDag(&dag);
|
||||
|
||||
schedulerDestroy();
|
||||
|
||||
schedulerFreeJob(&job, 0);
|
||||
}
|
||||
|
||||
TEST(insertTest, normalCase) {
|
||||
|
@ -938,20 +1009,21 @@ TEST(insertTest, normalCase) {
|
|||
char *dbname = "1.db1";
|
||||
char *tablename = "table1";
|
||||
SVgroupInfo vgInfo = {0};
|
||||
SQueryPlan dag;
|
||||
SQueryPlan* dag = (SQueryPlan*)nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN);
|
||||
uint64_t numOfRows = 0;
|
||||
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SEp));
|
||||
SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
|
||||
|
||||
SEp qnodeAddr = {0};
|
||||
strcpy(qnodeAddr.fqdn, "qnode0.ep");
|
||||
qnodeAddr.port = 6031;
|
||||
taosArrayPush(qnodeList, &qnodeAddr);
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.epSet.numOfEps = 1;
|
||||
strcpy(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
|
||||
load.addr.epSet.eps[0].port = 6031;
|
||||
taosArrayPush(qnodeList, &load);
|
||||
|
||||
int32_t code = schedulerInit();
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
schtBuildInsertDag(&dag);
|
||||
schtBuildInsertDag(dag);
|
||||
|
||||
schtSetPlanToString();
|
||||
schtSetAsyncSendMsgToServer();
|
||||
|
@ -959,24 +1031,32 @@ TEST(insertTest, normalCase) {
|
|||
TdThreadAttr thattr;
|
||||
taosThreadAttrInit(&thattr);
|
||||
|
||||
schtJobDone = false;
|
||||
|
||||
TdThread thread1;
|
||||
taosThreadCreate(&(thread1), &thattr, schtSendRsp, &insertJobRefId);
|
||||
|
||||
SExecResult res = {0};
|
||||
|
||||
int32_t queryDone = 0;
|
||||
SRequestConnInfo conn = {0};
|
||||
conn.pTrans = mockPointer;
|
||||
SSchedulerReq req = {0};
|
||||
req.pConn = &conn;
|
||||
req.pNodeList = qnodeList;
|
||||
req.pDag = &dag;
|
||||
req.pDag = dag;
|
||||
req.sql = "insert into tb values(now,1)";
|
||||
req.execFp = schtQueryCb;
|
||||
req.cbParam = NULL;
|
||||
req.cbParam = &queryDone;
|
||||
|
||||
code = schedulerExecJob(&req, &insertJobRefId);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.numOfRows, 20);
|
||||
|
||||
while (true) {
|
||||
if (schtJobDone) {
|
||||
break;
|
||||
}
|
||||
|
||||
taosUsleep(10000);
|
||||
}
|
||||
|
||||
schedulerFreeJob(&insertJobRefId, 0);
|
||||
|
||||
|
@ -989,7 +1069,7 @@ TEST(multiThread, forceFree) {
|
|||
|
||||
TdThread thread1, thread2, thread3;
|
||||
taosThreadCreate(&(thread1), &thattr, schtRunJobThread, NULL);
|
||||
taosThreadCreate(&(thread2), &thattr, schtFreeJobThread, NULL);
|
||||
// taosThreadCreate(&(thread2), &thattr, schtFreeJobThread, NULL);
|
||||
taosThreadCreate(&(thread3), &thattr, schtFetchRspThread, NULL);
|
||||
|
||||
while (true) {
|
||||
|
@ -1002,7 +1082,17 @@ TEST(multiThread, forceFree) {
|
|||
}
|
||||
|
||||
schtTestStop = true;
|
||||
taosSsleep(3);
|
||||
//taosSsleep(3);
|
||||
}
|
||||
|
||||
TEST(otherTest, otherCase) {
|
||||
// excpet test
|
||||
schReleaseJob(0);
|
||||
schFreeRpcCtx(NULL);
|
||||
|
||||
ASSERT_EQ(schDumpEpSet(NULL), (char*)NULL);
|
||||
ASSERT_EQ(strcmp(schGetOpStr(SCH_OP_NULL), "NULL"), 0);
|
||||
ASSERT_EQ(strcmp(schGetOpStr((SCH_OP_TYPE)100), "UNKNOWN"), 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
|
@ -179,7 +179,8 @@ int32_t streamStateSessionDel_rocksdb(SStreamState* pState, const SSessionKey* k
|
|||
SStreamStateCur* streamStateSessionSeekKeyCurrentPrev_rocksdb(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekKeyCurrentNext_rocksdb(SStreamState* pState, SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekKeyNext_rocksdb(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekToLast_rocksdb(SStreamState* pState);
|
||||
SStreamStateCur* streamStateSessionSeekKeyPrev_rocksdb(SStreamState* pState, const SSessionKey* key);
|
||||
SStreamStateCur* streamStateSessionSeekToLast_rocksdb(SStreamState* pState, int64_t groupId);
|
||||
int32_t streamStateSessionCurPrev_rocksdb(SStreamStateCur* pCur);
|
||||
|
||||
int32_t streamStateSessionGetKVByCur_rocksdb(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||
|
|
|
@ -109,8 +109,6 @@ void destroyStreamDataBlock(SStreamDataBlock* pBlock);
|
|||
int32_t streamRetrieveReqToData(const SStreamRetrieveReq* pReq, SStreamDataBlock* pData);
|
||||
int32_t streamBroadcastToUpTasks(SStreamTask* pTask, const SSDataBlock* pBlock);
|
||||
|
||||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
||||
|
||||
int32_t streamSaveTaskCheckpointInfo(SStreamTask* p, int64_t checkpointId);
|
||||
int32_t streamSendCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
|
||||
|
||||
|
|
|
@ -2883,13 +2883,13 @@ int32_t streamStateSessionDel_rocksdb(SStreamState* pState, const SSessionKey* k
|
|||
return code;
|
||||
}
|
||||
|
||||
SStreamStateCur* streamStateSessionSeekToLast_rocksdb(SStreamState* pState) {
|
||||
SStreamStateCur* streamStateSessionSeekToLast_rocksdb(SStreamState* pState, int64_t groupId) {
|
||||
stDebug("streamStateSessionSeekToLast_rocksdb");
|
||||
|
||||
int32_t code = 0;
|
||||
|
||||
SSessionKey maxSessionKey = {.groupId = UINT64_MAX, .win = {.skey = INT64_MAX, .ekey = INT64_MAX}};
|
||||
SStateSessionKey maxKey = {.key = maxSessionKey, .opNum = INT64_MAX};
|
||||
SSessionKey maxSessionKey = {.groupId = groupId, .win = {.skey = INT64_MAX, .ekey = INT64_MAX}};
|
||||
SStateSessionKey maxKey = {.key = maxSessionKey, .opNum = pState->number};
|
||||
|
||||
STREAM_STATE_PUT_ROCKSDB(pState, "sess", &maxKey, "", 0);
|
||||
if (code != 0) {
|
||||
|
@ -3048,6 +3048,46 @@ SStreamStateCur* streamStateSessionSeekKeyNext_rocksdb(SStreamState* pState, con
|
|||
return pCur;
|
||||
}
|
||||
|
||||
SStreamStateCur* streamStateSessionSeekKeyPrev_rocksdb(SStreamState* pState, const SSessionKey* key) {
|
||||
stDebug("streamStateSessionSeekKeyPrev_rocksdb");
|
||||
STaskDbWrapper* wrapper = pState->pTdbState->pOwner->pBackend;
|
||||
SStreamStateCur* pCur = createStreamStateCursor();
|
||||
if (pCur == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pCur->db = wrapper->db;
|
||||
pCur->iter = streamStateIterCreate(pState, "sess", (rocksdb_snapshot_t**)&pCur->snapshot,
|
||||
(rocksdb_readoptions_t**)&pCur->readOpt);
|
||||
pCur->number = pState->number;
|
||||
|
||||
SStateSessionKey sKey = {.key = *key, .opNum = pState->number};
|
||||
|
||||
char buf[128] = {0};
|
||||
int len = stateSessionKeyEncode(&sKey, buf);
|
||||
if (!streamStateIterSeekAndValid(pCur->iter, buf, len)) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
while (rocksdb_iter_valid(pCur->iter) && iterValueIsStale(pCur->iter)) rocksdb_iter_prev(pCur->iter);
|
||||
if (!rocksdb_iter_valid(pCur->iter)) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t klen;
|
||||
const char* iKey = rocksdb_iter_key(pCur->iter, &klen);
|
||||
SStateSessionKey curKey = {0};
|
||||
stateSessionKeyDecode(&curKey, (char*)iKey);
|
||||
if (stateSessionKeyCmpr(&sKey, sizeof(sKey), &curKey, sizeof(curKey)) > 0) return pCur;
|
||||
|
||||
rocksdb_iter_prev(pCur->iter);
|
||||
if (!rocksdb_iter_valid(pCur->iter)) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
return pCur;
|
||||
}
|
||||
|
||||
int32_t streamStateSessionGetKVByCur_rocksdb(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen) {
|
||||
stDebug("streamStateSessionGetKVByCur_rocksdb");
|
||||
if (!pCur) {
|
||||
|
|
|
@ -68,18 +68,6 @@ int32_t tEncodeStreamCheckpointSourceRsp(SEncoder* pEncoder, const SStreamCheckp
|
|||
return pEncoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeStreamCheckpointSourceRsp(SDecoder* pDecoder, SStreamCheckpointSourceRsp* pRsp) {
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pRsp->streamId) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pRsp->checkpointId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->taskId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->nodeId) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pRsp->expireTime) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pRsp->success) < 0) return -1;
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeStreamCheckpointReadyMsg(SEncoder* pEncoder, const SStreamCheckpointReadyMsg* pReq) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1;
|
||||
|
@ -512,7 +500,7 @@ int32_t streamTaskBuildCheckpoint(SStreamTask* pTask) {
|
|||
SStreamTaskId hTaskId = {.streamId = pTask->hTaskInfo.id.streamId, .taskId = pTask->hTaskInfo.id.taskId};
|
||||
|
||||
stDebug("s-task:%s fill-history finish checkpoint done, drop related fill-history task:0x%x", id, hTaskId.taskId);
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pTask->pMeta->vgId, &hTaskId);
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pTask->pMeta->vgId, &hTaskId, 1);
|
||||
} else {
|
||||
stWarn("s-task:%s related fill-history task:0x%x is erased", id, (int32_t)pTask->hTaskInfo.id.taskId);
|
||||
}
|
||||
|
|
|
@ -162,6 +162,8 @@ int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tDeleteStreamRetrieveReq(SStreamRetrieveReq* pReq) { taosMemoryFree(pReq->pRetrieve); }
|
||||
|
||||
void sendRetrieveRsp(SStreamRetrieveReq *pReq, SRpcMsg* pRsp){
|
||||
void* buf = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamRetrieveRsp));
|
||||
((SMsgHead*)buf)->vgId = htonl(pReq->srcNodeId);
|
||||
|
@ -569,6 +571,7 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S
|
|||
char ctbName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
if (pDataBlock->info.parTbName[0]) {
|
||||
if(pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER &&
|
||||
pTask->subtableWithoutMd5 != 1 &&
|
||||
!isAutoTableName(pDataBlock->info.parTbName) &&
|
||||
!alreadyAddGroupId(pDataBlock->info.parTbName) &&
|
||||
groupId != 0){
|
||||
|
|
|
@ -328,7 +328,7 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) {
|
|||
id, (int32_t) pTask->streamTaskId.taskId);
|
||||
|
||||
// 1. free it and remove fill-history task from disk meta-store
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id);
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id, 0);
|
||||
|
||||
// 2. save to disk
|
||||
streamMetaWLock(pMeta);
|
||||
|
|
|
@ -725,9 +725,6 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t
|
|||
|
||||
// it is an fill-history task, remove the related stream task's id that points to it
|
||||
atomic_sub_fetch_32(&pMeta->numOfStreamTasks, 1);
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
streamTaskClearHTaskAttr(pTask, false);
|
||||
}
|
||||
|
||||
taosHashRemove(pMeta->pTasksMap, &id, sizeof(id));
|
||||
doRemoveIdFromList(pMeta, (int32_t)taosArrayGetSize(pMeta->pTaskList), &pTask->id);
|
||||
|
|
|
@ -28,6 +28,12 @@ int sessionStateKeyCompare(const SSessionKey* pWin1, const void* pDatas, int pos
|
|||
return sessionWinKeyCmpr(pWin1, pWin2);
|
||||
}
|
||||
|
||||
int sessionStateRangeKeyCompare(const SSessionKey* pWin1, const void* pDatas, int pos) {
|
||||
SRowBuffPos* pPos2 = taosArrayGetP(pDatas, pos);
|
||||
SSessionKey* pWin2 = (SSessionKey*)pPos2->pKey;
|
||||
return sessionRangeKeyCmpr(pWin1, pWin2);
|
||||
}
|
||||
|
||||
int32_t binarySearch(void* keyList, int num, const void* key, __session_compare_fn_t cmpFn) {
|
||||
int firstPos = 0, lastPos = num - 1, midPos = -1;
|
||||
int numOfRows = 0;
|
||||
|
@ -69,6 +75,12 @@ bool inSessionWindow(SSessionKey* pKey, TSKEY ts, int64_t gap) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SStreamStateCur* createSessionStateCursor(SStreamFileState* pFileState) {
|
||||
SStreamStateCur* pCur = createStreamStateCursor();
|
||||
pCur->pStreamFileState = pFileState;
|
||||
return pCur;
|
||||
}
|
||||
|
||||
static SRowBuffPos* addNewSessionWindow(SStreamFileState* pFileState, SArray* pWinInfos, const SSessionKey* pKey) {
|
||||
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
|
||||
ASSERT(pNewPos->pRowBuff);
|
||||
|
@ -91,7 +103,12 @@ SRowBuffPos* createSessionWinBuff(SStreamFileState* pFileState, SSessionKey* pKe
|
|||
memcpy(pNewPos->pKey, pKey, sizeof(SSessionKey));
|
||||
pNewPos->needFree = true;
|
||||
pNewPos->beFlushed = true;
|
||||
if(p) {
|
||||
memcpy(pNewPos->pRowBuff, p, *pVLen);
|
||||
} else {
|
||||
int32_t len = getRowStateRowSize(pFileState);
|
||||
memset(pNewPos->pRowBuff, 0, len);
|
||||
}
|
||||
taosMemoryFree(p);
|
||||
return pNewPos;
|
||||
}
|
||||
|
@ -364,9 +381,8 @@ static SStreamStateCur* seekKeyCurrentPrev_buff(SStreamFileState* pFileState, co
|
|||
}
|
||||
|
||||
if (index >= 0) {
|
||||
pCur = createStreamStateCursor();
|
||||
pCur = createSessionStateCursor(pFileState);
|
||||
pCur->buffIndex = index;
|
||||
pCur->pStreamFileState = pFileState;
|
||||
if (pIndex) {
|
||||
*pIndex = index;
|
||||
}
|
||||
|
@ -405,7 +421,7 @@ static void checkAndTransformCursor(SStreamFileState* pFileState, const uint64_t
|
|||
if (taosArrayGetSize(pWinStates) > 0 &&
|
||||
(code == TSDB_CODE_FAILED || sessionStateKeyCompare(&key, pWinStates, 0) >= 0)) {
|
||||
if (!(*ppCur)) {
|
||||
(*ppCur) = createStreamStateCursor();
|
||||
(*ppCur) = createSessionStateCursor(pFileState);
|
||||
}
|
||||
transformCursor(pFileState, *ppCur);
|
||||
} else if (*ppCur) {
|
||||
|
@ -419,7 +435,7 @@ SStreamStateCur* sessionWinStateSeekKeyCurrentNext(SStreamFileState* pFileState,
|
|||
int32_t index = -1;
|
||||
SStreamStateCur* pCur = seekKeyCurrentPrev_buff(pFileState, pWinKey, &pWinStates, &index);
|
||||
if (pCur) {
|
||||
if (sessionStateKeyCompare(pWinKey, pWinStates, index) > 0) {
|
||||
if (sessionStateRangeKeyCompare(pWinKey, pWinStates, index) > 0) {
|
||||
sessionWinStateMoveToNext(pCur);
|
||||
}
|
||||
return pCur;
|
||||
|
@ -446,6 +462,66 @@ SStreamStateCur* sessionWinStateSeekKeyNext(SStreamFileState* pFileState, const
|
|||
return pCur;
|
||||
}
|
||||
|
||||
SStreamStateCur* countWinStateSeekKeyPrev(SStreamFileState* pFileState, const SSessionKey* pWinKey, COUNT_TYPE count) {
|
||||
SArray* pWinStates = NULL;
|
||||
int32_t index = -1;
|
||||
SStreamStateCur* pBuffCur = seekKeyCurrentPrev_buff(pFileState, pWinKey, &pWinStates, &index);
|
||||
int32_t resSize = getRowStateRowSize(pFileState);
|
||||
COUNT_TYPE winCount = 0;
|
||||
if (pBuffCur) {
|
||||
while (index >= 0) {
|
||||
SRowBuffPos* pPos = taosArrayGetP(pWinStates, index);
|
||||
winCount = *((COUNT_TYPE*) ((char*)pPos->pRowBuff + (resSize - sizeof(COUNT_TYPE))));
|
||||
if (sessionStateRangeKeyCompare(pWinKey, pWinStates, index) == 0 || winCount < count) {
|
||||
index--;
|
||||
} else if (index >= 0) {
|
||||
pBuffCur->buffIndex = index + 1;
|
||||
return pBuffCur;
|
||||
}
|
||||
}
|
||||
pBuffCur->buffIndex = 0;
|
||||
} else if (taosArrayGetSize(pWinStates) > 0) {
|
||||
pBuffCur = createSessionStateCursor(pFileState);
|
||||
pBuffCur->buffIndex = 0;
|
||||
}
|
||||
|
||||
void* pFileStore = getStateFileStore(pFileState);
|
||||
SStreamStateCur* pCur = streamStateSessionSeekKeyPrev_rocksdb(pFileStore, pWinKey);
|
||||
if (pCur) {
|
||||
SSessionKey key = {0};
|
||||
void* pVal = NULL;
|
||||
int len = 0;
|
||||
int32_t code = streamStateSessionGetKVByCur_rocksdb(pCur, &key, &pVal, &len);
|
||||
if (code == TSDB_CODE_FAILED) {
|
||||
streamStateFreeCur(pCur);
|
||||
return pBuffCur;
|
||||
}
|
||||
winCount = *((COUNT_TYPE*) ((char*)pVal + (resSize - sizeof(COUNT_TYPE))));
|
||||
if (sessionRangeKeyCmpr(pWinKey, &key) != 0 && winCount == count) {
|
||||
streamStateFreeCur(pCur);
|
||||
return pBuffCur;
|
||||
}
|
||||
streamStateCurPrev(pFileStore, pCur);
|
||||
while (1) {
|
||||
code = streamStateSessionGetKVByCur_rocksdb(pCur, &key, &pVal, &len);
|
||||
if (code == TSDB_CODE_FAILED) {
|
||||
streamStateCurNext(pFileStore, pCur);
|
||||
streamStateFreeCur(pBuffCur);
|
||||
return pCur;
|
||||
}
|
||||
winCount = *((COUNT_TYPE*) ((char*)pVal + (resSize - sizeof(COUNT_TYPE))));
|
||||
if (sessionRangeKeyCmpr(pWinKey, &key) == 0 || winCount < count) {
|
||||
streamStateCurPrev(pFileStore, pCur);
|
||||
} else {
|
||||
streamStateCurNext(pFileStore, pCur);
|
||||
streamStateFreeCur(pBuffCur);
|
||||
return pCur;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pBuffCur;
|
||||
}
|
||||
|
||||
int32_t sessionWinStateGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen) {
|
||||
if (!pCur) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -503,7 +579,7 @@ int32_t sessionWinStateMoveToNext(SStreamStateCur* pCur) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessionKey* key, SSessionKey* curKey) {
|
||||
int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessionKey* key, SSessionKey* curKey, range_cmpr_fn cmpFn) {
|
||||
SStreamStateCur* pCur = sessionWinStateSeekKeyCurrentPrev(pFileState, key);
|
||||
SSessionKey tmpKey = *key;
|
||||
int32_t code = sessionWinStateGetKVByCur(pCur, &tmpKey, NULL, NULL);
|
||||
|
@ -520,7 +596,7 @@ int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessio
|
|||
goto _end;
|
||||
}
|
||||
|
||||
if (sessionRangeKeyCmpr(key, &tmpKey) == 0) {
|
||||
if (cmpFn(key, &tmpKey) == 0) {
|
||||
*curKey = tmpKey;
|
||||
goto _end;
|
||||
} else if (!hasCurrentPrev) {
|
||||
|
@ -530,7 +606,7 @@ int32_t sessionWinStateGetKeyByRange(SStreamFileState* pFileState, const SSessio
|
|||
|
||||
sessionWinStateMoveToNext(pCur);
|
||||
code = sessionWinStateGetKVByCur(pCur, &tmpKey, NULL, NULL);
|
||||
if (code == TSDB_CODE_SUCCESS && sessionRangeKeyCmpr(key, &tmpKey) == 0) {
|
||||
if (code == TSDB_CODE_SUCCESS && cmpFn(key, &tmpKey) == 0) {
|
||||
*curKey = tmpKey;
|
||||
} else {
|
||||
code = TSDB_CODE_FAILED;
|
||||
|
@ -636,3 +712,143 @@ int32_t getStateWinResultBuff(SStreamFileState* pFileState, SSessionKey* key, ch
|
|||
_end:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t getCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, COUNT_TYPE winCount, void** pVal, int32_t* pVLen) {
|
||||
SSessionKey* pWinKey = pKey;
|
||||
const TSKEY gap = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSHashObj* pSessionBuff = getRowStateBuff(pFileState);
|
||||
SArray* pWinStates = NULL;
|
||||
void** ppBuff = tSimpleHashGet(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t));
|
||||
if (ppBuff) {
|
||||
pWinStates = (SArray*)(*ppBuff);
|
||||
} else {
|
||||
pWinStates = taosArrayInit(16, POINTER_BYTES);
|
||||
tSimpleHashPut(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t), &pWinStates, POINTER_BYTES);
|
||||
}
|
||||
|
||||
TSKEY startTs = pWinKey->win.skey;
|
||||
TSKEY endTs = pWinKey->win.ekey;
|
||||
|
||||
int32_t size = taosArrayGetSize(pWinStates);
|
||||
if (size == 0) {
|
||||
void* pFileStore = getStateFileStore(pFileState);
|
||||
void* pRockVal = NULL;
|
||||
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileStore, pKey->groupId);
|
||||
code = streamStateSessionGetKVByCur_rocksdb(pCur, pWinKey, &pRockVal, pVLen);
|
||||
if (code == TSDB_CODE_SUCCESS || isFlushedState(pFileState, endTs, 0)) {
|
||||
qDebug("===stream===0 get state win:%" PRId64 ",%" PRId64 " from disc, res %d", pWinKey->win.skey, pWinKey->win.ekey, code);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
int32_t valSize = *pVLen;
|
||||
COUNT_TYPE* pWinStateCout = (COUNT_TYPE*)( (char*)(pRockVal) + (valSize - sizeof(COUNT_TYPE)) );
|
||||
if (inSessionWindow(pWinKey, startTs, gap) || (*pWinStateCout) < winCount) {
|
||||
(*pVal) = createSessionWinBuff(pFileState, pWinKey, pRockVal, pVLen);
|
||||
streamStateFreeCur(pCur);
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
pWinKey->win.skey = startTs;
|
||||
pWinKey->win.ekey = endTs;
|
||||
(*pVal) = createSessionWinBuff(pFileState, pWinKey, NULL, NULL);
|
||||
taosMemoryFree(pRockVal);
|
||||
streamStateFreeCur(pCur);
|
||||
} else {
|
||||
(*pVal) = addNewSessionWindow(pFileState, pWinStates, pWinKey);
|
||||
code = TSDB_CODE_FAILED;
|
||||
}
|
||||
goto _end;
|
||||
}
|
||||
|
||||
// find the first position which is smaller than the pWinKey
|
||||
int32_t index = binarySearch(pWinStates, size, pWinKey, sessionStateKeyCompare);
|
||||
SRowBuffPos* pPos = NULL;
|
||||
int32_t valSize = *pVLen;
|
||||
|
||||
if (index >= 0) {
|
||||
pPos = taosArrayGetP(pWinStates, index);
|
||||
COUNT_TYPE* pWinStateCout = (COUNT_TYPE*)( (char*)(pPos->pRowBuff) + (valSize - sizeof(COUNT_TYPE)) );
|
||||
if (inSessionWindow(pPos->pKey, startTs, gap) || (index == size - 1 && (*pWinStateCout) < winCount) ) {
|
||||
(*pVal) = pPos;
|
||||
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
|
||||
pPos->beUsed = true;
|
||||
*pWinKey = *pDestWinKey;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
if (!isDeteled(pFileState, endTs)) {
|
||||
void* p = NULL;
|
||||
void* pFileStore = getStateFileStore(pFileState);
|
||||
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileStore, pKey->groupId);
|
||||
int32_t code_file = streamStateSessionGetKVByCur_rocksdb(pCur, pWinKey, &p, pVLen);
|
||||
if (code_file == TSDB_CODE_SUCCESS) {
|
||||
(*pVal) = createSessionWinBuff(pFileState, pWinKey, p, pVLen);
|
||||
code = code_file;
|
||||
qDebug("===stream===1 get state win:%" PRId64 ",%" PRId64 " from disc, res %d", pWinKey->win.skey, pWinKey->win.ekey, code_file);
|
||||
streamStateFreeCur(pCur);
|
||||
goto _end;
|
||||
}
|
||||
taosMemoryFree(p);
|
||||
streamStateFreeCur(pCur);
|
||||
}
|
||||
}
|
||||
|
||||
if (index + 1 < size) {
|
||||
pPos = taosArrayGetP(pWinStates, index + 1);
|
||||
(*pVal) = pPos;
|
||||
SSessionKey* pDestWinKey = (SSessionKey*)pPos->pKey;
|
||||
pPos->beUsed = true;
|
||||
*pWinKey = *pDestWinKey;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
(*pVal) = addNewSessionWindow(pFileState, pWinStates, pWinKey);
|
||||
code = TSDB_CODE_FAILED;
|
||||
|
||||
_end:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t createCountWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey, void** pVal, int32_t* pVLen) {
|
||||
SSessionKey* pWinKey = pKey;
|
||||
const TSKEY gap = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSHashObj* pSessionBuff = getRowStateBuff(pFileState);
|
||||
SArray* pWinStates = NULL;
|
||||
void** ppBuff = tSimpleHashGet(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t));
|
||||
if (ppBuff) {
|
||||
pWinStates = (SArray*)(*ppBuff);
|
||||
} else {
|
||||
pWinStates = taosArrayInit(16, POINTER_BYTES);
|
||||
tSimpleHashPut(pSessionBuff, &pWinKey->groupId, sizeof(uint64_t), &pWinStates, POINTER_BYTES);
|
||||
}
|
||||
|
||||
TSKEY startTs = pWinKey->win.skey;
|
||||
TSKEY endTs = pWinKey->win.ekey;
|
||||
|
||||
int32_t size = taosArrayGetSize(pWinStates);
|
||||
if (size == 0) {
|
||||
void* pFileStore = getStateFileStore(pFileState);
|
||||
void* p = NULL;
|
||||
|
||||
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileStore, pKey->groupId);
|
||||
int32_t code_file = streamStateSessionGetKVByCur_rocksdb(pCur, pWinKey, &p, pVLen);
|
||||
if (code_file == TSDB_CODE_SUCCESS || isFlushedState(pFileState, endTs, 0)) {
|
||||
(*pVal) = createSessionWinBuff(pFileState, pWinKey, p, pVLen);
|
||||
code = code_file;
|
||||
qDebug("===stream===0 get state win:%" PRId64 ",%" PRId64 " from disc, res %d", pWinKey->win.skey, pWinKey->win.ekey, code_file);
|
||||
} else {
|
||||
(*pVal) = addNewSessionWindow(pFileState, pWinStates, pWinKey);
|
||||
code = TSDB_CODE_FAILED;
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
streamStateFreeCur(pCur);
|
||||
goto _end;
|
||||
} else {
|
||||
(*pVal) = addNewSessionWindow(pFileState, pWinStates, pWinKey);
|
||||
}
|
||||
|
||||
_end:
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -391,6 +391,16 @@ void doProcessDownstreamReadyRsp(SStreamTask* pTask) {
|
|||
int64_t startTs = pTask->execInfo.start;
|
||||
streamMetaAddTaskLaunchResult(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, initTs, startTs, true);
|
||||
|
||||
if (pTask->status.taskStatus == TASK_STATUS__HALT) {
|
||||
ASSERT(HAS_RELATED_FILLHISTORY_TASK(pTask) && (pTask->info.fillHistory == 0));
|
||||
|
||||
// halt it self for count window stream task until the related
|
||||
// fill history task completd.
|
||||
stDebug("s-task:%s level:%d initial status is %s from mnode, set it to be halt", pTask->id.idStr,
|
||||
pTask->info.taskLevel, streamTaskGetStatusStr(pTask->status.taskStatus));
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_HALT);
|
||||
}
|
||||
|
||||
// start the related fill-history task, when current task is ready
|
||||
// not invoke in success callback due to the deadlock.
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
|
@ -539,11 +549,6 @@ int32_t streamSetParamForScanHistory(SStreamTask* pTask) {
|
|||
return qSetStreamOperatorOptionForScanHistory(pTask->exec.pExecutor);
|
||||
}
|
||||
|
||||
int32_t streamRestoreParam(SStreamTask* pTask) {
|
||||
stDebug("s-task:%s restore operator param after scan-history", pTask->id.idStr);
|
||||
return qRestoreStreamOperatorOption(pTask->exec.pExecutor);
|
||||
}
|
||||
|
||||
// source
|
||||
int32_t streamSetParamForStreamScannerStep1(SStreamTask* pTask, SVersionRange* pVerRange, STimeWindow* pWindow) {
|
||||
return qStreamSourceScanParamForHistoryScanStep1(pTask->exec.pExecutor, pVerRange, pWindow);
|
||||
|
@ -804,7 +809,7 @@ int32_t streamLaunchFillHistoryTask(SStreamTask* pTask) {
|
|||
|
||||
// check stream task status in the first place.
|
||||
SStreamTaskState* pStatus = streamTaskGetStatus(pTask);
|
||||
if (pStatus->state != TASK_STATUS__READY) {
|
||||
if (pStatus->state != TASK_STATUS__READY && pStatus->state != TASK_STATUS__HALT) {
|
||||
stDebug("s-task:%s not launch related fill-history task:0x%" PRIx64 "-0x%x, status:%s", idStr, hStreamId, hTaskId,
|
||||
pStatus->name);
|
||||
|
||||
|
|
|
@ -42,6 +42,14 @@ int sessionRangeKeyCmpr(const SSessionKey* pWin1, const SSessionKey* pWin2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int countRangeKeyEqual(const SSessionKey* pWin1, const SSessionKey* pWin2) {
|
||||
if (pWin1->groupId == pWin2->groupId && pWin1->win.skey <= pWin2->win.skey && pWin2->win.skey <= pWin1->win.ekey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sessionWinKeyCmpr(const SSessionKey* pWin1, const SSessionKey* pWin2) {
|
||||
if (pWin1->groupId > pWin2->groupId) {
|
||||
return 1;
|
||||
|
@ -752,6 +760,12 @@ int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int32_t streamStateSessionReset(SStreamState* pState, void* pVal) {
|
||||
int32_t len = getRowStateRowSize(pState->pFileState);
|
||||
memset(pVal, 0, len);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SStreamStateCur* streamStateSessionSeekKeyCurrentPrev(SStreamState* pState, const SSessionKey* key) {
|
||||
#ifdef USE_ROCKSDB
|
||||
return sessionWinStateSeekKeyCurrentPrev(pState->pFileState, key);
|
||||
|
@ -846,6 +860,13 @@ SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSess
|
|||
#endif
|
||||
}
|
||||
|
||||
SStreamStateCur* streamStateCountSeekKeyPrev(SStreamState* pState, const SSessionKey* key, COUNT_TYPE count) {
|
||||
#ifdef USE_ROCKSDB
|
||||
return countWinStateSeekKeyPrev(pState->pFileState, key, count);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen) {
|
||||
#ifdef USE_ROCKSDB
|
||||
return sessionWinStateGetKVByCur(pCur, pKey, pVal, pVLen);
|
||||
|
@ -896,7 +917,7 @@ int32_t streamStateSessionClear(SStreamState* pState) {
|
|||
|
||||
int32_t streamStateSessionGetKeyByRange(SStreamState* pState, const SSessionKey* key, SSessionKey* curKey) {
|
||||
#ifdef USE_ROCKSDB
|
||||
return sessionWinStateGetKeyByRange(pState->pFileState, key, curKey);
|
||||
return sessionWinStateGetKeyByRange(pState->pFileState, key, curKey, sessionRangeKeyCmpr);
|
||||
#else
|
||||
SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
|
||||
if (pCur == NULL) {
|
||||
|
@ -946,6 +967,13 @@ int32_t streamStateSessionGetKeyByRange(SStreamState* pState, const SSessionKey*
|
|||
#endif
|
||||
}
|
||||
|
||||
int32_t streamStateCountGetKeyByRange(SStreamState* pState, const SSessionKey* key, SSessionKey* curKey) {
|
||||
#ifdef USE_ROCKSDB
|
||||
return sessionWinStateGetKeyByRange(pState->pFileState, key, curKey, countRangeKeyEqual);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal,
|
||||
int32_t* pVLen) {
|
||||
#ifdef USE_ROCKSDB
|
||||
|
@ -1135,90 +1163,11 @@ SStreamStateCur* createStreamStateCursor() {
|
|||
return pCur;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char* streamStateSessionDump(SStreamState* pState) {
|
||||
SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
|
||||
if (pCur == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pCur->number = pState->number;
|
||||
if (tdbTbcOpen(pState->pTdbState->pSessionStateDb, &pCur->pCur, NULL) < 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
tdbTbcMoveToFirst(pCur->pCur);
|
||||
|
||||
SSessionKey key = {0};
|
||||
void* buf = NULL;
|
||||
int32_t bufSize = 0;
|
||||
int32_t code = streamStateSessionGetKVByCur(pCur, &key, &buf, &bufSize);
|
||||
if (code != 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
// count window
|
||||
int32_t streamStateCountWinAddIfNotExist(SStreamState* pState, SSessionKey* pKey, COUNT_TYPE winCount, void** ppVal, int32_t* pVLen) {
|
||||
return getCountWinResultBuff(pState->pFileState, pKey, winCount, ppVal, pVLen);
|
||||
}
|
||||
|
||||
int32_t size = 2048;
|
||||
char* dumpBuf = taosMemoryCalloc(size, 1);
|
||||
int64_t len = 0;
|
||||
len += snprintf(dumpBuf + len, size - len, "||s:%15" PRId64 ",", key.win.skey);
|
||||
len += snprintf(dumpBuf + len, size - len, "e:%15" PRId64 ",", key.win.ekey);
|
||||
len += snprintf(dumpBuf + len, size - len, "g:%15" PRId64 "||", key.groupId);
|
||||
while (1) {
|
||||
tdbTbcMoveToNext(pCur->pCur);
|
||||
key = (SSessionKey){0};
|
||||
code = streamStateSessionGetKVByCur(pCur, &key, NULL, 0);
|
||||
if (code != 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return dumpBuf;
|
||||
int32_t streamStateCountWinAdd(SStreamState* pState, SSessionKey* pKey, void** pVal, int32_t* pVLen) {
|
||||
return createCountWinResultBuff(pState->pFileState, pKey, pVal, pVLen);
|
||||
}
|
||||
len += snprintf(dumpBuf + len, size - len, "||s:%15" PRId64 ",", key.win.skey);
|
||||
len += snprintf(dumpBuf + len, size - len, "e:%15" PRId64 ",", key.win.ekey);
|
||||
len += snprintf(dumpBuf + len, size - len, "g:%15" PRId64 "||", key.groupId);
|
||||
}
|
||||
streamStateFreeCur(pCur);
|
||||
return dumpBuf;
|
||||
}
|
||||
|
||||
char* streamStateIntervalDump(SStreamState* pState) {
|
||||
SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur));
|
||||
if (pCur == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pCur->number = pState->number;
|
||||
if (tdbTbcOpen(pState->pTdbState->pStateDb, &pCur->pCur, NULL) < 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
tdbTbcMoveToFirst(pCur->pCur);
|
||||
|
||||
SWinKey key = {0};
|
||||
void* buf = NULL;
|
||||
int32_t bufSize = 0;
|
||||
int32_t code = streamStateGetKVByCur(pCur, &key, (const void **)&buf, &bufSize);
|
||||
if (code != 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t size = 2048;
|
||||
char* dumpBuf = taosMemoryCalloc(size, 1);
|
||||
int64_t len = 0;
|
||||
len += snprintf(dumpBuf + len, size - len, "||s:%15" PRId64 ",", key.ts);
|
||||
// len += snprintf(dumpBuf + len, size - len, "e:%15" PRId64 ",", key.win.ekey);
|
||||
len += snprintf(dumpBuf + len, size - len, "g:%15" PRId64 "||", key.groupId);
|
||||
while (1) {
|
||||
tdbTbcMoveToNext(pCur->pCur);
|
||||
key = (SWinKey){0};
|
||||
code = streamStateGetKVByCur(pCur, &key, NULL, 0);
|
||||
if (code != 0) {
|
||||
streamStateFreeCur(pCur);
|
||||
return dumpBuf;
|
||||
}
|
||||
len += snprintf(dumpBuf + len, size - len, "||s:%15" PRId64 ",", key.ts);
|
||||
// len += snprintf(dumpBuf + len, size - len, "e:%15" PRId64 ",", key.win.ekey);
|
||||
len += snprintf(dumpBuf + len, size - len, "g:%15" PRId64 "||", key.groupId);
|
||||
}
|
||||
streamStateFreeCur(pCur);
|
||||
return dumpBuf;
|
||||
}
|
||||
#endif
|
|
@ -80,7 +80,7 @@ static SStreamChildEpInfo* createStreamTaskEpInfo(const SStreamTask* pTask) {
|
|||
}
|
||||
|
||||
SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset, bool fillHistory, int64_t triggerParam,
|
||||
SArray* pTaskList, bool hasFillhistory) {
|
||||
SArray* pTaskList, bool hasFillhistory, int8_t subtableWithoutMd5) {
|
||||
SStreamTask* pTask = (SStreamTask*)taosMemoryCalloc(1, sizeof(SStreamTask));
|
||||
if (pTask == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -96,6 +96,7 @@ SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset,
|
|||
pTask->info.taskLevel = taskLevel;
|
||||
pTask->info.fillHistory = fillHistory;
|
||||
pTask->info.triggerParam = triggerParam;
|
||||
pTask->subtableWithoutMd5 = subtableWithoutMd5;
|
||||
|
||||
pTask->status.pSM = streamCreateStateMachine(pTask);
|
||||
if (pTask->status.pSM == NULL) {
|
||||
|
@ -108,7 +109,7 @@ SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, SEpSet* pEpset,
|
|||
|
||||
pTask->id.idStr = taosStrdup(buf);
|
||||
pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE;
|
||||
pTask->status.taskStatus = (fillHistory || hasFillhistory) ? TASK_STATUS__SCAN_HISTORY : TASK_STATUS__READY;
|
||||
pTask->status.taskStatus = fillHistory? TASK_STATUS__SCAN_HISTORY : TASK_STATUS__READY;
|
||||
pTask->inputq.status = TASK_INPUT_STATUS__NORMAL;
|
||||
pTask->outputq.status = TASK_OUTPUT_STATUS__NORMAL;
|
||||
|
||||
|
@ -126,7 +127,6 @@ int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo)
|
|||
if (tEncodeI32(pEncoder, pInfo->taskId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pInfo->nodeId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pInfo->childId) < 0) return -1;
|
||||
/*if (tEncodeI64(pEncoder, pInfo->processedVer) < 0) return -1;*/
|
||||
if (tEncodeSEpSet(pEncoder, &pInfo->epSet) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pInfo->stage) < 0) return -1;
|
||||
return 0;
|
||||
|
@ -136,7 +136,6 @@ int32_t tDecodeStreamEpInfo(SDecoder* pDecoder, SStreamChildEpInfo* pInfo) {
|
|||
if (tDecodeI32(pDecoder, &pInfo->taskId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pInfo->nodeId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pInfo->childId) < 0) return -1;
|
||||
/*if (tDecodeI64(pDecoder, &pInfo->processedVer) < 0) return -1;*/
|
||||
if (tDecodeSEpSet(pDecoder, &pInfo->epSet) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pInfo->stage) < 0) return -1;
|
||||
return 0;
|
||||
|
@ -205,6 +204,7 @@ int32_t tEncodeStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) {
|
|||
if (tEncodeCStr(pEncoder, pTask->outputInfo.shuffleDispatcher.stbFullName) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI64(pEncoder, pTask->info.triggerParam) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->subtableWithoutMd5) < 0) return -1;
|
||||
if (tEncodeCStrWithLen(pEncoder, pTask->reserve, sizeof(pTask->reserve) - 1) < 0) return -1;
|
||||
|
||||
tEndEncode(pEncoder);
|
||||
|
@ -287,6 +287,7 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
|
|||
if (tDecodeCStrTo(pDecoder, pTask->outputInfo.shuffleDispatcher.stbFullName) < 0) return -1;
|
||||
}
|
||||
if (tDecodeI64(pDecoder, &pTask->info.triggerParam) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->subtableWithoutMd5) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pTask->reserve) < 0) return -1;
|
||||
|
||||
tEndDecode(pDecoder);
|
||||
|
@ -294,7 +295,6 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
|
|||
}
|
||||
|
||||
int32_t tDecodeStreamTaskChkInfo(SDecoder* pDecoder, SCheckpointInfo* pChkpInfo) {
|
||||
int64_t ver;
|
||||
int64_t skip64;
|
||||
int8_t skip8;
|
||||
int32_t skip32;
|
||||
|
@ -648,7 +648,7 @@ int32_t streamTaskStop(SStreamTask* pTask) {
|
|||
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_STOP);
|
||||
qKillTask(pTask->exec.pExecutor, TSDB_CODE_SUCCESS);
|
||||
while (/*pTask->status.schedStatus != TASK_SCHED_STATUS__INACTIVE */ !streamTaskIsIdle(pTask)) {
|
||||
while (!streamTaskIsIdle(pTask)) {
|
||||
stDebug("s-task:%s level:%d wait for task to be idle and then close, check again in 100ms", id,
|
||||
pTask->info.taskLevel);
|
||||
taosMsleep(100);
|
||||
|
@ -755,7 +755,7 @@ int8_t streamTaskSetSchedStatusInactive(SStreamTask* pTask) {
|
|||
return status;
|
||||
}
|
||||
|
||||
int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, bool metaLock) {
|
||||
int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, int32_t resetRelHalt, bool metaLock) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
STaskId sTaskId = {.streamId = pTask->streamTaskId.streamId, .taskId = pTask->streamTaskId.taskId};
|
||||
if (pTask->info.fillHistory == 0) {
|
||||
|
@ -773,6 +773,12 @@ int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, bool metaLock) {
|
|||
|
||||
taosThreadMutexLock(&(*ppStreamTask)->lock);
|
||||
CLEAR_RELATED_FILLHISTORY_TASK((*ppStreamTask));
|
||||
|
||||
if (resetRelHalt) {
|
||||
(*ppStreamTask)->status.taskStatus = TASK_STATUS__READY;
|
||||
stDebug("s-task:0x%" PRIx64 " set the status to be ready", sTaskId.taskId);
|
||||
}
|
||||
|
||||
streamMetaSaveTask(pMeta, *ppStreamTask);
|
||||
taosThreadMutexUnlock(&(*ppStreamTask)->lock);
|
||||
}
|
||||
|
@ -784,7 +790,7 @@ int32_t streamTaskClearHTaskAttr(SStreamTask* pTask, bool metaLock) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskId* pTaskId) {
|
||||
int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskId* pTaskId, int64_t resetRelHalt) {
|
||||
SVDropStreamTaskReq* pReq = rpcMallocCont(sizeof(SVDropStreamTaskReq));
|
||||
if (pReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -794,6 +800,7 @@ int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskI
|
|||
pReq->head.vgId = vgId;
|
||||
pReq->taskId = pTaskId->taskId;
|
||||
pReq->streamId = pTaskId->streamId;
|
||||
pReq->resetRelHalt = resetRelHalt;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_DROP, .pCont = pReq, .contLen = sizeof(SVDropStreamTaskReq)};
|
||||
int32_t code = tmsgPutToQueue(pMsgCb, WRITE_QUEUE, &msg);
|
||||
|
@ -881,9 +888,7 @@ void streamTaskResume(SStreamTask* pTask) {
|
|||
}
|
||||
}
|
||||
|
||||
bool streamTaskIsSinkTask(const SStreamTask* pTask) {
|
||||
return pTask->info.taskLevel == TASK_LEVEL__SINK;
|
||||
}
|
||||
bool streamTaskIsSinkTask(const SStreamTask* pTask) { return pTask->info.taskLevel == TASK_LEVEL__SINK; }
|
||||
|
||||
int32_t streamTaskSendCheckpointReq(SStreamTask* pTask) {
|
||||
int32_t code;
|
||||
|
|
|
@ -261,6 +261,7 @@ void updateInfoDestroy(SUpdateInfo *pInfo) {
|
|||
|
||||
taosArrayDestroy(pInfo->pTsSBFs);
|
||||
taosHashCleanup(pInfo->pMap);
|
||||
updateInfoDestoryColseWinSBF(pInfo);
|
||||
taosMemoryFree(pInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,15 @@ int32_t deleteRowBuff(SStreamFileState* pFileState, const void* pKey, int32_t ke
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
int32_t resetRowBuff(SStreamFileState* pFileState, const void* pKey, int32_t keyLen) {
|
||||
int32_t code_buff = pFileState->stateBuffRemoveFn(pFileState->rowStateBuff, pKey, keyLen);
|
||||
int32_t code_file = pFileState->stateFileRemoveFn(pFileState, pKey);
|
||||
if (code_buff == TSDB_CODE_SUCCESS || code_file == TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static void recoverSessionRowBuff(SStreamFileState* pFileState, SRowBuffPos* pPos) {
|
||||
int32_t len = 0;
|
||||
void* pBuff = NULL;
|
||||
|
@ -656,7 +665,7 @@ int32_t recoverSesssion(SStreamFileState* pFileState, int64_t ckId) {
|
|||
deleteExpiredCheckPoint(pFileState, mark);
|
||||
}
|
||||
|
||||
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileState->pFileStore);
|
||||
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileState->pFileStore, INT64_MAX);
|
||||
if (pCur == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ add_test(
|
|||
COMMAND streamUpdateTest
|
||||
)
|
||||
|
||||
# add_test(
|
||||
# NAME checkpointTest
|
||||
# COMMAND checkpointTest
|
||||
# )
|
||||
add_test(
|
||||
NAME checkpointTest
|
||||
COMMAND checkpointTest
|
||||
)
|
|
@ -140,11 +140,7 @@ void* rpcMallocCont(int64_t contLen) {
|
|||
return start + sizeof(STransMsgHead);
|
||||
}
|
||||
|
||||
void rpcFreeCont(void* cont) {
|
||||
if (cont == NULL) return;
|
||||
taosMemoryFree((char*)cont - TRANS_MSG_OVERHEAD);
|
||||
tTrace("rpc free cont:%p", (char*)cont - TRANS_MSG_OVERHEAD);
|
||||
}
|
||||
void rpcFreeCont(void* cont) { transFreeMsg(cont); }
|
||||
|
||||
void* rpcReallocCont(void* ptr, int64_t contLen) {
|
||||
if (ptr == NULL) return rpcMallocCont(contLen);
|
||||
|
|
|
@ -218,7 +218,6 @@ static void (*cliAsyncHandle[])(SCliMsg* pMsg, SCliThrd* pThrd) = {cliHandleReq,
|
|||
/// static void (*cliAsyncHandle[])(SCliMsg* pMsg, SCliThrd* pThrd) = {cliHandleReq, cliHandleQuit, cliHandleRelease,
|
||||
/// NULL,cliHandleUpdate};
|
||||
|
||||
static FORCE_INLINE void destroyUserdata(STransMsg* userdata);
|
||||
static FORCE_INLINE void destroyCmsg(void* cmsg);
|
||||
static FORCE_INLINE void destroyCmsgAndAhandle(void* cmsg);
|
||||
static FORCE_INLINE int cliRBChoseIdx(STrans* pTransInst);
|
||||
|
@ -962,6 +961,10 @@ static void cliSendCb(uv_write_t* req, int status) {
|
|||
tTrace("%s conn %p send cost:%dus ", CONN_GET_INST_LABEL(pConn), pConn, (int)cost);
|
||||
}
|
||||
}
|
||||
if (pMsg->msg.contLen == 0 && pMsg->msg.pCont != 0) {
|
||||
rpcFreeCont(pMsg->msg.pCont);
|
||||
pMsg->msg.pCont = 0;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
tDebug("%s conn %p data already was written out", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
|
@ -1950,14 +1953,6 @@ _err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void destroyUserdata(STransMsg* userdata) {
|
||||
if (userdata->pCont == NULL) {
|
||||
return;
|
||||
}
|
||||
transFreeMsg(userdata->pCont);
|
||||
userdata->pCont = NULL;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void destroyCmsg(void* arg) {
|
||||
SCliMsg* pMsg = arg;
|
||||
if (pMsg == NULL) {
|
||||
|
@ -1965,7 +1960,7 @@ static FORCE_INLINE void destroyCmsg(void* arg) {
|
|||
}
|
||||
|
||||
transDestroyConnCtx(pMsg->ctx);
|
||||
destroyUserdata(&pMsg->msg);
|
||||
transFreeMsg(pMsg->msg.pCont);
|
||||
taosMemoryFree(pMsg);
|
||||
}
|
||||
|
||||
|
@ -1984,7 +1979,7 @@ static FORCE_INLINE void destroyCmsgAndAhandle(void* param) {
|
|||
tDebug("destroy Ahandle C");
|
||||
|
||||
transDestroyConnCtx(pMsg->ctx);
|
||||
destroyUserdata(&pMsg->msg);
|
||||
transFreeMsg(pMsg->msg.pCont);
|
||||
taosMemoryFree(pMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ void transFreeMsg(void* msg) {
|
|||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
tTrace("rpc free cont:%p", (char*)msg - TRANS_MSG_OVERHEAD);
|
||||
taosMemoryFree((char*)msg - sizeof(STransMsgHead));
|
||||
}
|
||||
int transSockInfo2Str(struct sockaddr* sockname, char* dst) {
|
||||
|
|
|
@ -632,6 +632,11 @@ int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, in
|
|||
return writeLen;
|
||||
}
|
||||
|
||||
bool lastErrorIsFileNotExist() {
|
||||
DWORD dwError = GetLastError();
|
||||
return dwError == ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
#else
|
||||
int taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
|
||||
int access = O_BINARY;
|
||||
|
@ -1028,6 +1033,8 @@ int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, in
|
|||
#endif
|
||||
}
|
||||
|
||||
bool lastErrorIsFileNotExist() { return errno == ENOENT; }
|
||||
|
||||
#endif // WINDOWS
|
||||
|
||||
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||
|
|
|
@ -350,7 +350,7 @@ void taosResetLog() {
|
|||
static bool taosCheckFileIsOpen(char *logFileName) {
|
||||
TdFilePtr pFile = taosOpenFile(logFileName, TD_FILE_WRITE);
|
||||
if (pFile == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
if (lastErrorIsFileNotExist()) {
|
||||
return false;
|
||||
} else {
|
||||
printf("\nfailed to open log file:%s, reason:%s\n", logFileName, strerror(errno));
|
||||
|
|
|
@ -18,6 +18,9 @@ from frame.autogen import *
|
|||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
updatecfgDict = {
|
||||
'slowLogScope':"query"
|
||||
}
|
||||
|
||||
def init(self, conn, logSql, replicaVar=3):
|
||||
super(TDTestCase, self).init(conn, logSql, replicaVar=3, db="snapshot", checkColName="c1")
|
||||
|
|
|
@ -33,7 +33,8 @@ class TDTestCase(TBase):
|
|||
"lossyColumns" : "float,double",
|
||||
"fPrecision" : "0.000000001",
|
||||
"dPrecision" : "0.00000000000000001",
|
||||
"ifAdtFse" : "1"
|
||||
"ifAdtFse" : "1",
|
||||
'slowLogScope' : "insert"
|
||||
}
|
||||
|
||||
def insertData(self):
|
||||
|
@ -56,7 +57,7 @@ class TDTestCase(TBase):
|
|||
sql = f"select * from {self.db}.{self.stb} where fc!=100"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
sql = f"select count(*) from {self.db}.{self.stb} where dc!=200"
|
||||
sql = f"select * from {self.db}.{self.stb} where dc!=200"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
sql = f"select avg(fc) from {self.db}.{self.stb}"
|
||||
|
|
|
@ -31,6 +31,9 @@ from frame.srvCtl import *
|
|||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
updatecfgDict = {
|
||||
'slowLogScope' : "others"
|
||||
}
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
tdLog.debug(f"start to init {__file__}")
|
||||
|
|
|
@ -31,9 +31,9 @@ class TDTestCase(TBase):
|
|||
'queryMaxConcurrentTables': '2K',
|
||||
'streamMax': '1M',
|
||||
'totalMemoryKB': '1G',
|
||||
#'rpcQueueMemoryAllowed': '1T',
|
||||
#'mndLogRetention': '1P',
|
||||
'streamBufferSize':'2G'
|
||||
'streamMax': '1P',
|
||||
'streamBufferSize':'1T',
|
||||
'slowLogScope':"query"
|
||||
}
|
||||
|
||||
def insertData(self):
|
||||
|
@ -47,8 +47,40 @@ class TDTestCase(TBase):
|
|||
# taosBenchmark run
|
||||
etool.benchMark(command = f"-d {self.db} -t {self.childtable_count} -n {self.insert_rows} -v 2 -y")
|
||||
|
||||
def checkQueryOK(self, rets):
|
||||
if rets[-2][:9] != "Query OK,":
|
||||
tdLog.exit(f"check taos -s return unecpect: {rets}")
|
||||
|
||||
def doTaos(self):
|
||||
tdLog.info(f"check taos command options...")
|
||||
|
||||
# local command
|
||||
options = [
|
||||
"DebugFlag 143",
|
||||
"enableCoreFile 1",
|
||||
"fqdn 127.0.0.1",
|
||||
"firstEp 127.0.0.1",
|
||||
"locale ENG",
|
||||
"metaCacheMaxSize 10000",
|
||||
"minimalTmpDirGB 5",
|
||||
"minimalLogDirGB 1",
|
||||
"secondEp 127.0.0.2",
|
||||
"smlChildTableName smltbname",
|
||||
"smlAutoChildTableNameDelimiter autochild",
|
||||
"smlTagName tagname",
|
||||
"smlTsDefaultName tsdef",
|
||||
"serverPort 6030",
|
||||
"slowLogScope insert",
|
||||
"timezone tz",
|
||||
"tempDir /var/tmp"
|
||||
]
|
||||
# exec
|
||||
for option in options:
|
||||
rets = etool.runBinFile("taos", f"-s \"alter local '{option}'\";")
|
||||
self.checkQueryOK(rets)
|
||||
# error
|
||||
etool.runBinFile("taos", f"-s \"alter local 'nocmd check'\";")
|
||||
|
||||
# help
|
||||
rets = etool.runBinFile("taos", "--help")
|
||||
self.checkListNotEmpty(rets)
|
||||
|
|
|
@ -8,6 +8,9 @@ from frame.caseBase import *
|
|||
from frame import *
|
||||
|
||||
class TDTestCase(TBase):
|
||||
updatecfgDict = {
|
||||
'slowLogScope':"all"
|
||||
}
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
|
|
|
@ -31,7 +31,9 @@ class TDTestCase(TBase):
|
|||
updatecfgDict = {
|
||||
"keepColumnName" : "1",
|
||||
"ttlChangeOnWrite" : "1",
|
||||
"querySmaOptimize": "1"
|
||||
"querySmaOptimize" : "1",
|
||||
"slowLogScope" : "none",
|
||||
"queryBufferSize" : 10240
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -160,6 +160,14 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_AlwaysReturnValue.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_AlwaysReturnValue.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_AlwaysReturnValue.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_AlwaysReturnValue.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_NotReturnValue.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_NotReturnValue.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_NotReturnValue.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/agg_group_NotReturnValue.py -Q 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False
|
||||
|
@ -575,6 +583,7 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts_3405_3398_3423.py -N 3 -n 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4348-td-27939.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/backslash_g.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/test_ts4467.py
|
||||
|
||||
,,n,system-test,python3 ./test.py -f 2-query/queryQnode.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode1mnode.py
|
||||
|
@ -1140,6 +1149,8 @@
|
|||
,,y,script,./test.sh -f tsim/query/bug3398.sim
|
||||
,,y,script,./test.sh -f tsim/query/explain_tsorder.sim
|
||||
,,y,script,./test.sh -f tsim/query/apercentile.sim
|
||||
,,y,script,./test.sh -f tsim/query/query_count0.sim
|
||||
,,y,script,./test.sh -f tsim/query/query_count_sliding0.sim
|
||||
,,y,script,./test.sh -f tsim/qnode/basic1.sim
|
||||
,,y,script,./test.sh -f tsim/snode/basic1.sim
|
||||
,,y,script,./test.sh -f tsim/mnode/basic1.sim
|
||||
|
@ -1184,6 +1195,13 @@
|
|||
,,y,script,./test.sh -f tsim/stream/checkpointInterval0.sim
|
||||
,,y,script,./test.sh -f tsim/stream/checkStreamSTable1.sim
|
||||
,,y,script,./test.sh -f tsim/stream/checkStreamSTable.sim
|
||||
,,y,script,./test.sh -f tsim/stream/count0.sim
|
||||
,,y,script,./test.sh -f tsim/stream/count1.sim
|
||||
,,y,script,./test.sh -f tsim/stream/count2.sim
|
||||
,,y,script,./test.sh -f tsim/stream/count3.sim
|
||||
,,y,script,./test.sh -f tsim/stream/countSliding0.sim
|
||||
,,y,script,./test.sh -f tsim/stream/countSliding1.sim
|
||||
,,y,script,./test.sh -f tsim/stream/countSliding2.sim
|
||||
,,y,script,./test.sh -f tsim/stream/deleteInterval.sim
|
||||
,,y,script,./test.sh -f tsim/stream/deleteSession.sim
|
||||
,,y,script,./test.sh -f tsim/stream/deleteState.sim
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue