Merge remote-tracking branch 'origin/3.0' into feat/TD-27337
This commit is contained in:
commit
fb20dd51de
|
@ -91,13 +91,15 @@ The list of currently supported Hints is as follows:
|
|||
| :-----------: | -------------- | -------------------------- | -----------------------------------|
|
||||
| BATCH_SCAN | None | Batch table scan | JOIN statment for stable |
|
||||
| NO_BATCH_SCAN | None | Sequential table scan | JOIN statment for stable |
|
||||
| SORT_FOR_GROUP| None | Use sort for partition | With normal column in partition by list |
|
||||
| SORT_FOR_GROUP| None | Use sort for partition, conflict with PARTITION_FIRST | With normal column in partition by list |
|
||||
| PARTITION_FIRST| None | Use Partition before aggregate, conflict with SORT_FOR_GROUP | With normal column in partition by list |
|
||||
|
||||
For example:
|
||||
|
||||
```sql
|
||||
SELECT /*+ BATCH_SCAN() */ a.ts FROM stable1 a, stable2 b where a.tag0 = b.tag0 and a.ts = b.ts;
|
||||
SELECT /*+ SORT_FOR_GROUP() */ count(*), c1 FROM stable1 PARTITION BY c1;
|
||||
SELECT /*+ PARTITION_FIRST() */ count(*), c1 FROM stable1 PARTITION BY c1;
|
||||
```
|
||||
|
||||
## Lists
|
||||
|
|
|
@ -91,13 +91,15 @@ Hints 是用户控制单个语句查询优化的一种手段,当 Hint 不适
|
|||
| :-----------: | -------------- | -------------------------- | -----------------------------|
|
||||
| BATCH_SCAN | 无 | 采用批量读表的方式 | 超级表 JOIN 语句 |
|
||||
| NO_BATCH_SCAN | 无 | 采用顺序读表的方式 | 超级表 JOIN 语句 |
|
||||
| SORT_FOR_GROUP| 无 | 采用sort方式进行分组 | partition by 列表有普通列时 |
|
||||
| SORT_FOR_GROUP| 无 | 采用sort方式进行分组, 与PARTITION_FIRST冲突 | partition by 列表有普通列时 |
|
||||
| PARTITION_FIRST| 无 | 在聚合之前使用PARTITION计算分组, 与SORT_FOR_GROUP冲突 | partition by 列表有普通列时 |
|
||||
|
||||
举例:
|
||||
|
||||
```sql
|
||||
SELECT /*+ BATCH_SCAN() */ a.ts FROM stable1 a, stable2 b where a.tag0 = b.tag0 and a.ts = b.ts;
|
||||
SELECT /*+ SORT_FOR_GROUP() */ count(*), c1 FROM stable1 PARTITION BY c1;
|
||||
SELECT /*+ PARTITION_FIRST() */ count(*), c1 FROM stable1 PARTITION BY c1;
|
||||
```
|
||||
|
||||
## 列表
|
||||
|
|
|
@ -270,6 +270,9 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf, c
|
|||
int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pDataBlocks, const STSchema* pTSchema, int64_t uid, int32_t vgId,
|
||||
tb_uid_t suid);
|
||||
|
||||
bool alreadyAddGroupId(char* ctbName);
|
||||
bool isAutoTableName(char* ctbName);
|
||||
void buildCtbNameAddGruopId(char* ctbName, uint64_t groupId);
|
||||
char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId);
|
||||
int32_t buildCtbNameByGroupIdImpl(const char* stbName, uint64_t groupId, char* pBuf);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ extern int64_t tsRpcQueueMemoryAllowed;
|
|||
extern int32_t tsElectInterval;
|
||||
extern int32_t tsHeartbeatInterval;
|
||||
extern int32_t tsHeartbeatTimeout;
|
||||
extern int32_t tsSnapReplMaxWaitN;
|
||||
|
||||
// vnode
|
||||
extern int64_t tsVndCommitMaxIntervalMs;
|
||||
|
|
|
@ -53,9 +53,12 @@ typedef struct {
|
|||
void* mgmt;
|
||||
void* clientRpc;
|
||||
void* serverRpc;
|
||||
void* statusRpc;
|
||||
void* syncRpc;
|
||||
PutToQueueFp putToQueueFp;
|
||||
GetQueueSizeFp qsizeFp;
|
||||
SendReqFp sendReqFp;
|
||||
SendReqFp sendSyncReqFp;
|
||||
SendRspFp sendRspFp;
|
||||
RegisterBrokenLinkArgFp registerBrokenLinkArgFp;
|
||||
ReleaseHandleFp releaseHandleFp;
|
||||
|
@ -67,6 +70,7 @@ void tmsgSetDefault(const SMsgCb* msgcb);
|
|||
int32_t tmsgPutToQueue(const SMsgCb* msgcb, EQueueType qtype, SRpcMsg* pMsg);
|
||||
int32_t tmsgGetQueueSize(const SMsgCb* msgcb, int32_t vgId, EQueueType qtype);
|
||||
int32_t tmsgSendReq(const SEpSet* epSet, SRpcMsg* pMsg);
|
||||
int32_t tmsgSendSyncReq(const SEpSet* epSet, SRpcMsg* pMsg);
|
||||
void tmsgSendRsp(SRpcMsg* pMsg);
|
||||
void tmsgRegisterBrokenLinkArg(SRpcMsg* pMsg);
|
||||
void tmsgReleaseHandle(SRpcHandleInfo* pHandle, int8_t type);
|
||||
|
|
|
@ -75,6 +75,7 @@ static FORCE_INLINE int64_t taosGetTimestampToday(int32_t precision) {
|
|||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
||||
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval);
|
||||
int64_t taosTimeGetIntervalEnd(int64_t ts, const SInterval* pInterval);
|
||||
int32_t taosTimeCountIntervalForFill(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision, int32_t order);
|
||||
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
|
|
|
@ -383,6 +383,7 @@
|
|||
#define TK_BATCH_SCAN 606
|
||||
#define TK_NO_BATCH_SCAN 607
|
||||
#define TK_SORT_FOR_GROUP 608
|
||||
#define TK_PARTITION_FIRST 609
|
||||
|
||||
|
||||
#define TK_NK_NIL 65535
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
// message process
|
||||
int32_t tqStreamTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, bool restart);
|
||||
int32_t tqStreamOneTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, int64_t streamId, int32_t taskId);
|
||||
int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pMsg, bool restored);
|
||||
int32_t tqStreamTaskProcessDispatchReq(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
int32_t tqStreamTaskProcessDispatchRsp(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
|
@ -27,11 +28,15 @@ int32_t tqStreamTaskProcessScanHistoryFinishRsp(SStreamMeta* pMeta, SRpcMsg* pMs
|
|||
int32_t tqStreamTaskProcessCheckReq(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader);
|
||||
int32_t tqStreamTaskProcessCheckpointReadyMsg(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, int64_t sversion, char* msg, int32_t msgLen, bool isLeader, bool restored);
|
||||
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, SMsgCb* cb, int64_t sversion, char* msg, int32_t msgLen,
|
||||
bool isLeader, bool restored);
|
||||
int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen);
|
||||
int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader);
|
||||
int32_t tqStreamTaskResetStatus(SStreamMeta* pMeta);
|
||||
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta);
|
||||
int32_t tqStreamTasksGetTotalNum(SStreamMeta* pMeta);
|
||||
int32_t tqStreamTaskProcessTaskResetReq(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
int32_t tqStreamTaskProcessTaskPauseReq(SStreamMeta* pMeta, char* pMsg);
|
||||
int32_t tqStreamTaskProcessTaskResumeReq(void* handle, int64_t sversion, char* pMsg, bool fromVnode);
|
||||
|
||||
#endif // TDENGINE_TQ_COMMON_H
|
||||
|
|
|
@ -210,6 +210,7 @@ void* qExtractReaderFromStreamScanner(void* scanner);
|
|||
int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner);
|
||||
|
||||
int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo);
|
||||
int32_t qResetStreamOperatorOptionForScanHistory(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);
|
||||
|
|
|
@ -189,7 +189,8 @@ typedef struct TsdReader {
|
|||
|
||||
typedef struct SStoreCacheReader {
|
||||
int32_t (*openReader)(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr);
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray *pFuncTypeList);
|
||||
void *(*closeReader)(void *pReader);
|
||||
int32_t (*retrieveRows)(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUidList);
|
||||
|
|
|
@ -249,6 +249,10 @@ typedef struct SPoint {
|
|||
int32_t taosGetLinearInterpolationVal(SPoint *point, int32_t outputType, SPoint *point1, SPoint *point2,
|
||||
int32_t inputType);
|
||||
|
||||
#define LEASTSQUARES_DOUBLE_ITEM_LENGTH 25
|
||||
#define LEASTSQUARES_BUFF_LENGTH 128
|
||||
#define DOUBLE_PRECISION_DIGITS "16e"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -259,9 +259,13 @@ EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, STimeWindow*
|
|||
int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet);
|
||||
int32_t fmGetUdafExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t fmSetInvertFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmSetNormalFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
bool fmIsInvertible(int32_t funcId);
|
||||
#endif
|
||||
|
||||
char* fmGetFuncName(int32_t funcId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -149,6 +149,8 @@ void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pCon
|
|||
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
|
||||
bool nodesEqualNode(const SNode* a, const SNode* b);
|
||||
bool nodeListNodeEqual(const SNodeList* a, const SNode* b);
|
||||
|
||||
bool nodesMatchNode(const SNode* pSub, const SNode* pNode);
|
||||
|
||||
SNode* nodesCloneNode(const SNode* pNode);
|
||||
|
|
|
@ -120,6 +120,7 @@ typedef struct SScanLogicNode {
|
|||
bool onlyMetaCtbIdx; // for tag scan with no tbname
|
||||
bool filesetDelimited; // returned blocks delimited by fileset
|
||||
bool isCountByTag; // true if selectstmt hasCountFunc & part by tag/tbname
|
||||
SArray* pFuncTypes; // for last, last_row
|
||||
} SScanLogicNode;
|
||||
|
||||
typedef struct SJoinLogicNode {
|
||||
|
@ -159,6 +160,7 @@ typedef struct SProjectLogicNode {
|
|||
SNodeList* pProjections;
|
||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||
bool ignoreGroupId;
|
||||
bool inputIgnoreGroup;
|
||||
} SProjectLogicNode;
|
||||
|
||||
typedef struct SIndefRowsFuncLogicNode {
|
||||
|
@ -405,6 +407,7 @@ typedef struct SLastRowScanPhysiNode {
|
|||
bool groupSort;
|
||||
bool ignoreNull;
|
||||
SNodeList* pTargets;
|
||||
SArray* pFuncTypes;
|
||||
} SLastRowScanPhysiNode;
|
||||
|
||||
typedef SLastRowScanPhysiNode STableCountScanPhysiNode;
|
||||
|
@ -451,6 +454,7 @@ typedef struct SProjectPhysiNode {
|
|||
SNodeList* pProjections;
|
||||
bool mergeDataBlock;
|
||||
bool ignoreGroupId;
|
||||
bool inputIgnoreGroup;
|
||||
} SProjectPhysiNode;
|
||||
|
||||
typedef struct SIndefRowsFuncPhysiNode {
|
||||
|
|
|
@ -90,6 +90,7 @@ typedef struct SColumnNode {
|
|||
|
||||
typedef struct SColumnRefNode {
|
||||
ENodeType type;
|
||||
SDataType resType;
|
||||
char colName[TSDB_COL_NAME_LEN];
|
||||
} SColumnRefNode;
|
||||
|
||||
|
@ -133,6 +134,7 @@ typedef enum EHintOption {
|
|||
HINT_NO_BATCH_SCAN = 1,
|
||||
HINT_BATCH_SCAN,
|
||||
HINT_SORT_FOR_GROUP,
|
||||
HINT_PARTITION_FIRST,
|
||||
} EHintOption;
|
||||
|
||||
typedef struct SHintNode {
|
||||
|
@ -566,6 +568,7 @@ int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, EColle
|
|||
|
||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList* pFuncs);
|
||||
|
||||
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "systable.h"
|
||||
#include "tarray.h"
|
||||
#include "thash.h"
|
||||
#include "tlog.h"
|
||||
#include "tmsg.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "systable.h"
|
||||
|
||||
typedef enum {
|
||||
JOB_TASK_STATUS_NULL = 0,
|
||||
|
@ -90,8 +90,7 @@ typedef struct SExecResult {
|
|||
void* res;
|
||||
} SExecResult;
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct SCTableMeta {
|
||||
uint64_t uid;
|
||||
uint64_t suid;
|
||||
|
@ -100,8 +99,7 @@ typedef struct SCTableMeta {
|
|||
} SCTableMeta;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct STableMeta {
|
||||
// BEGIN: KEEP THIS PART SAME WITH SCTableMeta
|
||||
uint64_t uid;
|
||||
|
@ -137,8 +135,8 @@ typedef struct SDBVgInfo {
|
|||
int8_t hashMethod;
|
||||
int32_t numOfTable; // DB's table num, unit is TSDB_TABLE_NUM_UNIT
|
||||
int64_t stateTs;
|
||||
SHashObj* vgHash; // key:vgId, value:SVgroupInfo
|
||||
SArray* vgArray; // SVgroupInfo
|
||||
SHashObj* vgHash; // key:vgId, value:SVgroupInfo
|
||||
SArray* vgArray; // SVgroupInfo
|
||||
} SDBVgInfo;
|
||||
|
||||
typedef struct SUseDbOutput {
|
||||
|
@ -173,6 +171,7 @@ typedef struct SDataBuf {
|
|||
void* pData;
|
||||
uint32_t len;
|
||||
void* handle;
|
||||
int64_t handleRefId;
|
||||
SEpSet* pEpSet;
|
||||
} SDataBuf;
|
||||
|
||||
|
@ -284,7 +283,7 @@ void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType*
|
|||
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
|
||||
int32_t cloneSVreateTbReq(SVCreateTbReq* pSrc, SVCreateTbReq** pDst);
|
||||
void freeVgInfo(SDBVgInfo* vgInfo);
|
||||
void freeDbCfgInfo(SDbCfgInfo *pInfo);
|
||||
void freeDbCfgInfo(SDbCfgInfo* pInfo);
|
||||
|
||||
extern int32_t (*queryBuildMsg[TDMT_MAX])(void* input, char** msg, int32_t msgSize, int32_t* msgLen,
|
||||
void* (*mallocFp)(int64_t));
|
||||
|
@ -315,7 +314,9 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR)
|
||||
#define SYNC_OTHER_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_MNODE_NOT_FOUND)
|
||||
|
||||
#define NO_RET_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define NO_RET_REDIRECT_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
||||
(_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
|
||||
#define NEED_REDIRECT_ERROR(_code) \
|
||||
(NO_RET_REDIRECT_ERROR(_code) || SYNC_UNKNOWN_LEADER_REDIRECT_ERROR(_code) || \
|
||||
|
|
|
@ -50,18 +50,22 @@ extern "C" {
|
|||
(_t)->hTaskInfo.id.streamId = 0; \
|
||||
} while (0)
|
||||
|
||||
#define STREAM_EXEC_EXTRACT_DATA_IN_WAL_ID (-1)
|
||||
#define STREAM_EXEC_START_ALL_TASKS_ID (-2)
|
||||
#define STREAM_EXEC_RESTART_ALL_TASKS_ID (-3)
|
||||
#define STREAM_EXEC_STOP_ALL_TASKS_ID (-4)
|
||||
#define STREAM_EXEC_T_EXTRACT_WAL_DATA (-1)
|
||||
#define STREAM_EXEC_T_START_ALL_TASKS (-2)
|
||||
#define STREAM_EXEC_T_START_ONE_TASK (-3)
|
||||
#define STREAM_EXEC_T_RESTART_ALL_TASKS (-4)
|
||||
#define STREAM_EXEC_T_STOP_ALL_TASKS (-5)
|
||||
#define STREAM_EXEC_T_RESUME_TASK (-6)
|
||||
#define STREAM_EXEC_T_UPDATE_TASK_EPSET (-7)
|
||||
|
||||
typedef struct SStreamTask SStreamTask;
|
||||
typedef struct SStreamQueue SStreamQueue;
|
||||
typedef struct SStreamTaskSM SStreamTaskSM;
|
||||
|
||||
#define SSTREAM_TASK_VER 2
|
||||
#define SSTREAM_TASK_VER 3
|
||||
#define SSTREAM_TASK_INCOMPATIBLE_VER 1
|
||||
#define SSTREAM_TASK_NEED_CONVERT_VER 2
|
||||
#define SSTREAM_TASK_SUBTABLE_CHANGED_VER 3
|
||||
|
||||
enum {
|
||||
STREAM_STATUS__NORMAL = 0,
|
||||
|
@ -81,14 +85,12 @@ typedef enum ETaskStatus {
|
|||
TASK_STATUS__HALT, // pause, but not be manipulated by user command
|
||||
TASK_STATUS__PAUSE, // pause
|
||||
TASK_STATUS__CK, // stream task is in checkpoint status, no data are allowed to put into inputQ anymore
|
||||
// TASK_STATUS__STREAM_SCAN_HISTORY,
|
||||
} ETaskStatus;
|
||||
|
||||
enum {
|
||||
TASK_SCHED_STATUS__INACTIVE = 1,
|
||||
TASK_SCHED_STATUS__WAITING,
|
||||
TASK_SCHED_STATUS__ACTIVE,
|
||||
TASK_SCHED_STATUS__FAILED,
|
||||
TASK_SCHED_STATUS__DROPPING,
|
||||
};
|
||||
|
||||
|
@ -322,10 +324,11 @@ typedef struct SStreamStatus {
|
|||
int8_t taskStatus;
|
||||
int8_t downstreamReady; // downstream tasks are all ready now, if this flag is set
|
||||
int8_t schedStatus;
|
||||
int8_t keepTaskStatus;
|
||||
bool appendTranstateBlock; // has append the transfer state data block already, todo: remove it
|
||||
int32_t schedIdleTime; // idle time before invoke again
|
||||
int64_t lastExecTs; // last exec time stamp
|
||||
int8_t statusBackup;
|
||||
bool appendTranstateBlock; // has append the transfer state data block already
|
||||
int32_t timerActive; // timer is active
|
||||
int8_t allowedAddInTimer; // allowed to add into timer
|
||||
int32_t inScanHistorySentinel;
|
||||
} SStreamStatus;
|
||||
|
||||
|
@ -366,7 +369,8 @@ typedef struct STaskQueue {
|
|||
|
||||
typedef struct STaskSchedInfo {
|
||||
int8_t status;
|
||||
void* pTimer;
|
||||
tmr_h pDelayTimer;
|
||||
tmr_h pIdleTimer;
|
||||
} STaskSchedInfo;
|
||||
|
||||
typedef struct SSinkRecorder {
|
||||
|
@ -481,6 +485,11 @@ typedef struct STaskUpdateInfo {
|
|||
int32_t transId;
|
||||
} STaskUpdateInfo;
|
||||
|
||||
typedef struct SScanWalInfo {
|
||||
int32_t scanCounter;
|
||||
tmr_h scanTimer;
|
||||
} SScanWalInfo;
|
||||
|
||||
// meta
|
||||
typedef struct SStreamMeta {
|
||||
char* path;
|
||||
|
@ -498,7 +507,7 @@ typedef struct SStreamMeta {
|
|||
bool sendMsgBeforeClosing; // send hb to mnode before close all tasks when switch to follower.
|
||||
STaskStartInfo startInfo;
|
||||
TdThreadRwlock lock;
|
||||
int32_t walScanCounter;
|
||||
SScanWalInfo scanInfo;
|
||||
void* streamBackend;
|
||||
int64_t streamBackendRid;
|
||||
SHashObj* pTaskDbUnique;
|
||||
|
@ -541,6 +550,7 @@ typedef struct {
|
|||
SMsgHead head;
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
int32_t reqType;
|
||||
} SStreamTaskRunReq;
|
||||
|
||||
struct SStreamDispatchReq {
|
||||
|
@ -553,6 +563,7 @@ struct SStreamDispatchReq {
|
|||
int32_t upstreamTaskId;
|
||||
int32_t upstreamChildId;
|
||||
int32_t upstreamNodeId;
|
||||
int32_t upstreamRelTaskId;
|
||||
int32_t blockNum;
|
||||
int64_t totalLen;
|
||||
SArray* dataLen; // SArray<int32_t>
|
||||
|
@ -676,18 +687,18 @@ typedef struct STaskStatusEntry {
|
|||
int32_t statusLastDuration; // to record the last duration of current status
|
||||
int64_t stage;
|
||||
int32_t nodeId;
|
||||
int64_t verStart; // start version in WAL, only valid for source task
|
||||
int64_t verEnd; // end version in WAL, only valid for source task
|
||||
int64_t processedVer; // only valid for source task
|
||||
int64_t activeCheckpointId; // current active checkpoint id
|
||||
int32_t chkpointTransId; // checkpoint trans id
|
||||
bool checkpointFailed; // denote if the checkpoint is failed or not
|
||||
bool inputQChanging; // inputQ is changing or not
|
||||
int64_t verStart; // start version in WAL, only valid for source task
|
||||
int64_t verEnd; // end version in WAL, only valid for source task
|
||||
int64_t processedVer; // only valid for source task
|
||||
int64_t checkpointId; // current active checkpoint id
|
||||
int32_t chkpointTransId; // checkpoint trans id
|
||||
int8_t checkpointFailed; // denote if the checkpoint is failed or not
|
||||
bool inputQChanging; // inputQ is changing or not
|
||||
int64_t inputQUnchangeCounter;
|
||||
double inputQUsed; // in MiB
|
||||
double inputQUsed; // in MiB
|
||||
double inputRate;
|
||||
double sinkQuota; // existed quota size for sink task
|
||||
double sinkDataSize; // sink to dst data size
|
||||
double sinkQuota; // existed quota size for sink task
|
||||
double sinkDataSize; // sink to dst data size
|
||||
} STaskStatusEntry;
|
||||
|
||||
typedef struct SStreamHbMsg {
|
||||
|
@ -728,6 +739,11 @@ typedef struct SStreamTaskNodeUpdateMsg {
|
|||
int32_t tEncodeStreamTaskUpdateMsg(SEncoder* pEncoder, const SStreamTaskNodeUpdateMsg* pMsg);
|
||||
int32_t tDecodeStreamTaskUpdateMsg(SDecoder* pDecoder, SStreamTaskNodeUpdateMsg* pMsg);
|
||||
|
||||
typedef struct SStreamTaskState {
|
||||
ETaskStatus state;
|
||||
char* name;
|
||||
} SStreamTaskState;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
int32_t downstreamTaskId;
|
||||
|
@ -764,17 +780,18 @@ SStreamChildEpInfo* streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t
|
|||
|
||||
void streamTaskInputFail(SStreamTask* pTask);
|
||||
int32_t streamExecTask(SStreamTask* pTask);
|
||||
int32_t streamResumeTask(SStreamTask* pTask);
|
||||
int32_t streamSchedExec(SStreamTask* pTask);
|
||||
bool streamTaskShouldStop(const SStreamTask* pStatus);
|
||||
bool streamTaskShouldPause(const SStreamTask* pStatus);
|
||||
bool streamTaskIsIdle(const SStreamTask* pTask);
|
||||
bool streamTaskReadyToRun(const SStreamTask* pTask, char** pStatus);
|
||||
|
||||
char* createStreamTaskIdStr(int64_t streamId, int32_t taskId);
|
||||
ETaskStatus streamTaskGetStatus(const SStreamTask* pTask, char** pStr);
|
||||
const char* streamTaskGetStatusStr(ETaskStatus status);
|
||||
void streamTaskResetStatus(SStreamTask* pTask);
|
||||
void streamTaskSetStatusReady(SStreamTask* pTask);
|
||||
char* createStreamTaskIdStr(int64_t streamId, int32_t taskId);
|
||||
SStreamTaskState* streamTaskGetStatus(const SStreamTask* pTask);
|
||||
const char* streamTaskGetStatusStr(ETaskStatus status);
|
||||
void streamTaskResetStatus(SStreamTask* pTask);
|
||||
void streamTaskSetStatusReady(SStreamTask* pTask);
|
||||
|
||||
void initRpcMsg(SRpcMsg* pMsg, int32_t msgType, void* pCont, int32_t contLen);
|
||||
|
||||
|
@ -785,7 +802,7 @@ int32_t streamTaskCheckStatus(SStreamTask* pTask, int32_t upstreamTaskId, int32_
|
|||
int64_t* oldStage);
|
||||
int32_t streamTaskUpdateEpsetInfo(SStreamTask* pTask, SArray* pNodeList);
|
||||
void streamTaskResetUpstreamStageInfo(SStreamTask* pTask);
|
||||
bool streamTaskAllUpstreamClosed(SStreamTask* pTask);
|
||||
bool streamTaskIsAllUpstreamClosed(SStreamTask* pTask);
|
||||
bool streamTaskSetSchedStatusWait(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusActive(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusInactive(SStreamTask* pTask);
|
||||
|
@ -810,7 +827,7 @@ int32_t streamQueueGetNumOfItems(const SStreamQueue* pQueue);
|
|||
|
||||
// common
|
||||
int32_t streamRestoreParam(SStreamTask* pTask);
|
||||
void streamTaskPause(SStreamTask* pTask, SStreamMeta* pMeta);
|
||||
void streamTaskPause(SStreamMeta* pMeta, SStreamTask* pTask);
|
||||
void streamTaskResume(SStreamTask* pTask);
|
||||
int32_t streamTaskSetUpstreamInfo(SStreamTask* pTask, const SStreamTask* pUpstreamTask);
|
||||
void streamTaskUpdateUpstreamInfo(SStreamTask* pTask, int32_t nodeId, const SEpSet* pEpSet);
|
||||
|
@ -821,6 +838,7 @@ int32_t streamTaskReloadState(SStreamTask* pTask);
|
|||
void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId);
|
||||
void streamTaskOpenAllUpstreamInput(SStreamTask* pTask);
|
||||
int32_t streamTaskSetDb(SStreamMeta* pMeta, void* pTask, char* key);
|
||||
bool streamTaskIsSinkTask(const SStreamTask* pTask);
|
||||
|
||||
void streamTaskStatusInit(STaskStatusEntry* pEntry, const SStreamTask* pTask);
|
||||
void streamTaskStatusCopy(STaskStatusEntry* pDst, const STaskStatusEntry* pSrc);
|
||||
|
@ -855,8 +873,10 @@ int64_t streamMetaGetLatestCheckpointId(SStreamMeta* pMeta);
|
|||
void streamMetaNotifyClose(SStreamMeta* pMeta);
|
||||
void streamMetaStartHb(SStreamMeta* pMeta);
|
||||
bool streamMetaTaskInTimer(SStreamMeta* pMeta);
|
||||
int32_t streamMetaUpdateTaskDownstreamStatus(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int32_t streamMetaAddTaskLaunchResult(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int64_t endTs, bool ready);
|
||||
int32_t streamMetaResetTaskStatus(SStreamMeta* pMeta);
|
||||
|
||||
void streamMetaRLock(SStreamMeta* pMeta);
|
||||
void streamMetaRUnLock(SStreamMeta* pMeta);
|
||||
void streamMetaWLock(SStreamMeta* pMeta);
|
||||
|
@ -867,6 +887,9 @@ void streamMetaUpdateStageRole(SStreamMeta* pMeta, int64_t stage, bool i
|
|||
int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStopAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStartOneTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
bool streamMetaAllTasksReady(const SStreamMeta* pMeta);
|
||||
tmr_h streamTimerGetInstance();
|
||||
|
||||
// checkpoint
|
||||
int32_t streamProcessCheckpointSourceReq(SStreamTask* pTask, SStreamCheckpointSourceReq* pReq);
|
||||
|
|
|
@ -117,6 +117,8 @@ int32_t taosCompressFile(char *srcFileName, char *destFileName);
|
|||
|
||||
int32_t taosSetFileHandlesLimit();
|
||||
|
||||
int32_t taosLinkFile(char *src, char *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -745,6 +745,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_INVALID_VIEW_QUERY TAOS_DEF_ERROR_CODE(0, 0x266C)
|
||||
#define TSDB_CODE_PAR_COL_QUERY_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x266D)
|
||||
#define TSDB_CODE_PAR_VIEW_CONFLICT_WITH_TABLE TAOS_DEF_ERROR_CODE(0, 0x266E)
|
||||
#define TSDB_CODE_PAR_ORDERBY_AMBIGUOUS TAOS_DEF_ERROR_CODE(0, 0x266F)
|
||||
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
|
||||
|
||||
//planner
|
||||
|
|
|
@ -109,12 +109,12 @@ extern const int32_t TYPE_BYTES[21];
|
|||
#define TSDB_INS_USER_STABLES_DBNAME_COLID 2
|
||||
|
||||
static const int64_t TICK_PER_SECOND[] = {
|
||||
1000LL, // MILLISECOND
|
||||
1000000LL, // MICROSECOND
|
||||
1000000000LL, // NANOSECOND
|
||||
0LL, // HOUR
|
||||
0LL, // MINUTE
|
||||
1LL // SECOND
|
||||
1000LL, // MILLISECOND
|
||||
1000000LL, // MICROSECOND
|
||||
1000000000LL, // NANOSECOND
|
||||
0LL, // HOUR
|
||||
0LL, // MINUTE
|
||||
1LL // SECOND
|
||||
};
|
||||
|
||||
#define TSDB_TICK_PER_SECOND(precision) \
|
||||
|
@ -240,8 +240,8 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_MAX_SQL_SHOW_LEN 1024
|
||||
#define TSDB_MAX_ALLOWED_SQL_LEN (1 * 1024 * 1024u) // sql length should be less than 1mb
|
||||
|
||||
#define TSDB_VIEW_NAME_LEN 193
|
||||
#define TSDB_VIEW_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_VIEW_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
|
||||
#define TSDB_VIEW_NAME_LEN 193
|
||||
#define TSDB_VIEW_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_VIEW_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
|
||||
|
||||
#define TSDB_APP_NAME_LEN TSDB_UNI_LEN
|
||||
#define TSDB_TB_COMMENT_LEN 1025
|
||||
|
@ -261,7 +261,7 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_PASSWORD_LEN 32
|
||||
#define TSDB_USET_PASSWORD_LEN 129
|
||||
#define TSDB_VERSION_LEN 32
|
||||
#define TSDB_LABEL_LEN 12
|
||||
#define TSDB_LABEL_LEN 16
|
||||
#define TSDB_JOB_STATUS_LEN 32
|
||||
|
||||
#define TSDB_CLUSTER_ID_LEN 40
|
||||
|
@ -289,7 +289,7 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_ACTIVE_KEY_LEN 109
|
||||
#define TSDB_CONN_ACTIVE_KEY_LEN 255
|
||||
|
||||
#define TSDB_DEFAULT_PKT_SIZE 65480 // same as RPC_MAX_UDP_SIZE
|
||||
#define TSDB_DEFAULT_PKT_SIZE 65480 // same as RPC_MAX_UDP_SIZE
|
||||
#define TSDB_SNAP_DATA_PAYLOAD_SIZE (1 * 1024 * 1024)
|
||||
|
||||
#define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE
|
||||
|
@ -398,13 +398,13 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_MAX_STT_TRIGGER 1
|
||||
#define TSDB_DEFAULT_SST_TRIGGER 1
|
||||
#endif
|
||||
#define TSDB_STT_TRIGGER_ARRAY_SIZE 16 // maximum of TSDB_MAX_STT_TRIGGER of TD_ENTERPRISE and TD_COMMUNITY
|
||||
#define TSDB_MIN_HASH_PREFIX (2 - TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_MAX_HASH_PREFIX (TSDB_TABLE_NAME_LEN - 2)
|
||||
#define TSDB_DEFAULT_HASH_PREFIX 0
|
||||
#define TSDB_MIN_HASH_SUFFIX (2 - TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_MAX_HASH_SUFFIX (TSDB_TABLE_NAME_LEN - 2)
|
||||
#define TSDB_DEFAULT_HASH_SUFFIX 0
|
||||
#define TSDB_STT_TRIGGER_ARRAY_SIZE 16 // maximum of TSDB_MAX_STT_TRIGGER of TD_ENTERPRISE and TD_COMMUNITY
|
||||
#define TSDB_MIN_HASH_PREFIX (2 - TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_MAX_HASH_PREFIX (TSDB_TABLE_NAME_LEN - 2)
|
||||
#define TSDB_DEFAULT_HASH_PREFIX 0
|
||||
#define TSDB_MIN_HASH_SUFFIX (2 - TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_MAX_HASH_SUFFIX (TSDB_TABLE_NAME_LEN - 2)
|
||||
#define TSDB_DEFAULT_HASH_SUFFIX 0
|
||||
|
||||
#define TSDB_DB_MIN_WAL_RETENTION_PERIOD -1
|
||||
#define TSDB_REP_DEF_DB_WAL_RET_PERIOD 3600
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SQWorkerPool SQWorkerPool;
|
||||
typedef struct SWWorkerPool SWWorkerPool;
|
||||
|
||||
typedef struct SQueueWorker {
|
||||
|
@ -60,14 +59,14 @@ typedef struct SWWorker {
|
|||
SWWorkerPool *pool;
|
||||
} SWWorker;
|
||||
|
||||
typedef struct SWWorkerPool {
|
||||
struct SWWorkerPool {
|
||||
int32_t max; // max number of workers
|
||||
int32_t num;
|
||||
int32_t nextId; // from 0 to max-1, cyclic
|
||||
const char *name;
|
||||
SWWorker *workers;
|
||||
TdThreadMutex mutex;
|
||||
} SWWorkerPool;
|
||||
};
|
||||
|
||||
int32_t tQWorkerInit(SQWorkerPool *pool);
|
||||
void tQWorkerCleanup(SQWorkerPool *pool);
|
||||
|
|
|
@ -285,8 +285,8 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
|
||||
int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
||||
SRetrieveTableRsp* pRsp = NULL;
|
||||
int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode);
|
||||
int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, true);
|
||||
}
|
||||
|
@ -324,7 +324,8 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, atomic_load_8(&pRequest->pTscObj->biMode));
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp,
|
||||
atomic_load_8(&pRequest->pTscObj->biMode));
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, true);
|
||||
}
|
||||
|
@ -492,7 +493,8 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t
|
|||
pResInfo->userFields[i].bytes = pSchema[i].bytes;
|
||||
pResInfo->userFields[i].type = pSchema[i].type;
|
||||
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_VARCHAR || pSchema[i].type == TSDB_DATA_TYPE_VARBINARY || pSchema[i].type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_VARCHAR || pSchema[i].type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
pSchema[i].type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
pResInfo->userFields[i].bytes -= VARSTR_HEADER_SIZE;
|
||||
} else if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) {
|
||||
pResInfo->userFields[i].bytes = (pResInfo->userFields[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
|
@ -1103,9 +1105,9 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat
|
|||
SSqlCallbackWrapper* pWrapper) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
pRequest->type = pQuery->msgType;
|
||||
SArray* pMnodeList = NULL;
|
||||
SQueryPlan* pDag = NULL;
|
||||
int64_t st = taosGetTimestampUs();
|
||||
SArray* pMnodeList = NULL;
|
||||
SQueryPlan* pDag = NULL;
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
if (!pRequest->parseOnly) {
|
||||
pMnodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
|
||||
|
@ -1278,7 +1280,7 @@ int32_t removeMeta(STscObj* pTscObj, SArray* tbList, bool isView) {
|
|||
if (isView) {
|
||||
for (int32_t i = 0; i < tbNum; ++i) {
|
||||
SName* pViewName = taosArrayGet(tbList, i);
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(pViewName, dbFName);
|
||||
catalogRemoveViewMeta(pCatalog, dbFName, 0, pViewName->tname, 0);
|
||||
}
|
||||
|
@ -1510,8 +1512,12 @@ int32_t doProcessMsgFromServer(void* param) {
|
|||
|
||||
updateTargetEpSet(pSendInfo, pTscObj, pMsg, pEpSet);
|
||||
|
||||
SDataBuf buf = {
|
||||
.msgType = pMsg->msgType, .len = pMsg->contLen, .pData = NULL, .handle = pMsg->info.handle, .pEpSet = pEpSet};
|
||||
SDataBuf buf = {.msgType = pMsg->msgType,
|
||||
.len = pMsg->contLen,
|
||||
.pData = NULL,
|
||||
.handle = pMsg->info.handle,
|
||||
.handleRefId = pMsg->info.refId,
|
||||
.pEpSet = pEpSet};
|
||||
|
||||
if (pMsg->contLen > 0) {
|
||||
buf.pData = taosMemoryCalloc(1, pMsg->contLen);
|
||||
|
@ -2538,13 +2544,13 @@ static void fetchCallback(void* pResult, void* param, int32_t code) {
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pRequest->code = code;
|
||||
taosMemoryFreeClear(pResultInfo->pData);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFreeClear(pResultInfo->pData);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2565,12 +2571,12 @@ static void fetchCallback(void* pResult, void* param, int32_t code) {
|
|||
atomic_add_fetch_64((int64_t*)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
|
||||
}
|
||||
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, pResultInfo->numOfRows);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, pResultInfo->numOfRows);
|
||||
}
|
||||
|
||||
void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param) {
|
||||
pRequest->body.fetchFp = fp;
|
||||
((SSyncQueryParam *)pRequest->body.interParam)->userParam = param;
|
||||
((SSyncQueryParam*)pRequest->body.interParam)->userParam = param;
|
||||
|
||||
SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
|
||||
|
||||
|
@ -2611,7 +2617,7 @@ void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param
|
|||
void doRequestCallback(SRequestObj* pRequest, int32_t code) {
|
||||
pRequest->inCallback = true;
|
||||
int64_t this = pRequest->self;
|
||||
pRequest->body.queryFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, code);
|
||||
pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
|
||||
SRequestObj* pReq = acquireRequest(this);
|
||||
if (pReq != NULL) {
|
||||
pReq->inCallback = false;
|
||||
|
@ -2619,11 +2625,11 @@ void doRequestCallback(SRequestObj* pRequest, int32_t code) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t clientParseSql(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effectiveUser, SParseSqlRes* pRes) {
|
||||
int32_t clientParseSql(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effectiveUser,
|
||||
SParseSqlRes* pRes) {
|
||||
#ifndef TD_ENTERPRISE
|
||||
return TSDB_CODE_SUCCESS;
|
||||
#else
|
||||
return clientParseSqlImpl(param, dbName, sql, parseOnly, effectiveUser, pRes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -57,10 +57,6 @@ void taos_cleanup(void) {
|
|||
|
||||
tscStopCrashReport();
|
||||
|
||||
int32_t id = clientReqRefPool;
|
||||
clientReqRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
hbMgrCleanUp();
|
||||
|
||||
catalogDestroy();
|
||||
|
@ -70,6 +66,12 @@ void taos_cleanup(void) {
|
|||
qCleanupKeywordsTable();
|
||||
nodesDestroyAllocatorSet();
|
||||
|
||||
cleanupTaskQueue();
|
||||
|
||||
int32_t id = clientReqRefPool;
|
||||
clientReqRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
id = clientConnRefPool;
|
||||
clientConnRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
@ -77,8 +79,6 @@ void taos_cleanup(void) {
|
|||
rpcCleanup();
|
||||
tscDebug("rpc cleanup");
|
||||
|
||||
cleanupTaskQueue();
|
||||
|
||||
taosConvDestroy();
|
||||
|
||||
tscInfo("all local resources released");
|
||||
|
|
|
@ -1968,7 +1968,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
|||
void* rspObj = NULL;
|
||||
int64_t startTime = taosGetTimestampMs();
|
||||
|
||||
tscInfo("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
|
||||
tscDebug("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
|
||||
timeout);
|
||||
|
||||
// in no topic status, delayed task also need to be processed
|
||||
|
@ -2015,7 +2015,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
|||
int64_t currentTime = taosGetTimestampMs();
|
||||
int64_t elapsedTime = currentTime - startTime;
|
||||
if (elapsedTime > timeout) {
|
||||
tscInfo("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
|
||||
tscDebug("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
|
||||
tmq->consumerId, tmq->epoch, startTime, currentTime);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -939,8 +939,8 @@ TEST(clientCase, agg_query_tables) {
|
|||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
int64_t st = 1685959293000;
|
||||
for (int32_t i = 0; i < 10000000; ++i) {
|
||||
int64_t st = 1685959293299;
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
char s[256] = {0};
|
||||
|
||||
while (1) {
|
||||
|
@ -954,16 +954,16 @@ TEST(clientCase, agg_query_tables) {
|
|||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
sprintf(s, "insert into t2 values(%ld, %d)", st + i, i);
|
||||
pRes = taos_query(pConn, s);
|
||||
int32_t ret = taos_errno(pRes);
|
||||
|
||||
taos_free_result(pRes);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// while (1) {
|
||||
// sprintf(s, "insert into t2 values(%ld, %d)", st + i, i);
|
||||
// pRes = taos_query(pConn, s);
|
||||
// int32_t ret = taos_errno(pRes);
|
||||
//
|
||||
// taos_free_result(pRes);
|
||||
// if (ret == 0) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// pRes = taos_query(pConn, "show table distributed tup");
|
||||
|
|
|
@ -166,7 +166,7 @@ static const SSysDbTableSchema streamTaskSchema[] = {
|
|||
{.name = "node_type", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "node_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||
{.name = "level", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "status", .bytes = 15 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "status", .bytes = 12 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "stage", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
||||
{.name = "in_queue", .bytes = 20, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
// {.name = "out_queue", .bytes = 20, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
|
|
|
@ -2303,6 +2303,30 @@ _end:
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void buildCtbNameAddGruopId(char* ctbName, uint64_t groupId){
|
||||
char tmp[TSDB_TABLE_NAME_LEN] = {0};
|
||||
snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%"PRIu64, groupId);
|
||||
ctbName[TSDB_TABLE_NAME_LEN - strlen(tmp) - 1] = 0; // put groupId to the end
|
||||
strcat(ctbName, tmp);
|
||||
}
|
||||
|
||||
bool isAutoTableName(char* ctbName){
|
||||
return (strlen(ctbName) == 34 && ctbName[0] == 't' && ctbName[1] == '_');
|
||||
}
|
||||
|
||||
bool alreadyAddGroupId(char* ctbName){
|
||||
size_t len = strlen(ctbName);
|
||||
size_t _location = len - 1;
|
||||
while(_location > 0){
|
||||
if(ctbName[_location] < '0' || ctbName[_location] > '9'){
|
||||
break;
|
||||
}
|
||||
_location--;
|
||||
}
|
||||
|
||||
return ctbName[_location] == '_' && len - 1 - _location > 15; //15 means the min length of groupid
|
||||
}
|
||||
|
||||
char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
||||
char* pBuf = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
|
||||
if (!pBuf) {
|
||||
|
|
|
@ -58,7 +58,7 @@ int32_t tsNumOfMnodeQueryThreads = 4;
|
|||
int32_t tsNumOfMnodeFetchThreads = 1;
|
||||
int32_t tsNumOfMnodeReadThreads = 1;
|
||||
int32_t tsNumOfVnodeQueryThreads = 4;
|
||||
float tsRatioOfVnodeStreamThreads = 4.0;
|
||||
float tsRatioOfVnodeStreamThreads = 1.0;
|
||||
int32_t tsNumOfVnodeFetchThreads = 4;
|
||||
int32_t tsNumOfVnodeRsmaThreads = 2;
|
||||
int32_t tsNumOfQnodeQueryThreads = 4;
|
||||
|
@ -72,6 +72,7 @@ int32_t tsPQSortMemThreshold = 16; // M
|
|||
int32_t tsElectInterval = 25 * 1000;
|
||||
int32_t tsHeartbeatInterval = 1000;
|
||||
int32_t tsHeartbeatTimeout = 20 * 1000;
|
||||
int32_t tsSnapReplMaxWaitN = 128;
|
||||
|
||||
// mnode
|
||||
int64_t tsMndSdbWriteDelta = 200;
|
||||
|
@ -95,9 +96,9 @@ int32_t tsMonitorMaxLogs = 100;
|
|||
bool tsMonitorComp = false;
|
||||
|
||||
// audit
|
||||
bool tsEnableAudit = true;
|
||||
bool tsEnableAuditCreateTable = true;
|
||||
int32_t tsAuditInterval = 5000;
|
||||
bool tsEnableAudit = true;
|
||||
bool tsEnableAuditCreateTable = true;
|
||||
int32_t tsAuditInterval = 5000;
|
||||
|
||||
// telem
|
||||
#ifdef TD_ENTERPRISE
|
||||
|
@ -108,7 +109,7 @@ bool tsEnableTelem = true;
|
|||
int32_t tsTelemInterval = 43200;
|
||||
char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.tdengine.com";
|
||||
uint16_t tsTelemPort = 80;
|
||||
char * tsTelemUri = "/report";
|
||||
char *tsTelemUri = "/report";
|
||||
|
||||
#ifdef TD_ENTERPRISE
|
||||
bool tsEnableCrashReport = false;
|
||||
|
@ -252,7 +253,7 @@ int32_t tsCompactPullupInterval = 10;
|
|||
int32_t tsMqRebalanceInterval = 2;
|
||||
int32_t tsStreamCheckpointInterval = 60;
|
||||
float tsSinkDataRate = 2.0;
|
||||
int32_t tsStreamNodeCheckInterval = 15;
|
||||
int32_t tsStreamNodeCheckInterval = 16;
|
||||
int32_t tsTtlUnit = 86400;
|
||||
int32_t tsTtlPushIntervalSec = 10;
|
||||
int32_t tsTrimVDbIntervalSec = 60 * 60; // interval of trimming db in all vgroups
|
||||
|
@ -282,7 +283,7 @@ int32_t tsS3BlockCacheSize = 16; // number of blocks
|
|||
int32_t tsS3PageCacheSize = 4096; // number of pages
|
||||
int32_t tsS3UploadDelaySec = 60 * 60 * 24;
|
||||
|
||||
bool tsExperimental = true;
|
||||
bool tsExperimental = true;
|
||||
|
||||
#ifndef _STORAGE
|
||||
int32_t taosSetTfsCfg(SConfig *pCfg) {
|
||||
|
@ -621,7 +622,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
0)
|
||||
return -1;
|
||||
|
||||
if (cfgAddFloat(pCfg, "ratioOfVnodeStreamThreads", tsRatioOfVnodeStreamThreads, 0.01, 100, CFG_SCOPE_SERVER,
|
||||
if (cfgAddFloat(pCfg, "ratioOfVnodeStreamThreads", tsRatioOfVnodeStreamThreads, 0.01, 10, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -673,6 +674,9 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "syncHeartbeatTimeout", tsHeartbeatTimeout, 10, 1000 * 60 * 24 * 2, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "syncSnapReplMaxWaitN", tsSnapReplMaxWaitN, 16,
|
||||
(TSDB_SYNC_SNAP_BUFFER_SIZE >> 2), CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
|
||||
if (cfgAddInt64(pCfg, "mndSdbWriteDelta", tsMndSdbWriteDelta, 20, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
|
@ -691,8 +695,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
|
||||
if (cfgAddBool(pCfg, "audit", tsEnableAudit, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "auditCreateTable", tsEnableAuditCreateTable, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "auditInterval", tsAuditInterval, 500, 200000, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "auditInterval", tsAuditInterval, 500, 200000, CFG_SCOPE_SERVER, CFG_DYN_NONE) != 0) return -1;
|
||||
|
||||
if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, CFG_SCOPE_BOTH, CFG_DYN_NONE) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "telemetryReporting", tsEnableTelem, CFG_SCOPE_BOTH, CFG_DYN_ENT_SERVER) != 0) return -1;
|
||||
|
@ -711,8 +714,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "transPullupInterval", tsTransPullupInterval, 1, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) !=
|
||||
0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "compactPullupInterval", tsCompactPullupInterval, 1, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) !=
|
||||
0)
|
||||
if (cfgAddInt32(pCfg, "compactPullupInterval", tsCompactPullupInterval, 1, 10000, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "mqRebalanceInterval", tsMqRebalanceInterval, 1, 10000, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER) !=
|
||||
0)
|
||||
|
@ -1183,6 +1186,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
|||
tsElectInterval = cfgGetItem(pCfg, "syncElectInterval")->i32;
|
||||
tsHeartbeatInterval = cfgGetItem(pCfg, "syncHeartbeatInterval")->i32;
|
||||
tsHeartbeatTimeout = cfgGetItem(pCfg, "syncHeartbeatTimeout")->i32;
|
||||
tsSnapReplMaxWaitN = cfgGetItem(pCfg, "syncSnapReplMaxWaitN")->i32;
|
||||
|
||||
tsMndSdbWriteDelta = cfgGetItem(pCfg, "mndSdbWriteDelta")->i64;
|
||||
tsMndLogRetention = cfgGetItem(pCfg, "mndLogRetention")->i64;
|
||||
|
@ -1377,7 +1381,7 @@ void taosCleanupCfg() {
|
|||
|
||||
typedef struct {
|
||||
const char *optionName;
|
||||
void * optionVar;
|
||||
void *optionVar;
|
||||
} OptionNameAndVar;
|
||||
|
||||
static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize, SConfigItem *pItem, bool isDebugflag) {
|
||||
|
@ -1390,7 +1394,7 @@ static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize,
|
|||
switch (pItem->dtype) {
|
||||
case CFG_DTYPE_BOOL: {
|
||||
int32_t flag = pItem->i32;
|
||||
bool * pVar = pOptions[d].optionVar;
|
||||
bool *pVar = pOptions[d].optionVar;
|
||||
uInfo("%s set from %d to %d", optName, *pVar, flag);
|
||||
*pVar = flag;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
@ -1465,40 +1469,38 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
|
|||
{"stDebugFlag", &stDebugFlag}, {"sndDebugFlag", &sndDebugFlag},
|
||||
};
|
||||
|
||||
static OptionNameAndVar options[] = {
|
||||
{"audit", &tsEnableAudit},
|
||||
{"asynclog", &tsAsyncLog},
|
||||
{"disableStream", &tsDisableStream},
|
||||
{"enableWhiteList", &tsEnableWhiteList},
|
||||
{"telemetryReporting", &tsEnableTelem},
|
||||
{"monitor", &tsEnableMonitor},
|
||||
static OptionNameAndVar options[] = {{"audit", &tsEnableAudit},
|
||||
{"asynclog", &tsAsyncLog},
|
||||
{"disableStream", &tsDisableStream},
|
||||
{"enableWhiteList", &tsEnableWhiteList},
|
||||
{"telemetryReporting", &tsEnableTelem},
|
||||
{"monitor", &tsEnableMonitor},
|
||||
|
||||
{"mndSdbWriteDelta", &tsMndSdbWriteDelta},
|
||||
{"minDiskFreeSize", &tsMinDiskFreeSize},
|
||||
{"mndSdbWriteDelta", &tsMndSdbWriteDelta},
|
||||
{"minDiskFreeSize", &tsMinDiskFreeSize},
|
||||
|
||||
{"cacheLazyLoadThreshold", &tsCacheLazyLoadThreshold},
|
||||
{"checkpointInterval", &tsStreamCheckpointInterval},
|
||||
{"keepAliveIdle", &tsKeepAliveIdle},
|
||||
{"logKeepDays", &tsLogKeepDays},
|
||||
{"maxStreamBackendCache", &tsMaxStreamBackendCache},
|
||||
{"mqRebalanceInterval", &tsMqRebalanceInterval},
|
||||
{"numOfLogLines", &tsNumOfLogLines},
|
||||
{"queryRspPolicy", &tsQueryRspPolicy},
|
||||
{"timeseriesThreshold", &tsTimeSeriesThreshold},
|
||||
{"tmqMaxTopicNum", &tmqMaxTopicNum},
|
||||
{"transPullupInterval", &tsTransPullupInterval},
|
||||
{"compactPullupInterval", &tsCompactPullupInterval},
|
||||
{"trimVDbIntervalSec", &tsTrimVDbIntervalSec},
|
||||
{"ttlBatchDropNum", &tsTtlBatchDropNum},
|
||||
{"ttlFlushThreshold", &tsTtlFlushThreshold},
|
||||
{"ttlPushInterval", &tsTtlPushIntervalSec},
|
||||
//{"s3BlockSize", &tsS3BlockSize},
|
||||
{"s3BlockCacheSize", &tsS3BlockCacheSize},
|
||||
{"s3PageCacheSize", &tsS3PageCacheSize},
|
||||
{"s3UploadDelaySec", &tsS3UploadDelaySec},
|
||||
{"supportVnodes", &tsNumOfSupportVnodes},
|
||||
{"experimental", &tsExperimental}
|
||||
};
|
||||
{"cacheLazyLoadThreshold", &tsCacheLazyLoadThreshold},
|
||||
{"checkpointInterval", &tsStreamCheckpointInterval},
|
||||
{"keepAliveIdle", &tsKeepAliveIdle},
|
||||
{"logKeepDays", &tsLogKeepDays},
|
||||
{"maxStreamBackendCache", &tsMaxStreamBackendCache},
|
||||
{"mqRebalanceInterval", &tsMqRebalanceInterval},
|
||||
{"numOfLogLines", &tsNumOfLogLines},
|
||||
{"queryRspPolicy", &tsQueryRspPolicy},
|
||||
{"timeseriesThreshold", &tsTimeSeriesThreshold},
|
||||
{"tmqMaxTopicNum", &tmqMaxTopicNum},
|
||||
{"transPullupInterval", &tsTransPullupInterval},
|
||||
{"compactPullupInterval", &tsCompactPullupInterval},
|
||||
{"trimVDbIntervalSec", &tsTrimVDbIntervalSec},
|
||||
{"ttlBatchDropNum", &tsTtlBatchDropNum},
|
||||
{"ttlFlushThreshold", &tsTtlFlushThreshold},
|
||||
{"ttlPushInterval", &tsTtlPushIntervalSec},
|
||||
//{"s3BlockSize", &tsS3BlockSize},
|
||||
{"s3BlockCacheSize", &tsS3BlockCacheSize},
|
||||
{"s3PageCacheSize", &tsS3PageCacheSize},
|
||||
{"s3UploadDelaySec", &tsS3UploadDelaySec},
|
||||
{"supportVnodes", &tsNumOfSupportVnodes},
|
||||
{"experimental", &tsExperimental}};
|
||||
|
||||
if (taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true) != 0) {
|
||||
taosCfgSetOption(options, tListLen(options), pItem, false);
|
||||
|
@ -1692,36 +1694,34 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) {
|
|||
{"cDebugFlag", &cDebugFlag}, {"dDebugFlag", &dDebugFlag}, {"fsDebugFlag", &fsDebugFlag},
|
||||
{"idxDebugFlag", &idxDebugFlag}, {"jniDebugFlag", &jniDebugFlag}, {"qDebugFlag", &qDebugFlag},
|
||||
{"rpcDebugFlag", &rpcDebugFlag}, {"smaDebugFlag", &smaDebugFlag}, {"tmrDebugFlag", &tmrDebugFlag},
|
||||
{"uDebugFlag", &uDebugFlag}, {"simDebugFlag", &simDebugFlag},
|
||||
{"uDebugFlag", &uDebugFlag}, {"simDebugFlag", &simDebugFlag},
|
||||
};
|
||||
|
||||
static OptionNameAndVar options[] = {
|
||||
{"asyncLog", &tsAsyncLog},
|
||||
{"assert", &tsAssert},
|
||||
{"compressMsgSize", &tsCompressMsgSize},
|
||||
{"countAlwaysReturnValue", &tsCountAlwaysReturnValue},
|
||||
{"crashReporting", &tsEnableCrashReport},
|
||||
{"enableCoreFile", &tsAsyncLog},
|
||||
{"enableQueryHb", &tsEnableQueryHb},
|
||||
{"keepColumnName", &tsKeepColumnName},
|
||||
{"keepAliveIdle", &tsKeepAliveIdle},
|
||||
{"logKeepDays", &tsLogKeepDays},
|
||||
{"maxInsertBatchRows", &tsMaxInsertBatchRows},
|
||||
{"maxRetryWaitTime", &tsMaxRetryWaitTime},
|
||||
{"minSlidingTime", &tsMinSlidingTime},
|
||||
{"minIntervalTime", &tsMinIntervalTime},
|
||||
{"numOfLogLines", &tsNumOfLogLines},
|
||||
{"querySmaOptimize", &tsQuerySmaOptimize},
|
||||
{"queryPolicy", &tsQueryPolicy},
|
||||
{"queryPlannerTrace", &tsQueryPlannerTrace},
|
||||
{"queryNodeChunkSize", &tsQueryNodeChunkSize},
|
||||
{"queryUseNodeAllocator", &tsQueryUseNodeAllocator},
|
||||
{"smlDot2Underline", &tsSmlDot2Underline},
|
||||
{"shellActivityTimer", &tsShellActivityTimer},
|
||||
{"slowLogThreshold", &tsSlowLogThreshold},
|
||||
{"useAdapter", &tsUseAdapter},
|
||||
{"experimental", &tsExperimental}
|
||||
};
|
||||
static OptionNameAndVar options[] = {{"asyncLog", &tsAsyncLog},
|
||||
{"assert", &tsAssert},
|
||||
{"compressMsgSize", &tsCompressMsgSize},
|
||||
{"countAlwaysReturnValue", &tsCountAlwaysReturnValue},
|
||||
{"crashReporting", &tsEnableCrashReport},
|
||||
{"enableCoreFile", &tsAsyncLog},
|
||||
{"enableQueryHb", &tsEnableQueryHb},
|
||||
{"keepColumnName", &tsKeepColumnName},
|
||||
{"keepAliveIdle", &tsKeepAliveIdle},
|
||||
{"logKeepDays", &tsLogKeepDays},
|
||||
{"maxInsertBatchRows", &tsMaxInsertBatchRows},
|
||||
{"maxRetryWaitTime", &tsMaxRetryWaitTime},
|
||||
{"minSlidingTime", &tsMinSlidingTime},
|
||||
{"minIntervalTime", &tsMinIntervalTime},
|
||||
{"numOfLogLines", &tsNumOfLogLines},
|
||||
{"querySmaOptimize", &tsQuerySmaOptimize},
|
||||
{"queryPolicy", &tsQueryPolicy},
|
||||
{"queryPlannerTrace", &tsQueryPlannerTrace},
|
||||
{"queryNodeChunkSize", &tsQueryNodeChunkSize},
|
||||
{"queryUseNodeAllocator", &tsQueryUseNodeAllocator},
|
||||
{"smlDot2Underline", &tsSmlDot2Underline},
|
||||
{"shellActivityTimer", &tsShellActivityTimer},
|
||||
{"slowLogThreshold", &tsSlowLogThreshold},
|
||||
{"useAdapter", &tsUseAdapter},
|
||||
{"experimental", &tsExperimental}};
|
||||
|
||||
if (taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true) != 0) {
|
||||
taosCfgSetOption(options, tListLen(options), pItem, false);
|
||||
|
@ -1798,7 +1798,7 @@ void taosSetAllDebugFlag(int32_t flag) {
|
|||
taosArrayClear(noNeedToSetVars); // reset array
|
||||
|
||||
uInfo("all debug flag are set to %d", flag);
|
||||
if (terrno == TSDB_CODE_CFG_NOT_FOUND) terrno = TSDB_CODE_SUCCESS; // ignore not exist
|
||||
if (terrno == TSDB_CODE_CFG_NOT_FOUND) terrno = TSDB_CODE_SUCCESS; // ignore not exist
|
||||
}
|
||||
|
||||
int8_t taosGranted() { return atomic_load_8(&tsGrant); }
|
||||
|
|
|
@ -8334,7 +8334,7 @@ int32_t tDecodeMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
int32_t tEncodeMqDataRspCommon(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->reqOffset) < 0) return -1;
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->blockNum) < 0) return -1;
|
||||
|
@ -8356,11 +8356,16 @@ int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
if (tEncodeMqDataRspCommon(pEncoder, pRsp) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pRsp->sleepTime) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
if (tDecodeSTqOffsetVal(pDecoder, &pRsp->reqOffset) < 0) return -1;
|
||||
if (tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->blockNum) < 0) return -1;
|
||||
|
@ -8402,7 +8407,15 @@ int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (tDecodeI64(pDecoder, &pRsp->sleepTime) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
if (tDecodeMqDataRspCommon(pDecoder, pRsp) < 0) return -1;
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
if (tDecodeI64(pDecoder, &pRsp->sleepTime) < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8418,7 +8431,7 @@ void tDeleteMqDataRsp(SMqDataRsp *pRsp) {
|
|||
}
|
||||
|
||||
int32_t tEncodeSTaosxRsp(SEncoder *pEncoder, const STaosxRsp *pRsp) {
|
||||
if (tEncodeMqDataRsp(pEncoder, (const SMqDataRsp *)pRsp) < 0) return -1;
|
||||
if (tEncodeMqDataRspCommon(pEncoder, (const SMqDataRsp *)pRsp) < 0) return -1;
|
||||
|
||||
if (tEncodeI32(pEncoder, pRsp->createTableNum) < 0) return -1;
|
||||
if (pRsp->createTableNum) {
|
||||
|
@ -8432,7 +8445,7 @@ int32_t tEncodeSTaosxRsp(SEncoder *pEncoder, const STaosxRsp *pRsp) {
|
|||
}
|
||||
|
||||
int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp) {
|
||||
if (tDecodeMqDataRsp(pDecoder, (SMqDataRsp *)pRsp) < 0) return -1;
|
||||
if (tDecodeMqDataRspCommon(pDecoder, (SMqDataRsp*)pRsp) < 0) return -1;
|
||||
|
||||
if (tDecodeI32(pDecoder, &pRsp->createTableNum) < 0) return -1;
|
||||
if (pRsp->createTableNum) {
|
||||
|
@ -8447,6 +8460,7 @@ int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp) {
|
|||
taosArrayPush(pRsp->createTableReq, &pCreate);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -683,6 +683,10 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati
|
|||
return getDuration(*duration, *unit, duration, timePrecision);
|
||||
}
|
||||
|
||||
static bool taosIsLeapYear(int32_t year) {
|
||||
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
|
||||
}
|
||||
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
||||
if (duration == 0) {
|
||||
return t;
|
||||
|
@ -702,7 +706,13 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
|||
int32_t mon = tm.tm_year * 12 + tm.tm_mon + (int32_t)numOfMonth;
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
|
||||
int daysOfMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
if (taosIsLeapYear(1900 + tm.tm_year)) {
|
||||
daysOfMonth[1] = 29;
|
||||
}
|
||||
if (tm.tm_mday > daysOfMonth[tm.tm_mon]) {
|
||||
tm.tm_mday = daysOfMonth[tm.tm_mon];
|
||||
}
|
||||
return (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision) + fraction);
|
||||
}
|
||||
|
||||
|
@ -872,23 +882,33 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
ASSERT(pInterval->offset >= 0);
|
||||
|
||||
if (pInterval->offset > 0) {
|
||||
start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision);
|
||||
|
||||
// try to move current window to the left-hande-side, due to the offset effect.
|
||||
int64_t end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
|
||||
int64_t newe = end;
|
||||
int64_t newe = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
int64_t slidingStart = start;
|
||||
while (newe >= ts) {
|
||||
end = newe;
|
||||
newe = taosTimeAdd(newe, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
start = slidingStart;
|
||||
slidingStart = taosTimeAdd(slidingStart, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
int64_t slidingEnd = taosTimeAdd(slidingStart, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
newe = taosTimeAdd(slidingEnd, pInterval->offset, pInterval->offsetUnit, precision);
|
||||
}
|
||||
|
||||
start = taosTimeAdd(end, -pInterval->interval, pInterval->intervalUnit, precision) + 1;
|
||||
start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision);
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// used together with taosTimeTruncate. when offset is great than zero, slide-start/slide-end is the anchor point
|
||||
int64_t taosTimeGetIntervalEnd(int64_t intervalStart, const SInterval* pInterval) {
|
||||
if (pInterval->offset > 0) {
|
||||
int64_t slideStart = taosTimeAdd(intervalStart, -1 * pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
int64_t slideEnd = taosTimeAdd(slideStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
int64_t result = taosTimeAdd(slideEnd, pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
return result;
|
||||
} else {
|
||||
int64_t result = taosTimeAdd(intervalStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// internal function, when program is paused in debugger,
|
||||
// one can call this function from debugger to print a
|
||||
// timestamp as human readable string, for example (gdb):
|
||||
|
|
|
@ -45,7 +45,7 @@ static void dmMayShouldUpdateIpWhiteList(SDnodeMgmt *pMgmt, int64_t ver) {
|
|||
|
||||
SRetrieveIpWhiteReq req = {.ipWhiteVer = oldVer};
|
||||
int32_t contLen = tSerializeRetrieveIpWhite(NULL, 0, &req);
|
||||
void *pHead = rpcMallocCont(contLen);
|
||||
void * pHead = rpcMallocCont(contLen);
|
||||
tSerializeRetrieveIpWhite(pHead, contLen, &req);
|
||||
|
||||
SRpcMsg rpcMsg = {.pCont = pHead,
|
||||
|
@ -144,7 +144,7 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
|||
req.ipWhiteVer = pMgmt->pData->ipWhiteVer;
|
||||
|
||||
int32_t contLen = tSerializeSStatusReq(NULL, 0, &req);
|
||||
void *pHead = rpcMallocCont(contLen);
|
||||
void * pHead = rpcMallocCont(contLen);
|
||||
tSerializeSStatusReq(pHead, contLen, &req);
|
||||
tFreeSStatusReq(&req);
|
||||
|
||||
|
@ -161,7 +161,7 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
|||
SEpSet epSet = {0};
|
||||
int8_t epUpdated = 0;
|
||||
dmGetMnodeEpSet(pMgmt->pData, &epSet);
|
||||
rpcSendRecvWithTimeout(pMgmt->msgCb.clientRpc, &epSet, &rpcMsg, &rpcRsp, &epUpdated, 5000);
|
||||
rpcSendRecvWithTimeout(pMgmt->msgCb.statusRpc, &epSet, &rpcMsg, &rpcRsp, &epUpdated, tsStatusInterval * 5 * 1000);
|
||||
if (rpcRsp.code != 0) {
|
||||
dmRotateMnodeEpSet(pMgmt->pData);
|
||||
char tbuf[512];
|
||||
|
@ -189,7 +189,7 @@ void dmSendNotifyReq(SDnodeMgmt *pMgmt) {
|
|||
req.pVloads = vinfo.pVloads;
|
||||
|
||||
int32_t contLen = tSerializeSNotifyReq(NULL, 0, &req);
|
||||
void *pHead = rpcMallocCont(contLen);
|
||||
void * pHead = rpcMallocCont(contLen);
|
||||
tSerializeSNotifyReq(pHead, contLen, &req);
|
||||
tFreeSNotifyReq(&req);
|
||||
|
||||
|
@ -284,7 +284,7 @@ int32_t dmProcessServerRunStatus(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
SSDataBlock *dmBuildVariablesBlock(void) {
|
||||
SSDataBlock *pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
SSDataBlock * pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
size_t size = 0;
|
||||
const SSysTableMeta *pMeta = NULL;
|
||||
getInfosDbMeta(&pMeta, &size);
|
||||
|
|
|
@ -47,28 +47,29 @@ static void *dmStatusThreadFp(void *param) {
|
|||
}
|
||||
|
||||
SDmNotifyHandle dmNotifyHdl = {.state = 0};
|
||||
static void *dmNotifyThreadFp(void *param) {
|
||||
SDnodeMgmt *pMgmt = param;
|
||||
setThreadName("dnode-notify");
|
||||
|
||||
if (tsem_init(&dmNotifyHdl.sem, 0, 0) != 0) {
|
||||
return NULL;
|
||||
static void *dmNotifyThreadFp(void *param) {
|
||||
SDnodeMgmt *pMgmt = param;
|
||||
setThreadName("dnode-notify");
|
||||
|
||||
if (tsem_init(&dmNotifyHdl.sem, 0, 0) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool wait = true;
|
||||
while (1) {
|
||||
if (pMgmt->pData->dropped || pMgmt->pData->stopped) break;
|
||||
bool wait = true;
|
||||
while (1) {
|
||||
if (pMgmt->pData->dropped || pMgmt->pData->stopped) break;
|
||||
if (wait) tsem_wait(&dmNotifyHdl.sem);
|
||||
atomic_store_8(&dmNotifyHdl.state, 1);
|
||||
dmSendNotifyReq(pMgmt);
|
||||
if (1 == atomic_val_compare_exchange_8(&dmNotifyHdl.state, 1, 0)) {
|
||||
wait = true;
|
||||
continue;
|
||||
dmSendNotifyReq(pMgmt);
|
||||
if (1 == atomic_val_compare_exchange_8(&dmNotifyHdl.state, 1, 0)) {
|
||||
wait = true;
|
||||
continue;
|
||||
}
|
||||
wait = false;
|
||||
wait = false;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *dmMonitorThreadFp(void *param) {
|
||||
|
|
|
@ -407,12 +407,8 @@ int32_t vmStartWorker(SVnodeMgmt *pMgmt) {
|
|||
if (tWWorkerInit(pFPool) != 0) return -1;
|
||||
|
||||
SSingleWorkerCfg mgmtCfg = {
|
||||
.min = 1,
|
||||
.max = 1,
|
||||
.name = "vnode-mgmt",
|
||||
.fp = (FItem)vmProcessMgmtQueue,
|
||||
.param = pMgmt,
|
||||
};
|
||||
.min = 1, .max = 1, .name = "vnode-mgmt", .fp = (FItem)vmProcessMgmtQueue, .param = pMgmt};
|
||||
|
||||
if (tSingleWorkerInit(&pMgmt->mgmtWorker, &mgmtCfg) != 0) return -1;
|
||||
|
||||
dDebug("vnode workers are initialized");
|
||||
|
|
|
@ -48,6 +48,8 @@ typedef struct {
|
|||
typedef struct {
|
||||
void *serverRpc;
|
||||
void *clientRpc;
|
||||
void *statusRpc;
|
||||
void *syncRpc;
|
||||
SDnodeHandle msgHandles[TDMT_MAX];
|
||||
} SDnodeTrans;
|
||||
|
||||
|
@ -136,8 +138,10 @@ int32_t dmInitServer(SDnode *pDnode);
|
|||
void dmCleanupServer(SDnode *pDnode);
|
||||
int32_t dmInitClient(SDnode *pDnode);
|
||||
int32_t dmInitStatusClient(SDnode *pDnode);
|
||||
int32_t dmInitSyncClient(SDnode *pDnode);
|
||||
void dmCleanupClient(SDnode *pDnode);
|
||||
void dmCleanupStatusClient(SDnode *pDnode);
|
||||
void dmCleanupSyncClient(SDnode *pDnode);
|
||||
SMsgCb dmGetMsgcb(SDnode *pDnode);
|
||||
#ifdef TD_MODULE_OPTIMIZE
|
||||
int32_t dmInitMsgHandle(SDnode *pDnode, SMgmtWrapper *wrappers);
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
extern int32_t streamTimerInit();
|
||||
extern void streamTimerCleanUp();
|
||||
|
||||
static SDnode globalDnode = {0};
|
||||
|
||||
SDnode *dmInstance() { return &globalDnode; }
|
||||
|
@ -169,7 +166,6 @@ int32_t dmInit() {
|
|||
#if defined(USE_S3)
|
||||
if (s3Begin() != 0) return -1;
|
||||
#endif
|
||||
if (streamTimerInit() != 0) return -1;
|
||||
|
||||
dInfo("dnode env is initialized");
|
||||
return 0;
|
||||
|
@ -196,10 +192,10 @@ void dmCleanup() {
|
|||
udfStopUdfd();
|
||||
taosStopCacheRefreshWorker();
|
||||
dmDiskClose();
|
||||
|
||||
#if defined(USE_S3)
|
||||
s3End();
|
||||
#endif
|
||||
streamTimerCleanUp();
|
||||
|
||||
dInfo("dnode env is cleaned up");
|
||||
|
||||
|
|
|
@ -90,9 +90,13 @@ int32_t dmInitDnode(SDnode *pDnode) {
|
|||
goto _OVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
indexInit(tsNumOfCommitThreads);
|
||||
streamMetaInit();
|
||||
|
||||
dmInitStatusClient(pDnode);
|
||||
dmInitSyncClient(pDnode);
|
||||
|
||||
dmReportStartup("dnode-transport", "initialized");
|
||||
dDebug("dnode is created, ptr:%p", pDnode);
|
||||
code = 0;
|
||||
|
@ -108,11 +112,15 @@ _OVER:
|
|||
}
|
||||
|
||||
void dmCleanupDnode(SDnode *pDnode) {
|
||||
if (pDnode == NULL) return;
|
||||
if (pDnode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dmCleanupClient(pDnode);
|
||||
dmCleanupStatusClient(pDnode);
|
||||
dmCleanupSyncClient(pDnode);
|
||||
dmCleanupServer(pDnode);
|
||||
|
||||
dmClearVars(pDnode);
|
||||
rpcCleanup();
|
||||
streamMetaCleanup();
|
||||
|
|
|
@ -322,6 +322,23 @@ static inline int32_t dmSendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
static inline int32_t dmSendSyncReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
SDnode *pDnode = dmInstance();
|
||||
if (pDnode->status != DND_STAT_RUNNING && pMsg->msgType < TDMT_SYNC_MSG) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
if (pDnode->status == DND_STAT_INIT) {
|
||||
terrno = TSDB_CODE_APP_IS_STARTING;
|
||||
} else {
|
||||
terrno = TSDB_CODE_APP_IS_STOPPING;
|
||||
}
|
||||
dError("failed to send rpc msg:%s since %s, handle:%p", TMSG_INFO(pMsg->msgType), terrstr(), pMsg->info.handle);
|
||||
return -1;
|
||||
} else {
|
||||
rpcSendRequest(pDnode->trans.syncRpc, pEpSet, pMsg, NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dmRegisterBrokenLinkArg(SRpcMsg *pMsg) { rpcRegisterBrokenLinkArg(pMsg); }
|
||||
|
||||
|
@ -346,8 +363,8 @@ int32_t dmInitClient(SDnode *pDnode) {
|
|||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
|
||||
SRpcInit rpcInit = {0};
|
||||
rpcInit.label = "DND-C";
|
||||
rpcInit.numOfThreads = tsNumOfRpcThreads;
|
||||
rpcInit.label = "DNODE-CLI";
|
||||
rpcInit.numOfThreads = tsNumOfRpcThreads / 2;
|
||||
rpcInit.cfp = (RpcCfp)dmProcessRpcMsg;
|
||||
rpcInit.sessions = 1024;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
|
@ -366,7 +383,7 @@ int32_t dmInitClient(SDnode *pDnode) {
|
|||
rpcInit.failFastThreshold = 3; // failed threshold
|
||||
rpcInit.ffp = dmFailFastFp;
|
||||
|
||||
int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3);
|
||||
int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3) / 2;
|
||||
connLimitNum = TMAX(connLimitNum, 10);
|
||||
connLimitNum = TMIN(connLimitNum, 500);
|
||||
|
||||
|
@ -390,7 +407,7 @@ int32_t dmInitStatusClient(SDnode *pDnode) {
|
|||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
|
||||
SRpcInit rpcInit = {0};
|
||||
rpcInit.label = "DND-STATUS";
|
||||
rpcInit.label = "DNODE-STA-CLI";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = (RpcCfp)dmProcessRpcMsg;
|
||||
rpcInit.sessions = 1024;
|
||||
|
@ -421,16 +438,61 @@ int32_t dmInitStatusClient(SDnode *pDnode) {
|
|||
rpcInit.timeToGetConn = tsTimeToGetAvailableConn;
|
||||
taosVersionStrToInt(version, &(rpcInit.compatibilityVer));
|
||||
|
||||
// pTrans->statusClientRpc = rpcOpen(&rpcInit);
|
||||
// if (pTrans->statusClientRpc == NULL) {
|
||||
// dError("failed to init dnode rpc status client");
|
||||
// return -1;
|
||||
// }
|
||||
pTrans->statusRpc = rpcOpen(&rpcInit);
|
||||
if (pTrans->statusRpc == NULL) {
|
||||
dError("failed to init dnode rpc status client");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dDebug("dnode rpc status client is initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t dmInitSyncClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
|
||||
SRpcInit rpcInit = {0};
|
||||
rpcInit.label = "DNODE-SYNC-CLI";
|
||||
rpcInit.numOfThreads = tsNumOfRpcThreads / 2;
|
||||
rpcInit.cfp = (RpcCfp)dmProcessRpcMsg;
|
||||
rpcInit.sessions = 1024;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
rpcInit.user = TSDB_DEFAULT_USER;
|
||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||
rpcInit.parent = pDnode;
|
||||
rpcInit.rfp = rpcRfp;
|
||||
rpcInit.compressSize = tsCompressMsgSize;
|
||||
|
||||
rpcInit.retryMinInterval = tsRedirectPeriod;
|
||||
rpcInit.retryStepFactor = tsRedirectFactor;
|
||||
rpcInit.retryMaxInterval = tsRedirectMaxPeriod;
|
||||
rpcInit.retryMaxTimeout = tsMaxRetryWaitTime;
|
||||
|
||||
rpcInit.failFastInterval = 5000; // interval threshold(ms)
|
||||
rpcInit.failFastThreshold = 3; // failed threshold
|
||||
rpcInit.ffp = dmFailFastFp;
|
||||
|
||||
int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3) / 2;
|
||||
connLimitNum = TMAX(connLimitNum, 10);
|
||||
connLimitNum = TMIN(connLimitNum, 500);
|
||||
|
||||
rpcInit.connLimitNum = connLimitNum;
|
||||
rpcInit.connLimitLock = 1;
|
||||
rpcInit.supportBatch = 1;
|
||||
rpcInit.batchSize = 8 * 1024;
|
||||
rpcInit.timeToGetConn = tsTimeToGetAvailableConn;
|
||||
taosVersionStrToInt(version, &(rpcInit.compatibilityVer));
|
||||
|
||||
pTrans->syncRpc = rpcOpen(&rpcInit);
|
||||
if (pTrans->syncRpc == NULL) {
|
||||
dError("failed to init dnode rpc sync client");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dDebug("dnode rpc sync client is initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dmCleanupClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
if (pTrans->clientRpc) {
|
||||
|
@ -441,11 +503,19 @@ void dmCleanupClient(SDnode *pDnode) {
|
|||
}
|
||||
void dmCleanupStatusClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
// if (pTrans->statusClientRpc) {
|
||||
// rpcClose(pTrans->statusClientRpc);
|
||||
// pTrans->statusClientRpc = NULL;
|
||||
// dDebug("dnode rpc status client is closed");
|
||||
// }
|
||||
if (pTrans->statusRpc) {
|
||||
rpcClose(pTrans->statusRpc);
|
||||
pTrans->statusRpc = NULL;
|
||||
dDebug("dnode rpc status client is closed");
|
||||
}
|
||||
}
|
||||
void dmCleanupSyncClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
if (pTrans->syncRpc) {
|
||||
rpcClose(pTrans->syncRpc);
|
||||
pTrans->syncRpc = NULL;
|
||||
dDebug("dnode rpc sync client is closed");
|
||||
}
|
||||
}
|
||||
|
||||
int32_t dmInitServer(SDnode *pDnode) {
|
||||
|
@ -486,7 +556,10 @@ SMsgCb dmGetMsgcb(SDnode *pDnode) {
|
|||
SMsgCb msgCb = {
|
||||
.clientRpc = pDnode->trans.clientRpc,
|
||||
.serverRpc = pDnode->trans.serverRpc,
|
||||
.statusRpc = pDnode->trans.statusRpc,
|
||||
.syncRpc = pDnode->trans.syncRpc,
|
||||
.sendReqFp = dmSendReq,
|
||||
.sendSyncReqFp = dmSendSyncReq,
|
||||
.sendRspFp = dmSendRsp,
|
||||
.registerBrokenLinkArgFp = dmRegisterBrokenLinkArg,
|
||||
.releaseHandleFp = dmReleaseHandle,
|
||||
|
|
|
@ -71,7 +71,8 @@ int32_t mndPersistStream(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream
|
|||
|
||||
int32_t mndStreamRegisterTrans(STrans* pTrans, const char* pTransName, int64_t streamUid);
|
||||
int32_t mndAddtoCheckpointWaitingList(SStreamObj *pStream, int64_t checkpointId);
|
||||
bool streamTransConflictOtherTrans(SMnode *pMnode, int64_t streamUid, const char *pTransName, bool lock);
|
||||
bool mndStreamTransConflictCheck(SMnode *pMnode, int64_t streamUid, const char *pTransName, bool lock);
|
||||
int32_t mndStreamGetRelTrans(SMnode *pMnode, int64_t streamUid);
|
||||
|
||||
// for sma
|
||||
// TODO refactor
|
||||
|
|
|
@ -32,6 +32,10 @@ int32_t sendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
|||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return -1;
|
||||
}
|
||||
int32_t sendSyncReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *i642str(int64_t val) {
|
||||
static char str[24] = {0};
|
||||
|
@ -568,6 +572,7 @@ void mndDumpSdb() {
|
|||
SMsgCb msgCb = {0};
|
||||
msgCb.reportStartupFp = reportStartup;
|
||||
msgCb.sendReqFp = sendReq;
|
||||
msgCb.sendSyncReqFp = sendSyncReq;
|
||||
msgCb.sendRspFp = sendRsp;
|
||||
msgCb.mgmt = (SMgmtWrapper *)(&msgCb); // hack
|
||||
tmsgSetDefault(&msgCb);
|
||||
|
@ -590,7 +595,7 @@ void mndDumpSdb() {
|
|||
dumpTopic(pSdb, json);
|
||||
dumpConsumer(pSdb, json);
|
||||
dumpSubscribe(pSdb, json);
|
||||
// dumpOffset(pSdb, json);
|
||||
// dumpOffset(pSdb, json);
|
||||
dumpStream(pSdb, json);
|
||||
dumpAcct(pSdb, json);
|
||||
dumpAuth(pSdb, json);
|
||||
|
@ -605,7 +610,7 @@ void mndDumpSdb() {
|
|||
char *pCont = tjsonToString(json);
|
||||
int32_t contLen = strlen(pCont);
|
||||
char file[] = "sdb.json";
|
||||
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC| TD_FILE_WRITE_THROUGH);
|
||||
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
mError("failed to write %s since %s", file, terrstr());
|
||||
|
|
|
@ -145,7 +145,7 @@ static void mndCalMqRebalance(SMnode *pMnode) {
|
|||
void *pReq = mndBuildTimerMsg(&contLen);
|
||||
if (pReq != NULL) {
|
||||
SRpcMsg rpcMsg = {.msgType = TDMT_MND_TMQ_TIMER, .pCont = pReq, .contLen = contLen};
|
||||
tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg);
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,14 +299,14 @@ static bool mnodeIsNotLeader(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
static int32_t minCronTime() {
|
||||
int64_t min = INT64_MAX;
|
||||
int32_t min = INT32_MAX;
|
||||
min = TMIN(min, tsTtlPushIntervalSec);
|
||||
min = TMIN(min, tsTrimVDbIntervalSec);
|
||||
min = TMIN(min, tsTransPullupInterval);
|
||||
min = TMIN(min, tsCompactPullupInterval);
|
||||
min = TMIN(min, tsMqRebalanceInterval);
|
||||
min = TMIN(min, tsStreamCheckpointInterval);
|
||||
min = TMIN(min, 5); // checkpointRemain
|
||||
min = TMIN(min, 6); // checkpointRemain
|
||||
min = TMIN(min, tsStreamNodeCheckInterval);
|
||||
|
||||
int64_t telemInt = TMIN(60, (tsTelemInterval - 1));
|
||||
|
@ -386,7 +386,8 @@ static void *mndThreadFp(void *param) {
|
|||
int64_t minCron = minCronTime();
|
||||
if (sec % minCron == 0 && mnodeIsNotLeader(pMnode)) {
|
||||
// not leader, do nothing
|
||||
mTrace("timer not process since mnode is not leader, reason: %s", tstrerror(terrno)) terrno = 0;
|
||||
mTrace("timer not process since mnode is not leader, reason: %s", tstrerror(terrno));
|
||||
terrno = 0;
|
||||
continue;
|
||||
}
|
||||
mndDoTimerPullupTask(pMnode, sec);
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct SNodeEntry {
|
|||
|
||||
typedef struct SVgroupChangeInfo {
|
||||
SHashObj *pDBMap;
|
||||
SArray * pUpdateNodeList; // SArray<SNodeUpdateInfo>
|
||||
SArray *pUpdateNodeList; // SArray<SNodeUpdateInfo>
|
||||
} SVgroupChangeInfo;
|
||||
|
||||
static int32_t mndNodeCheckSentinel = 0;
|
||||
|
@ -80,22 +80,21 @@ static int32_t createStreamUpdateTrans(SStreamObj *pStream, SVgroupChangeInfo *p
|
|||
static void removeStreamTasksInBuf(SStreamObj *pStream, SStreamExecInfo *pExecNode);
|
||||
static void saveStreamTasksInfo(SStreamObj *pStream, SStreamExecInfo *pExecNode);
|
||||
static int32_t removeExpirednodeEntryAndTask(SArray *pNodeSnapshot);
|
||||
static int32_t killActiveCheckpointTrans(SMnode *pMnode, const char *pDbName, size_t len);
|
||||
static int32_t doKillCheckpointTrans(SMnode *pMnode, const char *pDbName, size_t len);
|
||||
static void killTransImpl(SMnode *pMnode, int32_t transId, const char *pDbName);
|
||||
|
||||
static int32_t setNodeEpsetExpiredFlag(const SArray *pNodeList);
|
||||
static void freeCheckpointCandEntry(void *);
|
||||
|
||||
static SSdbRaw *mndStreamActionEncode(SStreamObj *pStream);
|
||||
static SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw);
|
||||
|
||||
SSdbRaw * mndStreamSeqActionEncode(SStreamObj *pStream);
|
||||
SSdbRow * mndStreamSeqActionDecode(SSdbRaw *pRaw);
|
||||
SSdbRaw *mndStreamSeqActionEncode(SStreamObj *pStream);
|
||||
SSdbRow *mndStreamSeqActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndStreamSeqActionInsert(SSdb *pSdb, SStreamSeq *pStream);
|
||||
static int32_t mndStreamSeqActionDelete(SSdb *pSdb, SStreamSeq *pStream);
|
||||
static int32_t mndStreamSeqActionUpdate(SSdb *pSdb, SStreamSeq *pOldStream, SStreamSeq *pNewStream);
|
||||
|
||||
static SSdbRaw *mndStreamActionEncode(SStreamObj *pStream);
|
||||
static SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw);
|
||||
|
||||
int32_t mndInitStream(SMnode *pMnode) {
|
||||
SSdbTable table = {
|
||||
.sdbType = SDB_STREAM,
|
||||
|
@ -220,9 +219,9 @@ STREAM_ENCODE_OVER:
|
|||
|
||||
SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
SSdbRow * pRow = NULL;
|
||||
SSdbRow *pRow = NULL;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * buf = NULL;
|
||||
void *buf = NULL;
|
||||
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
|
||||
|
@ -302,7 +301,7 @@ static int32_t mndStreamActionUpdate(SSdb *pSdb, SStreamObj *pOldStream, SStream
|
|||
}
|
||||
|
||||
SStreamObj *mndAcquireStream(SMnode *pMnode, char *streamName) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = sdbAcquire(pSdb, SDB_STREAM, streamName);
|
||||
if (pStream == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||
terrno = TSDB_CODE_MND_STREAM_NOT_EXIST;
|
||||
|
@ -357,7 +356,7 @@ static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) {
|
|||
}
|
||||
|
||||
static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, SCMCreateStreamReq *pCreate) {
|
||||
SNode * pAst = NULL;
|
||||
SNode *pAst = NULL;
|
||||
SQueryPlan *pPlan = NULL;
|
||||
|
||||
mInfo("stream:%s to create", pCreate->name);
|
||||
|
@ -596,7 +595,7 @@ int32_t mndPersistDropStreamLog(SMnode *pMnode, STrans *pTrans, SStreamObj *pStr
|
|||
|
||||
static int32_t mndCreateStbForStream(SMnode *pMnode, STrans *pTrans, const SStreamObj *pStream, const char *user) {
|
||||
SStbObj *pStb = NULL;
|
||||
SDbObj * pDb = NULL;
|
||||
SDbObj *pDb = NULL;
|
||||
|
||||
SMCreateStbReq createReq = {0};
|
||||
tstrncpy(createReq.name, pStream->targetSTbName, TSDB_TABLE_FNAME_LEN);
|
||||
|
@ -685,9 +684,10 @@ _OVER:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t extractNodeEpset(SMnode *pMnode, SEpSet *pEpSet, bool* hasEpset, int32_t taskId, int32_t nodeId) {
|
||||
static int32_t extractNodeEpset(SMnode *pMnode, SEpSet *pEpSet, bool *hasEpset, int32_t taskId, int32_t nodeId) {
|
||||
*hasEpset = false;
|
||||
|
||||
pEpSet->numOfEps = 0;
|
||||
if (nodeId == SNODE_HANDLE) {
|
||||
SSnodeObj *pObj = NULL;
|
||||
void *pIter = NULL;
|
||||
|
@ -773,7 +773,7 @@ int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream)
|
|||
static int32_t checkForNumOfStreams(SMnode *pMnode, SStreamObj *pStreamObj) { // check for number of existed tasks
|
||||
int32_t numOfStream = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
while ((pIter = sdbFetch(pMnode->pSdb, SDB_STREAM, pIter, (void **)&pStream)) != NULL) {
|
||||
if (pStream->sourceDbUid == pStreamObj->sourceDbUid) {
|
||||
|
@ -804,7 +804,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
SStreamObj streamObj = {0};
|
||||
char * sql = NULL;
|
||||
char *sql = NULL;
|
||||
int32_t sqlLen = 0;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -931,7 +931,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
_OVER:
|
||||
if (terrno != TSDB_CODE_SUCCESS && terrno != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
if (terrno != TSDB_CODE_SUCCESS && terrno != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr());
|
||||
}
|
||||
|
||||
|
@ -947,8 +947,8 @@ _OVER:
|
|||
|
||||
int64_t mndStreamGenChkpId(SMnode *pMnode) {
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int64_t maxChkpId = 0;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -966,7 +966,7 @@ int64_t mndStreamGenChkpId(SMnode *pMnode) {
|
|||
|
||||
static int32_t mndProcessStreamCheckpointTmr(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -982,7 +982,7 @@ static int32_t mndProcessStreamCheckpointTmr(SRpcMsg *pReq) {
|
|||
|
||||
static int32_t mndProcessStreamRemainChkptTmr(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1023,7 +1023,7 @@ static int32_t mndBuildStreamCheckpointSourceReq2(void **pBuf, int32_t *pLen, in
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, tlen);
|
||||
tEncodeStreamCheckpointSourceReq(&encoder, &req);
|
||||
|
@ -1047,7 +1047,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_CHECKPOINT_NAME, true);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_CHECKPOINT_NAME, true);
|
||||
if (conflict) {
|
||||
mndAddtoCheckpointWaitingList(pStream, checkpointId);
|
||||
mWarn("checkpoint conflict with other trans in %s, ignore the checkpoint for stream:%s %" PRIx64, pStream->sourceDb,
|
||||
|
@ -1077,7 +1077,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
// 1. redo action: broadcast checkpoint source msg for all source vg
|
||||
int32_t totLevel = taosArrayGetSize(pStream->tasks);
|
||||
for (int32_t i = 0; i < totLevel; i++) {
|
||||
SArray * pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SArray *pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SStreamTask *p = taosArrayGetP(pLevel, 0);
|
||||
|
||||
if (p->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
|
@ -1091,7 +1091,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
goto _ERR;
|
||||
}
|
||||
|
||||
void * buf;
|
||||
void *buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, checkpointId, pTask->id.streamId,
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
|
@ -1143,7 +1143,7 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream
|
|||
|
||||
int32_t totLevel = taosArrayGetSize(pStream->tasks);
|
||||
for (int32_t i = 0; i < totLevel; i++) {
|
||||
SArray * pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SArray *pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, 0);
|
||||
|
||||
if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
|
@ -1160,7 +1160,7 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * buf;
|
||||
void *buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, chkptId, pTask->id.streamId,
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
|
@ -1279,7 +1279,7 @@ static int32_t mndCheckNodeStatus(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(execInfo.pTaskList); ++i) {
|
||||
STaskId * p = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskId *p = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, p, sizeof(*p));
|
||||
if (pEntry == NULL) {
|
||||
continue;
|
||||
|
@ -1298,9 +1298,9 @@ static int32_t mndCheckNodeStatus(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void * pIter = NULL;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SStreamObj *pStream = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -1322,7 +1322,7 @@ static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) {
|
|||
|
||||
static int32_t mndProcessStreamCheckpointInCandid(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&execInfo.lock);
|
||||
|
@ -1344,6 +1344,7 @@ static int32_t mndProcessStreamCheckpointInCandid(SRpcMsg *pReq) {
|
|||
if (ps == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mDebug("start to launch checkpoint for stream:%s %" PRIx64 " in candidate list", pEntry->pName, pEntry->streamId);
|
||||
|
||||
code = mndProcessStreamCheckpointTrans(pMnode, ps, pEntry->checkpointId);
|
||||
|
@ -1367,7 +1368,7 @@ static int32_t mndProcessStreamCheckpointInCandid(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMDropStreamReq dropReq = {0};
|
||||
|
@ -1399,7 +1400,7 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
// check if it is conflict with other trans in both sourceDb and targetDb.
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_DROP_NAME, true);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_DROP_NAME, true);
|
||||
if (conflict) {
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
tFreeMDropStreamReq(&dropReq);
|
||||
|
@ -1451,6 +1452,13 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// kill the related checkpoint trans
|
||||
int32_t transId = mndStreamGetRelTrans(pMnode, pStream->uid);
|
||||
if (transId != 0) {
|
||||
mDebug("drop active related transId:%d due to stream:%s dropped", transId, pStream->name);
|
||||
killTransImpl(pMnode, transId, pStream->sourceDb);
|
||||
}
|
||||
|
||||
removeStreamTasksInBuf(pStream, &execInfo);
|
||||
|
||||
SName name = {0};
|
||||
|
@ -1491,6 +1499,17 @@ int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
|||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// kill the related checkpoint trans
|
||||
int32_t transId = mndStreamGetRelTrans(pMnode, pStream->uid);
|
||||
if (transId != 0) {
|
||||
mDebug("drop active related transId:%d due to stream:%s dropped", transId, pStream->name);
|
||||
killTransImpl(pMnode, transId, pStream->sourceDb);
|
||||
}
|
||||
|
||||
// drop the stream obj in execInfo
|
||||
removeStreamTasksInBuf(pStream, &execInfo);
|
||||
|
||||
if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) {
|
||||
sdbRelease(pSdb, pStream);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
|
@ -1506,7 +1525,7 @@ int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
|||
}
|
||||
|
||||
int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
|
@ -1514,7 +1533,7 @@ int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams)
|
|||
}
|
||||
|
||||
int32_t numOfStreams = 0;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SStreamObj *pStream = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -1533,8 +1552,8 @@ int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams)
|
|||
}
|
||||
|
||||
static int32_t mndRetrieveStream(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
|
@ -1623,10 +1642,18 @@ static void mndCancelGetNextStream(SMnode *pMnode, void *pIter) {
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
||||
|
||||
static void setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SSDataBlock *pBlock, int32_t numOfRows) {
|
||||
static int32_t setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SSDataBlock *pBlock, int32_t numOfRows) {
|
||||
SColumnInfoData *pColInfo;
|
||||
int32_t cols = 0;
|
||||
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
|
||||
STaskStatusEntry *pe = taosHashGet(execInfo.pTaskMap, &id, sizeof(id));
|
||||
if (pe == NULL) {
|
||||
mError("task:0x%" PRIx64 " not exists in vnode, no valid status/stage info", id.taskId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// stream name
|
||||
char streamName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(streamName, mndGetDbStr(pStream->name), sizeof(streamName));
|
||||
|
@ -1677,14 +1704,7 @@ static void setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SSDat
|
|||
colDataSetVal(pColInfo, numOfRows, (const char *)level, false);
|
||||
|
||||
// status
|
||||
char status[20 + VARSTR_HEADER_SIZE] = {0};
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
|
||||
STaskStatusEntry *pe = taosHashGet(execInfo.pTaskMap, &id, sizeof(id));
|
||||
if (pe == NULL) {
|
||||
mError("task:0x%" PRIx64 " not exists in vnode, no valid status/stage info", id.taskId);
|
||||
return;
|
||||
}
|
||||
char status[20 + VARSTR_HEADER_SIZE] = {0};
|
||||
|
||||
const char *pStatus = streamTaskGetStatusStr(pe->status);
|
||||
STR_TO_VARSTR(status, pStatus);
|
||||
|
@ -1708,7 +1728,7 @@ static void setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SSDat
|
|||
colDataSetVal(pColInfo, numOfRows, (const char *)vbuf, false);
|
||||
|
||||
// output queue
|
||||
// sprintf(buf, queueInfoStr, pe->outputQUsed, pe->outputRate);
|
||||
// sprintf(buf, queueInfoStr, pe->outputQUsed, pe->outputRate);
|
||||
// STR_TO_VARSTR(vbuf, buf);
|
||||
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
|
@ -1727,6 +1747,8 @@ static void setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SSDat
|
|||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataSetVal(pColInfo, numOfRows, (const char *)vbuf, false);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t getNumOfTasks(SArray *pTaskList) {
|
||||
|
@ -1742,8 +1764,8 @@ static int32_t getNumOfTasks(SArray *pTaskList) {
|
|||
}
|
||||
|
||||
static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rowsCapacity) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
|
@ -1768,8 +1790,10 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock
|
|||
int32_t numOfLevels = taosArrayGetSize(pLevel);
|
||||
for (int32_t j = 0; j < numOfLevels; j++) {
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
setTaskAttrInResBlock(pStream, pTask, pBlock, numOfRows);
|
||||
numOfRows++;
|
||||
int32_t code = setTaskAttrInResBlock(pStream, pTask, pBlock, numOfRows);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
numOfRows++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1800,7 +1824,8 @@ static int32_t mndPauseStreamTask(SMnode *pMnode, STrans *pTrans, SStreamTask *p
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
mDebug("pause node:%d, epset:%d", pTask->info.nodeId, epset.numOfEps);
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1838,7 +1863,7 @@ int32_t mndPauseAllStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStre
|
|||
}
|
||||
|
||||
if (atomic_load_8(&pTask->status.taskStatus) != TASK_STATUS__PAUSE) {
|
||||
atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus);
|
||||
atomic_store_8(&pTask->status.statusBackup, pTask->status.taskStatus);
|
||||
atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__PAUSE);
|
||||
}
|
||||
}
|
||||
|
@ -1846,12 +1871,14 @@ int32_t mndPauseAllStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStre
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndPersistStreamLog(STrans *pTrans, const SStreamObj *pStream, int8_t status) {
|
||||
SStreamObj streamObj = {0};
|
||||
memcpy(streamObj.name, pStream->name, TSDB_STREAM_FNAME_LEN);
|
||||
streamObj.status = status;
|
||||
static int32_t mndPersistStreamLog(STrans *pTrans, SStreamObj *pStream, int8_t status) {
|
||||
// SStreamObj streamObj = {0};
|
||||
// memcpy(streamObj.name, pStream->name, TSDB_STREAM_FNAME_LEN);
|
||||
taosWLockLatch(&pStream->lock);
|
||||
pStream->status = status;
|
||||
SSdbRaw *pCommitRaw = mndStreamActionEncode(pStream);
|
||||
|
||||
SSdbRaw *pCommitRaw = mndStreamActionEncode(&streamObj);
|
||||
taosWUnLockLatch(&pStream->lock);
|
||||
if (pCommitRaw == NULL) return -1;
|
||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("stream trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
|
@ -1862,7 +1889,7 @@ static int32_t mndPersistStreamLog(STrans *pTrans, const SStreamObj *pStream, in
|
|||
}
|
||||
|
||||
static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMPauseStreamReq pauseReq = {0};
|
||||
|
@ -1894,7 +1921,7 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
// check if it is conflict with other trans in both sourceDb and targetDb.
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_PAUSE_NAME, true);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_PAUSE_NAME, true);
|
||||
if (conflict) {
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
return -1;
|
||||
|
@ -1966,7 +1993,7 @@ static int32_t mndResumeStreamTask(STrans *pTrans, SMnode *pMnode, SStreamTask *
|
|||
pReq->streamId = pTask->id.streamId;
|
||||
pReq->igUntreated = igUntreated;
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1996,7 +2023,7 @@ int32_t mndResumeAllStreamTasks(STrans *pTrans, SMnode *pMnode, SStreamObj *pStr
|
|||
}
|
||||
|
||||
if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__PAUSE) {
|
||||
atomic_store_8(&pTask->status.taskStatus, pTask->status.keepTaskStatus);
|
||||
atomic_store_8(&pTask->status.taskStatus, pTask->status.statusBackup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2004,7 +2031,7 @@ int32_t mndResumeAllStreamTasks(STrans *pTrans, SMnode *pMnode, SStreamObj *pStr
|
|||
}
|
||||
|
||||
static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMResumeStreamReq pauseReq = {0};
|
||||
|
@ -2037,7 +2064,7 @@ static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
// check if it is conflict with other trans in both sourceDb and targetDb.
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_RESUME_NAME, true);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_RESUME_NAME, true);
|
||||
if (conflict) {
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
return -1;
|
||||
|
@ -2122,7 +2149,7 @@ static int32_t doBuildStreamTaskUpdateMsg(void **pBuf, int32_t *pLen, SVgroupCha
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, tlen);
|
||||
tEncodeStreamTaskUpdateMsg(&encoder, &req);
|
||||
|
@ -2189,7 +2216,7 @@ static int32_t createStreamUpdateTrans(SStreamObj *pStream, SVgroupChangeInfo *p
|
|||
for (int32_t k = 0; k < numOfTasks; ++k) {
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, k);
|
||||
|
||||
void * pBuf = NULL;
|
||||
void *pBuf = NULL;
|
||||
int32_t len = 0;
|
||||
streamTaskUpdateEpsetInfo(pTask, pInfo->pUpdateNodeList);
|
||||
doBuildStreamTaskUpdateMsg(&pBuf, &len, pInfo, pTask->info.nodeId, &pTask->id, pTrans->id);
|
||||
|
@ -2268,8 +2295,8 @@ static SVgroupChangeInfo mndFindChangedNodeInfo(SMnode *pMnode, const SArray *pP
|
|||
}
|
||||
|
||||
static SArray *mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void * pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
|
||||
*allReady = true;
|
||||
|
@ -2337,23 +2364,22 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
STrans *pTrans = NULL;
|
||||
|
||||
// conflict check for nodeUpdate trans, here we randomly chose one stream to add into the trans pool
|
||||
while(1) {
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_TASK_UPDATE_NAME, false);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_TASK_UPDATE_NAME, false);
|
||||
sdbRelease(pSdb, pStream);
|
||||
|
||||
if (conflict) {
|
||||
mWarn("nodeUpdate trans in progress, current nodeUpdate ignored");
|
||||
mError("nodeUpdate conflict with other trans, current nodeUpdate ignored");
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
|
@ -2415,9 +2441,9 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
}
|
||||
|
||||
static SArray *extractNodeListFromStream(SMnode *pMnode) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
SHashObj *pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
while (1) {
|
||||
|
@ -2464,9 +2490,9 @@ static SArray *extractNodeListFromStream(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
static void doExtractTasksFromStream(SMnode *pMnode) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -2518,7 +2544,7 @@ int32_t removeExpirednodeEntryAndTask(SArray *pNodeSnapshot) {
|
|||
|
||||
int32_t numOfTask = taosArrayGetSize(execInfo.pTaskList);
|
||||
for (int32_t i = 0; i < numOfTask; ++i) {
|
||||
STaskId * pId = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskId *pId = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
|
||||
if (pEntry->nodeId == SNODE_HANDLE) continue;
|
||||
|
@ -2561,14 +2587,22 @@ int32_t removeExpirednodeEntryAndTask(SArray *pNodeSnapshot) {
|
|||
|
||||
// kill all trans in the dst DB
|
||||
static void killAllCheckpointTrans(SMnode *pMnode, SVgroupChangeInfo *pChangeInfo) {
|
||||
mDebug("start to clear checkpoints in all Dbs");
|
||||
|
||||
void *pIter = NULL;
|
||||
while ((pIter = taosHashIterate(pChangeInfo->pDBMap, pIter)) != NULL) {
|
||||
char *pDb = (char *)pIter;
|
||||
|
||||
size_t len = 0;
|
||||
void * pKey = taosHashGetKey(pDb, &len);
|
||||
killActiveCheckpointTrans(pMnode, pKey, len);
|
||||
void *pKey = taosHashGetKey(pDb, &len);
|
||||
char *p = strndup(pKey, len);
|
||||
|
||||
mDebug("clear checkpoint trans in Db:%s", p);
|
||||
doKillCheckpointTrans(pMnode, pKey, len);
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
|
||||
mDebug("complete clear checkpoints in Dbs");
|
||||
}
|
||||
|
||||
// this function runs by only one thread, so it is not multi-thread safe
|
||||
|
@ -2623,7 +2657,7 @@ static int32_t mndProcessNodeCheckReq(SRpcMsg *pMsg) {
|
|||
execInfo.pNodeList = pNodeSnapshot;
|
||||
execInfo.ts = ts;
|
||||
} else {
|
||||
mDebug("unexpect code during create nodeUpdate trans, code:%s", tstrerror(code));
|
||||
mError("unexpected code during create nodeUpdate trans, code:%s", tstrerror(code));
|
||||
taosArrayDestroy(pNodeSnapshot);
|
||||
}
|
||||
} else {
|
||||
|
@ -2646,7 +2680,7 @@ typedef struct SMStreamNodeCheckMsg {
|
|||
|
||||
static int32_t mndProcessNodeCheck(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2670,7 +2704,7 @@ void saveStreamTasksInfo(SStreamObj *pStream, SStreamExecInfo *pExecNode) {
|
|||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
void * p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
void *p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
if (p == NULL) {
|
||||
STaskStatusEntry entry = {0};
|
||||
streamTaskStatusInit(&entry, pTask);
|
||||
|
@ -2694,7 +2728,7 @@ void removeStreamTasksInBuf(SStreamObj *pStream, SStreamExecInfo *pExecNode) {
|
|||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
void * p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
void *p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
if (p != NULL) {
|
||||
taosHashRemove(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
|
||||
|
@ -2767,8 +2801,8 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) {
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(pReq);
|
||||
|
@ -2812,7 +2846,18 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) {
|
|||
return TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
int32_t killActiveCheckpointTrans(SMnode *pMnode, const char *pDBName, size_t len) {
|
||||
void killTransImpl(SMnode *pMnode, int32_t transId, const char *pDbName) {
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
||||
if (pTrans != NULL) {
|
||||
mInfo("kill active transId:%d in Db:%s", transId, pDbName);
|
||||
mndKillTrans(pMnode, pTrans);
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
} else {
|
||||
mError("failed to acquire trans in Db:%s, transId:%d", pDbName, transId);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t doKillCheckpointTrans(SMnode *pMnode, const char *pDBName, size_t len) {
|
||||
// data in the hash table will be removed automatically, no need to remove it here.
|
||||
SStreamTransInfo *pTransInfo = taosHashGet(execInfo.transMgmt.pDBTrans, pDBName, len);
|
||||
if (pTransInfo == NULL) {
|
||||
|
@ -2825,37 +2870,23 @@ int32_t killActiveCheckpointTrans(SMnode *pMnode, const char *pDBName, size_t le
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, pTransInfo->transId);
|
||||
if (pTrans != NULL) {
|
||||
char* pDupDBName = strndup(pDBName, len);
|
||||
mInfo("kill checkpoint transId:%d in Db:%s", pTransInfo->transId, pDupDBName);
|
||||
taosMemoryFree(pDupDBName);
|
||||
|
||||
mndKillTrans(pMnode, pTrans);
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
}
|
||||
char *pDupDBName = strndup(pDBName, len);
|
||||
killTransImpl(pMnode, pTransInfo->transId, pDupDBName);
|
||||
taosMemoryFree(pDupDBName);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mndResetStatusFromCheckpoint(SMnode *pMnode, int64_t streamId, int32_t transId) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
||||
if (pTrans != NULL) {
|
||||
mInfo("kill checkpoint transId:%d to reset task status", transId);
|
||||
mndKillTrans(pMnode, pTrans);
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
} else {
|
||||
mError("failed to acquire checkpoint trans:%d", transId);
|
||||
}
|
||||
killTransImpl(pMnode, transId, "");
|
||||
|
||||
SStreamObj *pStream = mndGetStreamObj(pMnode, streamId);
|
||||
if (pStream == NULL) {
|
||||
code = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
mError("failed to acquire the streamObj:0x%" PRIx64 " to reset checkpoint, may have been dropped", pStream->uid);
|
||||
} else {
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_TASK_RESET_NAME, false);
|
||||
bool conflict = mndStreamTransConflictCheck(pMnode, pStream->uid, MND_STREAM_TASK_RESET_NAME, false);
|
||||
if (conflict) {
|
||||
mError("stream:%s other trans exists in DB:%s, dstTable:%s failed to start reset-status trans", pStream->name,
|
||||
pStream->sourceDb, pStream->targetSTbName);
|
||||
|
@ -2886,38 +2917,38 @@ static SStreamTask *mndGetStreamTask(STaskId *pId, SStreamObj *pStream) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
// if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
// if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
// int32_t numOfReady = 0;
|
||||
// int32_t numOfTotal = 0;
|
||||
// for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
// STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
// if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
// numOfTotal++;
|
||||
// static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
// if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
// if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
// int32_t numOfReady = 0;
|
||||
// int32_t numOfTotal = 0;
|
||||
// for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
// STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
// if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
// numOfTotal++;
|
||||
//
|
||||
// if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
// STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
// if (pEntry->status == TASK_STATUS__READY) {
|
||||
// numOfReady++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
// STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
// if (pEntry->status == TASK_STATUS__READY) {
|
||||
// numOfReady++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (numOfReady > 0) {
|
||||
// mDebug("stream:0x%" PRIx64
|
||||
// " %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history task",
|
||||
// pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (numOfReady > 0) {
|
||||
// mDebug("stream:0x%" PRIx64
|
||||
// " %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history
|
||||
// task", pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// currently only handle the sink task
|
||||
// 1. sink task, drop related fill-history task msg is missing
|
||||
|
@ -2947,7 +2978,7 @@ static int32_t mndDropRelatedFillhistoryTask(SMnode *pMnode, STaskStatusEntry *p
|
|||
|
||||
mDebug("build and send drop related fill-history task for task:0x%x", pTask->id.taskId);
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3000,11 +3031,11 @@ static void updateStageInfo(STaskStatusEntry *pTaskEntry, int64_t stage) {
|
|||
}
|
||||
|
||||
int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamHbMsg req = {0};
|
||||
|
||||
bool checkpointFailed = false;
|
||||
int64_t activeCheckpointId = 0;
|
||||
int64_t checkpointId = 0;
|
||||
int64_t streamId = 0;
|
||||
int32_t transId = 0;
|
||||
|
||||
|
@ -3066,14 +3097,17 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
streamTaskStatusCopy(pTaskEntry, p);
|
||||
if (p->activeCheckpointId != 0) {
|
||||
if (activeCheckpointId != 0) {
|
||||
ASSERT(activeCheckpointId == p->activeCheckpointId);
|
||||
if (p->checkpointId != 0) {
|
||||
if (checkpointId != 0) {
|
||||
ASSERT(checkpointId == p->checkpointId);
|
||||
} else {
|
||||
activeCheckpointId = p->activeCheckpointId;
|
||||
checkpointId = p->checkpointId;
|
||||
}
|
||||
|
||||
if (p->checkpointFailed) {
|
||||
mError("stream task:0x%" PRIx64 " checkpointId:%" PRIx64 " transId:%d failed, kill it", p->id.taskId,
|
||||
p->checkpointId, p->chkpointTransId);
|
||||
|
||||
checkpointFailed = p->checkpointFailed;
|
||||
streamId = p->id.streamId;
|
||||
transId = p->chkpointTransId;
|
||||
|
@ -3090,35 +3124,22 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
|
||||
if (p->status != TASK_STATUS__READY) {
|
||||
mDebug("received s-task:0x%" PRIx64 " not in ready status:%s", p->id.taskId, streamTaskGetStatusStr(p->status));
|
||||
|
||||
// if (p->status == TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
// bool drop = needDropRelatedFillhistoryTask(pTaskEntry, &execInfo);
|
||||
// if (drop) {
|
||||
// SStreamObj *pStreamObj = mndGetStreamObj(pMnode, pTaskEntry->id.streamId);
|
||||
// if (pStreamObj == NULL) {
|
||||
// mError("failed to acquire the streamObj:0x%" PRIx64 " it may have been dropped", pStreamObj->uid);
|
||||
// } else {
|
||||
// mndDropRelatedFillhistoryTask(pMnode, pTaskEntry, pStreamObj);
|
||||
// mndReleaseStream(pMnode, pStreamObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// current checkpoint is failed, rollback from the checkpoint trans
|
||||
// kill the checkpoint trans and then set all tasks status to be normal
|
||||
if (checkpointFailed && activeCheckpointId != 0) {
|
||||
if (checkpointFailed && checkpointId != 0) {
|
||||
bool allReady = true;
|
||||
SArray *p = mndTakeVgroupSnapshot(pMnode, &allReady);
|
||||
taosArrayDestroy(p);
|
||||
|
||||
if (allReady || snodeChanged) {
|
||||
// if the execInfo.activeCheckpoint == 0, the checkpoint is restoring from wal
|
||||
mInfo("checkpointId:%" PRId64 " failed, issue task-reset trans to reset all tasks status", activeCheckpointId);
|
||||
mInfo("checkpointId:%" PRId64 " failed, issue task-reset trans to reset all tasks status", checkpointId);
|
||||
mndResetStatusFromCheckpoint(pMnode, streamId, transId);
|
||||
} else {
|
||||
mInfo("not all vgroups are ready, wait for next HB from stream tasks");
|
||||
mInfo("not all vgroups are ready, wait for next HB from stream tasks to reset the task status");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3132,9 +3153,10 @@ void freeCheckpointCandEntry(void *param) {
|
|||
SCheckpointCandEntry *pEntry = param;
|
||||
taosMemoryFreeClear(pEntry->pName);
|
||||
}
|
||||
|
||||
SStreamObj *mndGetStreamObj(SMnode *pMnode, int64_t streamId) {
|
||||
void * pIter = NULL;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
while ((pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream)) != NULL) {
|
||||
|
|
|
@ -65,7 +65,7 @@ int32_t clearFinishedTrans(SMnode* pMnode) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool streamTransConflictOtherTrans(SMnode* pMnode, int64_t streamUid, const char* pTransName, bool lock) {
|
||||
bool mndStreamTransConflictCheck(SMnode* pMnode, int64_t streamUid, const char* pTransName, bool lock) {
|
||||
if (lock) {
|
||||
taosThreadMutexLock(&execInfo.lock);
|
||||
}
|
||||
|
@ -89,9 +89,10 @@ bool streamTransConflictOtherTrans(SMnode* pMnode, int64_t streamUid, const char
|
|||
}
|
||||
|
||||
if (strcmp(tInfo.name, MND_STREAM_CHECKPOINT_NAME) == 0) {
|
||||
if (strcmp(pTransName, MND_STREAM_DROP_NAME) != 0) {
|
||||
if ((strcmp(pTransName, MND_STREAM_DROP_NAME) != 0) && (strcmp(pTransName, MND_STREAM_TASK_RESET_NAME) != 0)) {
|
||||
mWarn("conflict with other transId:%d streamUid:0x%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
tInfo.name);
|
||||
terrno = TSDB_CODE_MND_TRANS_CONFLICT;
|
||||
return true;
|
||||
} else {
|
||||
mDebug("not conflict with checkpoint trans, name:%s, continue create trans", pTransName);
|
||||
|
@ -100,6 +101,7 @@ bool streamTransConflictOtherTrans(SMnode* pMnode, int64_t streamUid, const char
|
|||
(strcmp(tInfo.name, MND_STREAM_TASK_RESET_NAME) == 0)) {
|
||||
mWarn("conflict with other transId:%d streamUid:0x%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
tInfo.name);
|
||||
terrno = TSDB_CODE_MND_TRANS_CONFLICT;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -113,6 +115,30 @@ bool streamTransConflictOtherTrans(SMnode* pMnode, int64_t streamUid, const char
|
|||
return false;
|
||||
}
|
||||
|
||||
int32_t mndStreamGetRelTrans(SMnode* pMnode, int64_t streamUid) {
|
||||
taosThreadMutexLock(&execInfo.lock);
|
||||
int32_t num = taosHashGetSize(execInfo.transMgmt.pDBTrans);
|
||||
if (num <= 0) {
|
||||
taosThreadMutexUnlock(&execInfo.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
clearFinishedTrans(pMnode);
|
||||
SStreamTransInfo* pEntry = taosHashGet(execInfo.transMgmt.pDBTrans, &streamUid, sizeof(streamUid));
|
||||
if (pEntry != NULL) {
|
||||
SStreamTransInfo tInfo = *pEntry;
|
||||
taosThreadMutexUnlock(&execInfo.lock);
|
||||
|
||||
if (strcmp(tInfo.name, MND_STREAM_CHECKPOINT_NAME) == 0 || strcmp(tInfo.name, MND_STREAM_TASK_UPDATE_NAME) == 0) {
|
||||
return tInfo.transId;
|
||||
}
|
||||
} else {
|
||||
taosThreadMutexUnlock(&execInfo.lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndAddtoCheckpointWaitingList(SStreamObj* pStream, int64_t checkpointId) {
|
||||
SCheckpointCandEntry* pEntry = taosHashGet(execInfo.transMgmt.pWaitingList, &pStream->uid, sizeof(pStream->uid));
|
||||
if (pEntry == NULL) {
|
||||
|
|
|
@ -747,7 +747,7 @@ static int32_t mndCheckConsumer(SRpcMsg *pMsg, SHashObj* rebSubHash) {
|
|||
int32_t hbStatus = atomic_add_fetch_32(&pConsumer->hbStatus, 1);
|
||||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
mInfo("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", createTime:%" PRId64 ", hbstatus:%d",
|
||||
mDebug("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", createTime:%" PRId64 ", hbstatus:%d",
|
||||
pConsumer->consumerId, status, mndConsumerStatusName(status), pConsumer->subscribeTime, pConsumer->createTime,
|
||||
hbStatus);
|
||||
|
||||
|
|
|
@ -1831,10 +1831,12 @@ static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDb
|
|||
int32_t newDnodeId) {
|
||||
mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
|
||||
|
||||
// assoc dnode
|
||||
SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
|
||||
pVgroup->replica++;
|
||||
pGid->dnodeId = newDnodeId;
|
||||
pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
|
||||
pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
|
||||
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
|
||||
if (pVgRaw == NULL) return -1;
|
||||
|
@ -1844,10 +1846,20 @@ static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDb
|
|||
}
|
||||
(void)sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
|
||||
|
||||
// learner
|
||||
for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId) != 0) return -1;
|
||||
}
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid) != 0) return -1;
|
||||
|
||||
// voter
|
||||
pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if (mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId) != 0) return -1;
|
||||
for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId) != 0) return -1;
|
||||
}
|
||||
|
||||
// confirm
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -61,6 +61,7 @@ class MndTestTrans2 : public ::testing::Test {
|
|||
static SMsgCb msgCb = {0};
|
||||
msgCb.reportStartupFp = reportStartup;
|
||||
msgCb.sendReqFp = sendReq;
|
||||
msgCb.sendSyncReqFp = sendSyncReq;
|
||||
msgCb.sendRspFp = sendRsp;
|
||||
msgCb.queueFps[SYNC_QUEUE] = putToQueue;
|
||||
msgCb.queueFps[WRITE_QUEUE] = putToQueue;
|
||||
|
|
|
@ -91,9 +91,7 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t nextProcessVer
|
|||
pTask->id.idStr, pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer);
|
||||
}
|
||||
|
||||
char *p = NULL;
|
||||
streamTaskGetStatus(pTask, &p);
|
||||
|
||||
char* p = streamTaskGetStatus(pTask)->name;
|
||||
if (pTask->info.fillHistory) {
|
||||
sndInfo("vgId:%d expand stream task, s-task:%s, checkpointId:%" PRId64 " checkpointVer:%" PRId64
|
||||
" nextProcessVer:%" PRId64
|
||||
|
@ -147,7 +145,7 @@ FAIL:
|
|||
}
|
||||
|
||||
int32_t sndInit(SSnode *pSnode) {
|
||||
tqStreamTaskResetStatus(pSnode->pMeta);
|
||||
streamMetaResetTaskStatus(pSnode->pMeta);
|
||||
streamMetaStartAllTasks(pSnode->pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
@ -195,7 +193,7 @@ int32_t sndProcessWriteMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg *pRsp) {
|
|||
case TDMT_STREAM_TASK_DEPLOY: {
|
||||
void * pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||
return tqStreamTaskProcessDeployReq(pSnode->pMeta, -1, pReq, len, true, true);
|
||||
return tqStreamTaskProcessDeployReq(pSnode->pMeta, &pSnode->msgCb,pMsg->info.conn.applyIndex, pReq, len, true, true);
|
||||
}
|
||||
|
||||
case TDMT_STREAM_TASK_DROP:
|
||||
|
@ -204,6 +202,10 @@ int32_t sndProcessWriteMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg *pRsp) {
|
|||
return tqStreamTaskProcessUpdateReq(pSnode->pMeta, &pSnode->msgCb, pMsg, true);
|
||||
case TDMT_VND_STREAM_TASK_RESET:
|
||||
return tqStreamTaskProcessTaskResetReq(pSnode->pMeta, pMsg);
|
||||
case TDMT_STREAM_TASK_PAUSE:
|
||||
return tqStreamTaskProcessTaskPauseReq(pSnode->pMeta, pMsg->pCont);
|
||||
case TDMT_STREAM_TASK_RESUME:
|
||||
return tqStreamTaskProcessTaskResumeReq(pSnode->pMeta, pMsg->info.conn.applyIndex, pMsg->pCont, false);
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,8 @@ void tsdbReaderSetNotifyCb(STsdbReader* pReader, TsdReaderNotifyCbFn not
|
|||
|
||||
int32_t tsdbReuseCacherowsReader(void *pReader, void *pTableIdList, int32_t numOfTables);
|
||||
int32_t tsdbCacherowsReaderOpen(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr);
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray* pFuncTypeList);
|
||||
int32_t tsdbRetrieveCacheRows(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUids);
|
||||
void *tsdbCacherowsReaderClose(void *pReader);
|
||||
|
|
|
@ -145,7 +145,7 @@ int32_t tqOffsetCommitFile(STqOffsetStore* pStore);
|
|||
|
||||
// tqSink
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr);
|
||||
const char* pIdStr, bool newSubTableRule);
|
||||
void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data);
|
||||
|
||||
// tqOffset
|
||||
|
@ -164,7 +164,7 @@ int32_t setDstTableDataPayload(uint64_t suid, const STSchema* pTSchema, int32_t
|
|||
int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, const char* id);
|
||||
|
||||
SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols,
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray);
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray, bool newSubTableRule);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -703,7 +703,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
code = tqBuildDeleteReq(pSma->pVnode->pTq, NULL, output, &deleteReq, "");
|
||||
code = tqBuildDeleteReq(pSma->pVnode->pTq, NULL, output, &deleteReq, "", true);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tdRSmaProcessDelReq(pSma, suid, pItem->level, &deleteReq);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
@ -188,7 +188,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
if (pDataBlock->info.type == STREAM_DELETE_RESULT) {
|
||||
pDeleteReq->suid = suid;
|
||||
pDeleteReq->deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "");
|
||||
code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "", true);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
continue;
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
SSubmitTbData tbData = {.suid = suid, .uid = 0, .sver = pTSchema->version, .flags = SUBMIT_REQ_AUTO_CREATE_TABLE,};
|
||||
|
||||
int32_t cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1;
|
||||
tbData.pCreateTbReq = buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray);
|
||||
tbData.pCreateTbReq = buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray, true);
|
||||
|
||||
{
|
||||
uint64_t groupId = pDataBlock->info.id.groupId;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
// 0: not init
|
||||
// 1: already inited
|
||||
// 2: wait to be inited or cleaup
|
||||
// 2: wait to be inited or cleanup
|
||||
static int32_t tqInitialize(STQ* pTq);
|
||||
|
||||
static FORCE_INLINE bool tqIsHandleExec(STqHandle* pHandle) { return TMQ_HANDLE_STATUS_EXEC == pHandle->status; }
|
||||
|
@ -136,6 +136,7 @@ void tqClose(STQ* pTq) {
|
|||
taosMemoryFree(pTq->path);
|
||||
tqMetaClose(pTq);
|
||||
streamMetaClose(pTq->pStreamMeta);
|
||||
|
||||
qDebug("end to close tq");
|
||||
taosMemoryFree(pTq);
|
||||
}
|
||||
|
@ -727,8 +728,6 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t nextProcessVer) {
|
|||
return code;
|
||||
}
|
||||
|
||||
streamTaskOpenAllUpstreamInput(pTask);
|
||||
|
||||
if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
STaskId taskId = {0};
|
||||
if (pTask->info.fillHistory) {
|
||||
|
@ -842,8 +841,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t nextProcessVer) {
|
|||
pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer);
|
||||
}
|
||||
|
||||
char* p = NULL;
|
||||
streamTaskGetStatus(pTask, &p);
|
||||
char* p = streamTaskGetStatus(pTask)->name;
|
||||
|
||||
if (pTask->info.fillHistory) {
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpointId:%" PRId64 " checkpointVer:%" PRId64
|
||||
|
@ -873,7 +871,8 @@ int32_t tqProcessTaskCheckRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
}
|
||||
|
||||
int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
return tqStreamTaskProcessDeployReq(pTq->pStreamMeta, sversion, msg, msgLen, vnodeIsRoleLeader(pTq->pVnode), pTq->pVnode->restored);
|
||||
return tqStreamTaskProcessDeployReq(pTq->pStreamMeta, &pTq->pVnode->msgCb, sversion, msg, msgLen,
|
||||
vnodeIsRoleLeader(pTq->pVnode), pTq->pVnode->restored);
|
||||
}
|
||||
|
||||
static void doStartFillhistoryStep2(SStreamTask* pTask, SStreamTask* pStreamTask, STQ* pTq) {
|
||||
|
@ -932,8 +931,7 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
// do recovery step1
|
||||
const char* id = pTask->id.idStr;
|
||||
char* pStatus = NULL;
|
||||
streamTaskGetStatus(pTask, &pStatus);
|
||||
char* pStatus = streamTaskGetStatus(pTask)->name;
|
||||
|
||||
// avoid multi-thread exec
|
||||
while (1) {
|
||||
|
@ -949,7 +947,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
// let's decide which step should be executed now
|
||||
if (pTask->execInfo.step1Start == 0) {
|
||||
int64_t ts = taosGetTimestampMs();
|
||||
|
||||
pTask->execInfo.step1Start = ts;
|
||||
tqDebug("s-task:%s start scan-history stage(step 1), status:%s, step1 startTs:%" PRId64, id, pStatus, ts);
|
||||
} else {
|
||||
|
@ -990,15 +987,15 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
if (retInfo.ret == TASK_SCANHISTORY_REXEC) {
|
||||
streamReExecScanHistoryFuture(pTask, retInfo.idleTime);
|
||||
} else {
|
||||
char* p = NULL;
|
||||
ETaskStatus s = streamTaskGetStatus(pTask, &p);
|
||||
SStreamTaskState* p = streamTaskGetStatus(pTask);
|
||||
ETaskStatus s = p->state;
|
||||
|
||||
if (s == TASK_STATUS__PAUSE) {
|
||||
tqDebug("s-task:%s is paused in the step1, elapsed time:%.2fs total:%.2fs, sched-status:%d", pTask->id.idStr,
|
||||
el, pTask->execInfo.step1El, status);
|
||||
} else if (s == TASK_STATUS__STOP || s == TASK_STATUS__DROPPING) {
|
||||
tqDebug("s-task:%s status:%p not continue scan-history data, total elapsed time:%.2fs quit", pTask->id.idStr, p,
|
||||
pTask->execInfo.step1El);
|
||||
tqDebug("s-task:%s status:%p not continue scan-history data, total elapsed time:%.2fs quit", pTask->id.idStr,
|
||||
p->name, pTask->execInfo.step1El);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1038,15 +1035,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
streamMetaReleaseTask(pMeta, pStreamTask);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
// STimeWindow* pWindow = &pTask->dataRange.window;
|
||||
// ASSERT(HAS_RELATED_FILLHISTORY_TASK(pTask) || streamTaskShouldStop(pTask));
|
||||
//
|
||||
// // Not update the fill-history time window until the state transfer is completed.
|
||||
// tqDebug("s-task:%s scan-history in stream time window completed, start to handle data from WAL, startVer:%" PRId64
|
||||
// ", window:%" PRId64 " - %" PRId64,
|
||||
// id, pTask->chkInfo.nextProcessVer, pWindow->skey, pWindow->ekey);
|
||||
//
|
||||
// code = streamTaskScanHistoryDataComplete(pTask);
|
||||
}
|
||||
|
||||
atomic_store_32(&pTask->status.inScanHistorySentinel, 0);
|
||||
|
@ -1066,15 +1054,16 @@ int32_t tqProcessTaskScanHistoryFinishRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SStreamTaskRunReq* pReq = pMsg->pCont;
|
||||
|
||||
int32_t taskId = pReq->taskId;
|
||||
|
||||
if (taskId == STREAM_EXEC_EXTRACT_DATA_IN_WAL_ID) { // all tasks are extracted submit data from the wal
|
||||
// extracted submit data from wal files for all tasks
|
||||
if (pReq->reqType == STREAM_EXEC_T_EXTRACT_WAL_DATA) {
|
||||
tqScanWal(pTq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t code = tqStreamTaskProcessRunReq(pTq->pStreamMeta, pMsg, vnodeIsRoleLeader(pTq->pVnode));
|
||||
if(code == 0 && taskId > 0){
|
||||
|
||||
// let's continue scan data in the wal files
|
||||
if(code == 0 && pReq->reqType >= 0){
|
||||
tqScanWalAsync(pTq, false);
|
||||
}
|
||||
|
||||
|
@ -1094,108 +1083,11 @@ int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
}
|
||||
|
||||
int32_t tqProcessTaskPauseReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)msg;
|
||||
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d process pause req, failed to acquire task:0x%x, it may have been dropped already", pMeta->vgId,
|
||||
pReq->taskId);
|
||||
// since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s receive pause msg from mnode", pTask->id.idStr);
|
||||
streamTaskPause(pTask, pMeta);
|
||||
|
||||
SStreamTask* pHistoryTask = NULL;
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
pHistoryTask = streamMetaAcquireTask(pMeta, pTask->hTaskInfo.id.streamId, pTask->hTaskInfo.id.taskId);
|
||||
if (pHistoryTask == NULL) {
|
||||
tqError("vgId:%d process pause req, failed to acquire fill-history task:0x%" PRIx64
|
||||
", it may have been dropped already",
|
||||
pMeta->vgId, pTask->hTaskInfo.id.taskId);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
// since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s fill-history task handle paused along with related stream task", pHistoryTask->id.idStr);
|
||||
|
||||
streamTaskPause(pHistoryTask, pMeta);
|
||||
streamMetaReleaseTask(pMeta, pHistoryTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tqProcessTaskResumeImpl(STQ* pTq, SStreamTask* pTask, int64_t sversion, int8_t igUntreated) {
|
||||
int32_t vgId = pTq->pStreamMeta->vgId;
|
||||
if (pTask == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
streamTaskResume(pTask);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
|
||||
int32_t level = pTask->info.taskLevel;
|
||||
if (level == TASK_LEVEL__SINK) {
|
||||
if (status == TASK_STATUS__UNINIT) {
|
||||
}
|
||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status == TASK_STATUS__READY || status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__CK) {
|
||||
// no lock needs to secure the access of the version
|
||||
if (igUntreated && level == TASK_LEVEL__SOURCE && !pTask->info.fillHistory) {
|
||||
// discard all the data when the stream task is suspended.
|
||||
walReaderSetSkipToVersion(pTask->exec.pWalReader, sversion);
|
||||
tqDebug("vgId:%d s-task:%s resume to exec, prev paused version:%" PRId64 ", start from vnode ver:%" PRId64
|
||||
", schedStatus:%d",
|
||||
vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
|
||||
} else { // from the previous paused version and go on
|
||||
tqDebug("vgId:%d s-task:%s resume to exec, from paused ver:%" PRId64 ", vnode ver:%" PRId64 ", schedStatus:%d",
|
||||
vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
|
||||
}
|
||||
|
||||
if (level == TASK_LEVEL__SOURCE && pTask->info.fillHistory && status == TASK_STATUS__SCAN_HISTORY) {
|
||||
streamStartScanHistoryAsync(pTask, igUntreated);
|
||||
} else if (level == TASK_LEVEL__SOURCE && (streamQueueGetNumOfItems(pTask->inputq.queue) == 0)) {
|
||||
tqScanWalAsync(pTq, false);
|
||||
} else {
|
||||
streamSchedExec(pTask);
|
||||
}
|
||||
} else if (status == TASK_STATUS__UNINIT) {
|
||||
// todo: fill-history task init ?
|
||||
if (pTask->info.fillHistory == 0) {
|
||||
EStreamTaskEvent event = /*HAS_RELATED_FILLHISTORY_TASK(pTask) ? TASK_EVENT_INIT_STREAM_SCANHIST : */TASK_EVENT_INIT;
|
||||
streamTaskHandleEvent(pTask->status.pSM, event);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||
return 0;
|
||||
return tqStreamTaskProcessTaskPauseReq(pTq->pStreamMeta, msg);
|
||||
}
|
||||
|
||||
int32_t tqProcessTaskResumeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SVResumeStreamTaskReq* pReq = (SVResumeStreamTaskReq*)msg;
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->streamId, pReq->taskId);
|
||||
int32_t code = tqProcessTaskResumeImpl(pTq, pTask, sversion, pReq->igUntreated);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
STaskId* pHTaskId = &pTask->hTaskInfo.id;
|
||||
SStreamTask* pHistoryTask = streamMetaAcquireTask(pTq->pStreamMeta, pHTaskId->streamId, pHTaskId->taskId);
|
||||
if (pHistoryTask) {
|
||||
code = tqProcessTaskResumeImpl(pTq, pHistoryTask, sversion, pReq->igUntreated);
|
||||
}
|
||||
|
||||
return code;
|
||||
return tqStreamTaskProcessTaskResumeReq(pTq, sversion, msg, true);
|
||||
}
|
||||
|
||||
int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
|
@ -1218,6 +1110,19 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
pRsp->info.handle = NULL;
|
||||
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, len);
|
||||
if (tDecodeStreamCheckpointSourceReq(&decoder, &req) < 0) {
|
||||
code = TSDB_CODE_MSG_DECODE_ERROR;
|
||||
tDecoderClear(&decoder);
|
||||
tqError("vgId:%d failed to decode checkpoint-source msg, code:%s", vgId, tstrerror(code));
|
||||
SRpcMsg rsp = {0};
|
||||
buildCheckpointSourceRsp(&req, &pMsg->info, &rsp, 0);
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return code;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
if (!vnodeIsRoleLeader(pTq->pVnode)) {
|
||||
tqDebug("vgId:%d not leader, ignore checkpoint-source msg, s-task:0x%x", vgId, req.taskId);
|
||||
SRpcMsg rsp = {0};
|
||||
|
@ -1234,19 +1139,6 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, len);
|
||||
if (tDecodeStreamCheckpointSourceReq(&decoder, &req) < 0) {
|
||||
code = TSDB_CODE_MSG_DECODE_ERROR;
|
||||
tDecoderClear(&decoder);
|
||||
tqError("vgId:%d failed to decode checkpoint-source msg, code:%s", vgId, tstrerror(code));
|
||||
SRpcMsg rsp = {0};
|
||||
buildCheckpointSourceRsp(&req, &pMsg->info, &rsp, 0);
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return code;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, req.streamId, req.taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d failed to find s-task:0x%x, ignore checkpoint msg. it may have been destroyed already", vgId,
|
||||
|
@ -1275,7 +1167,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
// todo save the checkpoint failed info
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask)->state;
|
||||
|
||||
if (status == TASK_STATUS__HALT || status == TASK_STATUS__PAUSE) {
|
||||
tqError("s-task:%s not ready for checkpoint, since it is halt, ignore this checkpoint:%" PRId64 ", set it failure",
|
||||
|
@ -1362,14 +1254,8 @@ int32_t tqProcessTaskDropHTask(STQ* pTq, SRpcMsg* pMsg) {
|
|||
}
|
||||
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
// if (status == TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
// streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE);
|
||||
// }
|
||||
|
||||
SStreamTaskId id = {.streamId = pTask->hTaskInfo.id.streamId, .taskId = pTask->hTaskInfo.id.taskId};
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &id);
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
// clear the scheduler status
|
||||
|
|
|
@ -596,10 +596,12 @@ static int32_t doSetVal(SColumnInfoData* pColumnInfoData, int32_t rowIndex, SCol
|
|||
|
||||
if (IS_STR_DATA_TYPE(pColVal->type)) {
|
||||
char val[65535 + 2] = {0};
|
||||
if (pColVal->value.pData != NULL) {
|
||||
memcpy(varDataVal(val), pColVal->value.pData, pColVal->value.nData);
|
||||
if(COL_VAL_IS_VALUE(pColVal)){
|
||||
if (pColVal->value.pData != NULL) {
|
||||
memcpy(varDataVal(val), pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
varDataSetLen(val, pColVal->value.nData);
|
||||
code = colDataSetVal(pColumnInfoData, rowIndex, val, !COL_VAL_IS_VALUE(pColVal));
|
||||
code = colDataSetVal(pColumnInfoData, rowIndex, val, false);
|
||||
} else {
|
||||
colDataSetNULL(pColumnInfoData, rowIndex);
|
||||
}
|
||||
|
@ -869,22 +871,8 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
|||
sourceIdx++;
|
||||
} else if (pCol->cid == pColData->info.colId) {
|
||||
tColDataGetValue(pCol, i, &colVal);
|
||||
|
||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||
if (colVal.value.pData != NULL) {
|
||||
char val[65535 + 2];
|
||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||
varDataSetLen(val, colVal.value.nData);
|
||||
if (colDataSetVal(pColData, curRow - lastRow, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
} else {
|
||||
colDataSetNULL(pColData, curRow - lastRow);
|
||||
}
|
||||
} else {
|
||||
if (colDataSetVal(pColData, curRow - lastRow, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
if(doSetVal(pColData, curRow - lastRow, &colVal) != TDB_CODE_SUCCESS){
|
||||
goto FAIL;
|
||||
}
|
||||
sourceIdx++;
|
||||
targetIdx++;
|
||||
|
@ -967,23 +955,10 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
|||
if (colVal.cid < pColData->info.colId) {
|
||||
sourceIdx++;
|
||||
} else if (colVal.cid == pColData->info.colId) {
|
||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||
if (colVal.value.pData != NULL) {
|
||||
char val[65535 + 2];
|
||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||
varDataSetLen(val, colVal.value.nData);
|
||||
if (colDataSetVal(pColData, curRow - lastRow, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
} else {
|
||||
colDataSetNULL(pColData, curRow - lastRow);
|
||||
}
|
||||
} else {
|
||||
if (colDataSetVal(pColData, curRow - lastRow, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
if(doSetVal(pColData, curRow - lastRow, &colVal) != TDB_CODE_SUCCESS){
|
||||
goto FAIL;
|
||||
}
|
||||
sourceIdx++;
|
||||
sourceIdx++;
|
||||
targetIdx++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@ static bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const ch
|
|||
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);
|
||||
int64_t gid, bool newSubTableRule);
|
||||
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr) {
|
||||
const char* pIdStr, bool newSubTableRule) {
|
||||
int32_t totalRows = pDataBlock->info.rows;
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pDataBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pDataBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
|
@ -68,6 +68,12 @@ 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) {
|
||||
buildCtbNameAddGruopId(name, groupId);
|
||||
}
|
||||
} else if (stbFullName) {
|
||||
name = buildCtbNameByGroupId(stbFullName, groupId);
|
||||
} else {
|
||||
|
@ -173,9 +179,18 @@ SArray* createDefaultTagColName() {
|
|||
}
|
||||
|
||||
void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid) {
|
||||
int64_t gid, bool newSubTableRule) {
|
||||
if (pDataBlock->info.parTbName[0]) {
|
||||
pCreateTableReq->name = taosStrdup(pDataBlock->info.parTbName);
|
||||
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);
|
||||
}else{
|
||||
pCreateTableReq->name = taosStrdup(pDataBlock->info.parTbName);
|
||||
}
|
||||
} else {
|
||||
pCreateTableReq->name = buildCtbNameByGroupId(stbFullName, gid);
|
||||
}
|
||||
|
@ -247,7 +262,7 @@ static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, S
|
|||
ASSERT(gid == *(int64_t*)pGpIdData);
|
||||
}
|
||||
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid);
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
|
||||
taosArrayPush(reqs.pArray, pCreateTbReq);
|
||||
tqDebug("s-task:%s build create table:%s msg complete", pTask->id.idStr, pCreateTbReq->name);
|
||||
|
@ -357,7 +372,8 @@ int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSDataBlock*
|
|||
int64_t suid) {
|
||||
SBatchDeleteReq deleteReq = {.suid = suid, .deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq))};
|
||||
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr);
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr,
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -411,7 +427,7 @@ bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const char* ctbNam
|
|||
}
|
||||
|
||||
SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols,
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray) {
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray, bool newSubTableRule) {
|
||||
SVCreateTbReq* pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
|
||||
if (pCreateTbReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -436,7 +452,7 @@ SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, in
|
|||
pCreateTbReq->ctb.tagName = createDefaultTagColName();
|
||||
|
||||
// set table name
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId);
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId, newSubTableRule);
|
||||
return pCreateTbReq;
|
||||
}
|
||||
|
||||
|
@ -637,6 +653,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
tqDebug("s-task:%s vgId:%d, gropuId:%" PRIu64 " datablock table name is null, set name:%s", id, vgId, groupId,
|
||||
dstTableName);
|
||||
} else {
|
||||
tstrncpy(dstTableName, pTableSinkInfo->name.data, pTableSinkInfo->name.len + 1);
|
||||
if (pTableSinkInfo->uid != 0) {
|
||||
tqDebug("s-task:%s write %d rows into groupId:%" PRIu64 " dstTable:%s(uid:%" PRIu64 ")", id, numOfRows, groupId,
|
||||
dstTableName, pTableSinkInfo->uid);
|
||||
|
@ -649,10 +666,17 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
if (dstTableName[0] == 0) {
|
||||
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) {
|
||||
buildCtbNameAddGruopId(dstTableName, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nameLen = strlen(dstTableName);
|
||||
pTableSinkInfo = taosMemoryCalloc(1, sizeof(STableSinkInfo) + nameLen);
|
||||
pTableSinkInfo = taosMemoryCalloc(1, sizeof(STableSinkInfo) + nameLen + 1);
|
||||
if (pTableSinkInfo == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -690,7 +714,7 @@ 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);
|
||||
buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
taosArrayDestroy(pTagArray);
|
||||
|
||||
if (pTableData->pCreateTbReq == NULL) {
|
||||
|
@ -719,7 +743,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t setDstTableDataPayload(uint64_t suid, const STSchema *pTSchema, int32_t blockIndex, SSDataBlock* pDataBlock,
|
||||
|
|
|
@ -24,6 +24,7 @@ static int32_t setWalReaderStartOffset(SStreamTask* pTask, int32_t vgId);
|
|||
static bool handleFillhistoryScanComplete(SStreamTask* pTask, int64_t ver);
|
||||
static bool taskReadyForDataFromWal(SStreamTask* pTask);
|
||||
static bool doPutDataIntoInputQFromWal(SStreamTask* pTask, int64_t maxVer, int32_t* numOfItems);
|
||||
static int32_t tqScanWalInFuture(STQ* pTq, int32_t numOfTasks, int32_t idleDuration);
|
||||
|
||||
// extract data blocks(submit/delete) from WAL, and add them into the input queue for all the sources tasks.
|
||||
int32_t tqScanWal(STQ* pTq) {
|
||||
|
@ -31,35 +32,82 @@ int32_t tqScanWal(STQ* pTq) {
|
|||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
int64_t st = taosGetTimestampMs();
|
||||
|
||||
while (1) {
|
||||
int32_t scan = pMeta->walScanCounter;
|
||||
tqDebug("vgId:%d continue check if data in wal are available, walScanCounter:%d", vgId, scan);
|
||||
tqDebug("vgId:%d continue to check if data in wal are available, scanCounter:%d", vgId, pMeta->scanInfo.scanCounter);
|
||||
|
||||
// check all tasks
|
||||
bool shouldIdle = true;
|
||||
doScanWalForAllTasks(pTq->pStreamMeta, &shouldIdle);
|
||||
// check all tasks
|
||||
int32_t numOfTasks = 0;
|
||||
bool shouldIdle = true;
|
||||
doScanWalForAllTasks(pMeta, &shouldIdle);
|
||||
|
||||
// if (shouldIdle) {
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t times = (--pMeta->walScanCounter);
|
||||
ASSERT(pMeta->walScanCounter >= 0);
|
||||
streamMetaWUnLock(pMeta);
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t times = (--pMeta->scanInfo.scanCounter);
|
||||
ASSERT(pMeta->scanInfo.scanCounter >= 0);
|
||||
|
||||
if (times <= 0) {
|
||||
break;
|
||||
} else {
|
||||
tqDebug("vgId:%d scan wal for stream tasks for %d times in %dms", vgId, times, SCAN_WAL_IDLE_DURATION);
|
||||
}
|
||||
// }
|
||||
|
||||
taosMsleep(SCAN_WAL_IDLE_DURATION);
|
||||
}
|
||||
numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
int64_t el = (taosGetTimestampMs() - st);
|
||||
tqDebug("vgId:%d scan wal for stream tasks completed, elapsed time:%" PRId64 " ms", vgId, el);
|
||||
|
||||
if (times > 0) {
|
||||
tqDebug("vgId:%d scan wal for stream tasks for %d times in %dms", vgId, times, SCAN_WAL_IDLE_DURATION);
|
||||
tqScanWalInFuture(pTq, numOfTasks, SCAN_WAL_IDLE_DURATION);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct SBuildScanWalMsgParam {
|
||||
STQ* pTq;
|
||||
int32_t numOfTasks;
|
||||
} SBuildScanWalMsgParam;
|
||||
|
||||
static void doStartScanWal(void* param, void* tmrId) {
|
||||
SBuildScanWalMsgParam* pParam = (SBuildScanWalMsgParam*) param;
|
||||
|
||||
int32_t vgId = pParam->pTq->pStreamMeta->vgId;
|
||||
|
||||
SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq));
|
||||
if (pRunReq == NULL) {
|
||||
taosMemoryFree(pParam);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create msg to start wal scanning to launch stream tasks, code:%s", vgId, terrstr());
|
||||
return;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d create msg to start wal scan, numOfTasks:%d, vnd restored:%d", vgId, pParam->numOfTasks,
|
||||
pParam->pTq->pVnode->restored);
|
||||
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
pRunReq->taskId = 0;
|
||||
pRunReq->reqType = STREAM_EXEC_T_EXTRACT_WAL_DATA;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(&pParam->pTq->pVnode->msgCb, STREAM_QUEUE, &msg);
|
||||
|
||||
taosMemoryFree(pParam);
|
||||
}
|
||||
|
||||
int32_t tqScanWalInFuture(STQ* pTq, int32_t numOfTasks, int32_t idleDuration) {
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
|
||||
SBuildScanWalMsgParam* pParam = taosMemoryMalloc(sizeof(SBuildScanWalMsgParam));
|
||||
|
||||
pParam->pTq = pTq;
|
||||
pParam->numOfTasks = numOfTasks;
|
||||
|
||||
tmr_h pTimer = streamTimerGetInstance();
|
||||
ASSERT(pTimer);
|
||||
|
||||
if (pMeta->scanInfo.scanTimer == NULL) {
|
||||
pMeta->scanInfo.scanTimer = taosTmrStart(doStartScanWal, idleDuration, pParam, pTimer);
|
||||
} else {
|
||||
taosTmrReset(doStartScanWal, idleDuration, pParam, pTimer, &pMeta->scanInfo.scanTimer);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
|
@ -80,23 +128,23 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
pMeta->walScanCounter += 1;
|
||||
if (pMeta->walScanCounter > MAX_REPEAT_SCAN_THRESHOLD) {
|
||||
pMeta->walScanCounter = MAX_REPEAT_SCAN_THRESHOLD;
|
||||
pMeta->scanInfo.scanCounter += 1;
|
||||
if (pMeta->scanInfo.scanCounter > MAX_REPEAT_SCAN_THRESHOLD) {
|
||||
pMeta->scanInfo.scanCounter = MAX_REPEAT_SCAN_THRESHOLD;
|
||||
}
|
||||
|
||||
if (pMeta->walScanCounter > 1) {
|
||||
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter);
|
||||
if (pMeta->scanInfo.scanCounter > 1) {
|
||||
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->scanInfo.scanCounter);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t numOfPauseTasks = pTq->pStreamMeta->numOfPausedTasks;
|
||||
int32_t numOfPauseTasks = pMeta->numOfPausedTasks;
|
||||
if (ckPause && numOfTasks == numOfPauseTasks) {
|
||||
tqDebug("vgId:%d ignore all submit, all streams had been paused, reset the walScanCounter", vgId);
|
||||
|
||||
// reset the counter value, since we do not launch the scan wal operation.
|
||||
pMeta->walScanCounter = 0;
|
||||
pMeta->scanInfo.scanCounter = 0;
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
@ -114,7 +162,8 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
|||
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
pRunReq->taskId = STREAM_EXEC_EXTRACT_DATA_IN_WAL_ID;
|
||||
pRunReq->taskId = 0;
|
||||
pRunReq->reqType = STREAM_EXEC_T_EXTRACT_WAL_DATA;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg);
|
||||
|
@ -130,15 +179,16 @@ int32_t tqStopStreamTasksAsync(STQ* pTq) {
|
|||
SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq));
|
||||
if (pRunReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create msg to stop tasks, code:%s", vgId, terrstr());
|
||||
tqError("vgId:%d failed to create msg to stop tasks async, code:%s", vgId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d create msg to stop tasks", vgId);
|
||||
tqDebug("vgId:%d create msg to stop all tasks async", vgId);
|
||||
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
pRunReq->taskId = STREAM_EXEC_STOP_ALL_TASKS_ID;
|
||||
pRunReq->taskId = 0;
|
||||
pRunReq->reqType = STREAM_EXEC_T_STOP_ALL_TASKS;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg);
|
||||
|
@ -220,16 +270,15 @@ bool taskReadyForDataFromWal(SStreamTask* pTask) {
|
|||
}
|
||||
|
||||
// not in ready state, do not handle the data from wal
|
||||
char* p = NULL;
|
||||
int32_t status = streamTaskGetStatus(pTask, &p);
|
||||
if (streamTaskGetStatus(pTask, &p) != TASK_STATUS__READY) {
|
||||
tqTrace("s-task:%s not ready for submit block in wal, status:%s", pTask->id.idStr, p);
|
||||
SStreamTaskState* pState = streamTaskGetStatus(pTask);
|
||||
if (pState->state != TASK_STATUS__READY) {
|
||||
tqTrace("s-task:%s not ready for submit block in wal, status:%s", pTask->id.idStr, pState->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// fill-history task has entered into the last phase, no need to anything
|
||||
if ((pTask->info.fillHistory == 1) && pTask->status.appendTranstateBlock) {
|
||||
ASSERT(status == TASK_STATUS__READY);
|
||||
ASSERT(pState->state == TASK_STATUS__READY);
|
||||
// the maximum version of data in the WAL has reached already, the step2 is done
|
||||
tqDebug("s-task:%s fill-history reach the maximum ver:%" PRId64 ", not scan wal anymore", pTask->id.idStr,
|
||||
pTask->dataRange.range.maxVer);
|
||||
|
@ -342,10 +391,9 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
|||
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
|
||||
char* p = NULL;
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, &p);
|
||||
if (status != TASK_STATUS__READY) {
|
||||
tqDebug("s-task:%s not ready for submit block from wal, status:%s", pTask->id.idStr, p);
|
||||
SStreamTaskState* pState = streamTaskGetStatus(pTask);
|
||||
if (pState->state != TASK_STATUS__READY) {
|
||||
tqDebug("s-task:%s not ready for submit block from wal, status:%s", pTask->id.idStr, pState->name);
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pStreamMeta, pTask);
|
||||
continue;
|
||||
|
|
|
@ -25,7 +25,6 @@ typedef struct STaskUpdateEntry {
|
|||
|
||||
int32_t tqStreamTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, bool restart) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
if (numOfTasks == 0) {
|
||||
tqDebug("vgId:%d no stream tasks existed to run", vgId);
|
||||
|
@ -42,7 +41,35 @@ int32_t tqStreamTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, bool restart) {
|
|||
tqDebug("vgId:%d start all %d stream task(s) async", vgId, numOfTasks);
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
pRunReq->taskId = restart ? STREAM_EXEC_RESTART_ALL_TASKS_ID : STREAM_EXEC_START_ALL_TASKS_ID;
|
||||
pRunReq->taskId = 0;
|
||||
pRunReq->reqType = restart ? STREAM_EXEC_T_RESTART_ALL_TASKS : STREAM_EXEC_T_START_ALL_TASKS;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(cb, STREAM_QUEUE, &msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStreamOneTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, int64_t streamId, int32_t taskId) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
if (numOfTasks == 0) {
|
||||
tqDebug("vgId:%d no stream tasks existed to run", vgId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq));
|
||||
if (pRunReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create msg to start task:0x%x, code:%s", vgId, taskId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d start task:0x%x async", vgId, taskId);
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = streamId;
|
||||
pRunReq->taskId = taskId;
|
||||
pRunReq->reqType = STREAM_EXEC_T_START_ONE_TASK;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(cb, STREAM_QUEUE, &msg);
|
||||
|
@ -54,6 +81,7 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||
SRpcMsg rsp = {.info = pMsg->info, .code = TSDB_CODE_SUCCESS};
|
||||
int64_t st = taosGetTimestampMs();
|
||||
|
||||
SStreamTaskNodeUpdateMsg req = {0};
|
||||
|
||||
|
@ -75,8 +103,7 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
STaskId id = {.streamId = req.streamId, .taskId = req.taskId};
|
||||
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
if (ppTask == NULL || *ppTask == NULL) {
|
||||
tqError("vgId:%d failed to acquire task:0x%x when handling update, it may have been dropped already", pMeta->vgId,
|
||||
req.taskId);
|
||||
tqError("vgId:%d failed to acquire task:0x%x when handling update, it may have been dropped", vgId, req.taskId);
|
||||
rsp.code = TSDB_CODE_SUCCESS;
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
|
@ -85,43 +112,38 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
}
|
||||
|
||||
SStreamTask* pTask = *ppTask;
|
||||
const char* idstr = pTask->id.idStr;
|
||||
|
||||
if (pMeta->updateInfo.transId != req.transId) {
|
||||
pMeta->updateInfo.transId = req.transId;
|
||||
tqInfo("s-task:%s receive new trans to update nodeEp msg from mnode, transId:%d", pTask->id.idStr, req.transId);
|
||||
tqInfo("s-task:%s receive new trans to update nodeEp msg from mnode, transId:%d", idstr, req.transId);
|
||||
// info needs to be kept till the new trans to update the nodeEp arrived.
|
||||
taosHashClear(pMeta->updateInfo.pTasks);
|
||||
} else {
|
||||
tqDebug("s-task:%s recv trans to update nodeEp from mnode, transId:%d", pTask->id.idStr, req.transId);
|
||||
tqDebug("s-task:%s recv trans to update nodeEp from mnode, transId:%d", idstr, req.transId);
|
||||
}
|
||||
|
||||
// duplicate update epset msg received, discard this redundant message
|
||||
STaskUpdateEntry entry = {.streamId = req.streamId, .taskId = req.taskId, .transId = req.transId};
|
||||
void* exist = taosHashGet(pMeta->updateInfo.pTasks, &entry, sizeof(STaskUpdateEntry));
|
||||
if (exist != NULL) {
|
||||
tqDebug("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId,
|
||||
req.transId);
|
||||
|
||||
void* pReqTask = taosHashGet(pMeta->updateInfo.pTasks, &entry, sizeof(STaskUpdateEntry));
|
||||
if (pReqTask != NULL) {
|
||||
tqDebug("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", idstr, vgId, req.transId);
|
||||
rsp.code = TSDB_CODE_SUCCESS;
|
||||
streamMetaWUnLock(pMeta);
|
||||
taosArrayDestroy(req.pNodeList);
|
||||
return rsp.code;
|
||||
}
|
||||
|
||||
// streamMetaWUnLock(pMeta);
|
||||
|
||||
// todo for test purpose
|
||||
// the following two functions should not be executed within the scope of meta lock to avoid deadlock
|
||||
streamTaskUpdateEpsetInfo(pTask, req.pNodeList);
|
||||
streamTaskResetStatus(pTask);
|
||||
|
||||
// continue after lock the meta again
|
||||
// streamMetaWLock(pMeta);
|
||||
|
||||
SStreamTask** ppHTask = NULL;
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
ppHTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &pTask->hTaskInfo.id, sizeof(pTask->hTaskInfo.id));
|
||||
if (ppHTask == NULL || *ppHTask == NULL) {
|
||||
tqError("vgId:%d failed to acquire fill-history task:0x%x when handling update, it may have been dropped already",
|
||||
pMeta->vgId, req.taskId);
|
||||
vgId, req.taskId);
|
||||
CLEAR_RELATED_FILLHISTORY_TASK(pTask);
|
||||
} else {
|
||||
tqDebug("s-task:%s fill-history task update nodeEp along with stream task", (*ppHTask)->id.idStr);
|
||||
|
@ -129,28 +151,34 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (restored) {
|
||||
tqDebug("s-task:%s vgId:%d start to save task", idstr, vgId);
|
||||
streamMetaSaveTask(pMeta, pTask);
|
||||
if (ppHTask != NULL) {
|
||||
streamMetaSaveTask(pMeta, *ppHTask);
|
||||
}
|
||||
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
// persist to disk
|
||||
}
|
||||
} else {
|
||||
tqDebug("s-task:%s vgId:%d not save since restore not finish", idstr, vgId);
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s vgId:%d start to stop task after save task", idstr, vgId);
|
||||
streamTaskStop(pTask);
|
||||
|
||||
// keep the already handled info
|
||||
// keep the already updated info
|
||||
taosHashPut(pMeta->updateInfo.pTasks, &entry, sizeof(entry), NULL, 0);
|
||||
|
||||
if (ppHTask != NULL) {
|
||||
streamTaskStop(*ppHTask);
|
||||
tqDebug("s-task:%s task nodeEp update completed, streamTask and related fill-history task closed", pTask->id.idStr);
|
||||
|
||||
int64_t now = taosGetTimestampMs();
|
||||
tqDebug("s-task:%s vgId:%d task nodeEp update completed, streamTask/fill-history closed, elapsed:%" PRId64 " ms",
|
||||
idstr, vgId, now - st);
|
||||
taosHashPut(pMeta->updateInfo.pTasks, &(*ppHTask)->id, sizeof(pTask->id), NULL, 0);
|
||||
} else {
|
||||
tqDebug("s-task:%s task nodeEp update completed, streamTask closed", pTask->id.idStr);
|
||||
int64_t now = taosGetTimestampMs();
|
||||
tqDebug("s-task:%s vgId:%d, task nodeEp update completed, streamTask closed, elapsed time:%" PRId64 "ms", idstr,
|
||||
vgId, now - st);
|
||||
}
|
||||
|
||||
rsp.code = 0;
|
||||
|
@ -166,16 +194,21 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
updateTasks, (numOfTasks - updateTasks));
|
||||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
// persist to disk
|
||||
}
|
||||
|
||||
if (!restored) {
|
||||
tqDebug("vgId:%d vnode restore not completed, not start the tasks, clear the start after nodeUpdate flag", vgId);
|
||||
pMeta->startInfo.tasksWillRestart = 0;
|
||||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
tqDebug("vgId:%d all %d task(s) nodeEp updated and closed", vgId, numOfTasks);
|
||||
tqDebug("vgId:%d all %d task(s) nodeEp updated and closed, transId:%d", vgId, numOfTasks, req.transId);
|
||||
#if 0
|
||||
// for test purpose, to trigger the leader election
|
||||
taosMSleep(5000);
|
||||
#endif
|
||||
|
||||
tqStreamTaskStartAsync(pMeta, cb, true);
|
||||
streamMetaWUnLock(pMeta);
|
||||
}
|
||||
|
@ -399,11 +432,11 @@ int32_t tqStreamTaskProcessCheckReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
|||
rsp.status = streamTaskCheckStatus(pTask, req.upstreamTaskId, req.upstreamNodeId, req.stage, &rsp.oldStage);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
char* p = NULL;
|
||||
streamTaskGetStatus(pTask, &p);
|
||||
SStreamTaskState* pState = streamTaskGetStatus(pTask);
|
||||
tqDebug("s-task:%s status:%s, stage:%" PRId64 " recv task check req(reqId:0x%" PRIx64
|
||||
") task:0x%x (vgId:%d), check_status:%d",
|
||||
pTask->id.idStr, p, rsp.oldStage, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.status);
|
||||
pTask->id.idStr, pState->name, rsp.oldStage, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId,
|
||||
rsp.status);
|
||||
} else {
|
||||
rsp.status = TASK_DOWNSTREAM_NOT_READY;
|
||||
tqDebug("tq recv task check(taskId:0x%" PRIx64 "-0x%x not built yet) req(reqId:0x%" PRIx64
|
||||
|
@ -415,12 +448,22 @@ int32_t tqStreamTaskProcessCheckReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
|||
return streamSendCheckRsp(pMeta, &req, &rsp, &pMsg->info, taskId);
|
||||
}
|
||||
|
||||
static void setParam(SStreamTask* pTask, int64_t* initTs, bool* hasHTask, STaskId* pId) {
|
||||
*initTs = pTask->execInfo.init;
|
||||
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
*hasHTask = true;
|
||||
pId->streamId = pTask->hTaskInfo.id.streamId;
|
||||
pId->taskId = pTask->hTaskInfo.id.taskId;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader) {
|
||||
char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||
int32_t vgId = pMeta->vgId;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
int32_t code;
|
||||
SStreamTaskCheckRsp rsp;
|
||||
|
||||
SDecoder decoder;
|
||||
|
@ -437,20 +480,62 @@ int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLe
|
|||
tqDebug("tq task:0x%x (vgId:%d) recv check rsp(reqId:0x%" PRIx64 ") from 0x%x (vgId:%d) status %d",
|
||||
rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.status);
|
||||
|
||||
int64_t initTs = 0;
|
||||
int64_t now = taosGetTimestampMs();
|
||||
STaskId id = {.streamId = rsp.streamId, .taskId = rsp.upstreamTaskId};
|
||||
STaskId fId = {0};
|
||||
bool hasHistoryTask = false;
|
||||
|
||||
// todo extract method
|
||||
if (!isLeader) {
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, rsp.streamId, rsp.upstreamTaskId, 0, taosGetTimestampMs(), false);
|
||||
tqError("vgId:%d not leader, task:0x%x not handle the check rsp, downstream:0x%x (vgId:%d)", vgId,
|
||||
rsp.upstreamTaskId, rsp.downstreamTaskId, rsp.downstreamNodeId);
|
||||
// this task may have been stopped, so acquire task may failed. Retrieve it directly from the task hash map.
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
SStreamTask** ppTask = taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
if (ppTask != NULL) {
|
||||
setParam(*ppTask, &initTs, &hasHistoryTask, &fId);
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (hasHistoryTask) {
|
||||
streamMetaAddTaskLaunchResult(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
}
|
||||
|
||||
tqError("vgId:%d not leader, task:0x%x not handle the check rsp, downstream:0x%x (vgId:%d)", vgId,
|
||||
rsp.upstreamTaskId, rsp.downstreamTaskId, rsp.downstreamNodeId);
|
||||
} else {
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
tqError("tq failed to locate the stream task:0x%" PRIx64 "-0x%x (vgId:%d), it may have been destroyed or stopped",
|
||||
rsp.streamId, rsp.upstreamTaskId, vgId);
|
||||
code = terrno = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
}
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
return code;
|
||||
}
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, rsp.streamId, rsp.upstreamTaskId);
|
||||
if (pTask == NULL) {
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, rsp.streamId, rsp.upstreamTaskId, 0, taosGetTimestampMs(), false);
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
SStreamTask** ppTask = taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
if (ppTask != NULL) {
|
||||
setParam(*ppTask, &initTs, &hasHistoryTask, &fId);
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (hasHistoryTask) {
|
||||
streamMetaAddTaskLaunchResult(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
}
|
||||
} else {
|
||||
streamMetaRUnLock(pMeta);
|
||||
}
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
tqError("tq failed to locate the stream task:0x%" PRIx64 "-0x%x (vgId:%d), it may have been destroyed or stopped",
|
||||
rsp.streamId, rsp.upstreamTaskId, vgId);
|
||||
terrno = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
return -1;
|
||||
|
||||
code = terrno = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
return code;
|
||||
}
|
||||
|
||||
code = streamProcessCheckRsp(pTask, &rsp);
|
||||
|
@ -489,8 +574,8 @@ int32_t tqStreamTaskProcessCheckpointReadyMsg(SStreamMeta* pMeta, SRpcMsg* pMsg)
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, int64_t sversion, char* msg, int32_t msgLen, bool isLeader,
|
||||
bool restored) {
|
||||
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, SMsgCb* cb, int64_t sversion, char* msg, int32_t msgLen,
|
||||
bool isLeader, bool restored) {
|
||||
int32_t code = 0;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
|
@ -542,18 +627,19 @@ int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, int64_t sversion, char*
|
|||
// only handled in the leader node
|
||||
if (isLeader) {
|
||||
tqDebug("vgId:%d s-task:0x%x is deployed and add into meta, numOfTasks:%d", vgId, taskId, numOfTasks);
|
||||
SStreamTask* p = streamMetaAcquireTask(pMeta, streamId, taskId);
|
||||
|
||||
if (p != NULL && restored && p->info.fillHistory == 0) {
|
||||
EStreamTaskEvent event = TASK_EVENT_INIT;
|
||||
streamTaskHandleEvent(p->status.pSM, event);
|
||||
} else if (!restored) {
|
||||
tqWarn("s-task:%s not launched since vnode(vgId:%d) not ready", p->id.idStr, vgId);
|
||||
if (restored) {
|
||||
SStreamTask* p = streamMetaAcquireTask(pMeta, streamId, taskId);
|
||||
if (p != NULL && (p->info.fillHistory == 0)) {
|
||||
tqStreamOneTaskStartAsync(pMeta, cb, streamId, taskId);
|
||||
}
|
||||
if (p != NULL) {
|
||||
streamMetaReleaseTask(pMeta, p);
|
||||
}
|
||||
} else {
|
||||
tqWarn("s-task:0x%x not launched since vnode(vgId:%d) not ready", taskId, vgId);
|
||||
}
|
||||
|
||||
if (p != NULL) {
|
||||
streamMetaReleaseTask(pMeta, p);
|
||||
}
|
||||
} else {
|
||||
tqDebug("vgId:%d not leader, not launch stream task s-task:0x%x", vgId, taskId);
|
||||
}
|
||||
|
@ -658,9 +744,17 @@ static int32_t restartStreamTasks(SStreamMeta* pMeta, bool isLeader) {
|
|||
return code;
|
||||
}
|
||||
|
||||
{
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
taosHashClear(pStartInfo->pReadyTaskSet);
|
||||
taosHashClear(pStartInfo->pFailedTaskSet);
|
||||
pStartInfo->readyTs = 0;
|
||||
}
|
||||
|
||||
if (isLeader && !tsDisableStream) {
|
||||
tqStreamTaskResetStatus(pMeta);
|
||||
streamMetaResetTaskStatus(pMeta);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
streamMetaStartAllTasks(pMeta);
|
||||
} else {
|
||||
streamMetaResetStartInfo(&pMeta->startInfo);
|
||||
|
@ -675,26 +769,49 @@ static int32_t restartStreamTasks(SStreamMeta* pMeta, bool isLeader) {
|
|||
int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader) {
|
||||
SStreamTaskRunReq* pReq = pMsg->pCont;
|
||||
|
||||
int32_t taskId = pReq->taskId;
|
||||
int32_t type = pReq->reqType;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
if (taskId == STREAM_EXEC_START_ALL_TASKS_ID) {
|
||||
if (type == STREAM_EXEC_T_START_ONE_TASK) {
|
||||
streamMetaStartOneTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
return 0;
|
||||
} else if (type == STREAM_EXEC_T_START_ALL_TASKS) {
|
||||
streamMetaStartAllTasks(pMeta);
|
||||
return 0;
|
||||
} else if (taskId == STREAM_EXEC_RESTART_ALL_TASKS_ID) {
|
||||
} else if (type == STREAM_EXEC_T_RESTART_ALL_TASKS) {
|
||||
restartStreamTasks(pMeta, isLeader);
|
||||
return 0;
|
||||
} else if (taskId == STREAM_EXEC_STOP_ALL_TASKS_ID) {
|
||||
} else if (type == STREAM_EXEC_T_STOP_ALL_TASKS) {
|
||||
streamMetaStopAllTasks(pMeta);
|
||||
return 0;
|
||||
} else if (type == STREAM_EXEC_T_RESUME_TASK) { // task resume to run after idle for a while
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
|
||||
if (pTask != NULL) {
|
||||
char* pStatus = NULL;
|
||||
if (streamTaskReadyToRun(pTask, &pStatus)) {
|
||||
int64_t execTs = pTask->status.lastExecTs;
|
||||
int32_t idle = taosGetTimestampMs() - execTs;
|
||||
tqDebug("s-task:%s task resume to run after idle for:%dms from:%" PRId64, pTask->id.idStr, idle, execTs);
|
||||
|
||||
streamResumeTask(pTask);
|
||||
} else {
|
||||
int8_t status = streamTaskSetSchedStatusInactive(pTask);
|
||||
tqDebug("vgId:%d s-task:%s ignore run req since not in ready state, status:%s, sched-status:%d", vgId,
|
||||
pTask->id.idStr, pStatus, status);
|
||||
}
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, taskId);
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
if (pTask != NULL) { // even in halt status, the data in inputQ must be processed
|
||||
char* p = NULL;
|
||||
if (streamTaskReadyToRun(pTask, &p)) {
|
||||
tqDebug("vgId:%d s-task:%s start to process block from inputQ, next checked ver:%" PRId64, vgId, pTask->id.idStr,
|
||||
pTask->chkInfo.nextProcessVer);
|
||||
tqDebug("vgId:%d s-task:%s status:%s start to process block from inputQ, next checked ver:%" PRId64, vgId, pTask->id.idStr,
|
||||
p, pTask->chkInfo.nextProcessVer);
|
||||
streamExecTask(pTask);
|
||||
} else {
|
||||
int8_t status = streamTaskSetSchedStatusInactive(pTask);
|
||||
|
@ -706,29 +823,42 @@ int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLead
|
|||
return 0;
|
||||
} else { // NOTE: pTask->status.schedStatus is not updated since it is not be handled by the run exec.
|
||||
// todo add one function to handle this
|
||||
tqError("vgId:%d failed to found s-task, taskId:0x%x may have been dropped", vgId, taskId);
|
||||
tqError("vgId:%d failed to found s-task, taskId:0x%x may have been dropped", vgId, pReq->taskId);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta) {
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
if (pStartInfo->taskStarting == 1) {
|
||||
tqDebug("vgId:%d already in start tasks procedure in other thread, restartCounter:%d, do nothing", vgId,
|
||||
pMeta->startInfo.restartCount);
|
||||
} else { // not in starting procedure
|
||||
bool allReady = streamMetaAllTasksReady(pMeta);
|
||||
|
||||
if (pStartInfo->restartCount > 0) {
|
||||
pStartInfo->restartCount -= 1;
|
||||
if ((pStartInfo->restartCount > 0) && (!allReady)) {
|
||||
// if all tasks are ready now, do NOT restart again, and reset the value of pStartInfo->restartCount
|
||||
pStartInfo->restartCount -= 1;
|
||||
tqDebug("vgId:%d role:%d need to restart all tasks again, restartCounter:%d", vgId, pMeta->role,
|
||||
pStartInfo->restartCount);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
ASSERT(pStartInfo->taskStarting == 0);
|
||||
tqDebug("vgId:%d role:%d need to restart all tasks again, restartCounter:%d", pMeta->vgId, pMeta->role,
|
||||
pStartInfo->restartCount);
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
restartStreamTasks(pMeta, (pMeta->role == NODE_ROLE_LEADER));
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqDebug("vgId:%d start all tasks completed", pMeta->vgId);
|
||||
restartStreamTasks(pMeta, (pMeta->role == NODE_ROLE_LEADER));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
if (pStartInfo->restartCount == 0) {
|
||||
tqDebug("vgId:%d start all tasks completed in callbackFn, restartCount is 0", pMeta->vgId);
|
||||
} else if (allReady) {
|
||||
pStartInfo->restartCount = 0;
|
||||
tqDebug("vgId:%d all tasks are ready, reset restartCounter 0, not restart tasks", vgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -745,11 +875,119 @@ int32_t tqStreamTaskProcessTaskResetReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
|||
tqDebug("s-task:%s receive task-reset msg from mnode, reset status and ready for data processing", pTask->id.idStr);
|
||||
|
||||
// clear flag set during do checkpoint, and open inputQ for all upstream tasks
|
||||
if (streamTaskGetStatus(pTask, NULL) == TASK_STATUS__CK) {
|
||||
if (streamTaskGetStatus(pTask)->state == TASK_STATUS__CK) {
|
||||
streamTaskClearCheckInfo(pTask, true);
|
||||
streamTaskSetStatusReady(pTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessTaskPauseReq(SStreamMeta* pMeta, char* pMsg){
|
||||
SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)pMsg;
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d process pause req, failed to acquire task:0x%x, it may have been dropped already", pMeta->vgId,
|
||||
pReq->taskId);
|
||||
// since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s receive pause msg from mnode", pTask->id.idStr);
|
||||
streamTaskPause(pMeta, pTask);
|
||||
|
||||
SStreamTask* pHistoryTask = NULL;
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
pHistoryTask = streamMetaAcquireTask(pMeta, pTask->hTaskInfo.id.streamId, pTask->hTaskInfo.id.taskId);
|
||||
if (pHistoryTask == NULL) {
|
||||
tqError("vgId:%d process pause req, failed to acquire fill-history task:0x%" PRIx64
|
||||
", it may have been dropped already",
|
||||
pMeta->vgId, pTask->hTaskInfo.id.taskId);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
// since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s fill-history task handle paused along with related stream task", pHistoryTask->id.idStr);
|
||||
|
||||
streamTaskPause(pMeta, pHistoryTask);
|
||||
streamMetaReleaseTask(pMeta, pHistoryTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tqProcessTaskResumeImpl(void* handle, SStreamTask* pTask, int64_t sversion, int8_t igUntreated, bool fromVnode) {
|
||||
SStreamMeta *pMeta = fromVnode ? ((STQ*)handle)->pStreamMeta : handle;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
if (pTask == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
streamTaskResume(pTask);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask)->state;
|
||||
|
||||
int32_t level = pTask->info.taskLevel;
|
||||
if (level == TASK_LEVEL__SINK) {
|
||||
if (status == TASK_STATUS__UNINIT) {
|
||||
}
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status == TASK_STATUS__READY || status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__CK) {
|
||||
// no lock needs to secure the access of the version
|
||||
if (igUntreated && level == TASK_LEVEL__SOURCE && !pTask->info.fillHistory) {
|
||||
// discard all the data when the stream task is suspended.
|
||||
walReaderSetSkipToVersion(pTask->exec.pWalReader, sversion);
|
||||
tqDebug("vgId:%d s-task:%s resume to exec, prev paused version:%" PRId64 ", start from vnode ver:%" PRId64
|
||||
", schedStatus:%d",
|
||||
vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
|
||||
} else { // from the previous paused version and go on
|
||||
tqDebug("vgId:%d s-task:%s resume to exec, from paused ver:%" PRId64 ", vnode ver:%" PRId64 ", schedStatus:%d",
|
||||
vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
|
||||
}
|
||||
|
||||
if (level == TASK_LEVEL__SOURCE && pTask->info.fillHistory && status == TASK_STATUS__SCAN_HISTORY) {
|
||||
streamStartScanHistoryAsync(pTask, igUntreated);
|
||||
} else if (level == TASK_LEVEL__SOURCE && (streamQueueGetNumOfItems(pTask->inputq.queue) == 0)) {
|
||||
tqScanWalAsync((STQ*)handle, false);
|
||||
} else {
|
||||
streamSchedExec(pTask);
|
||||
}
|
||||
} else if (status == TASK_STATUS__UNINIT) {
|
||||
// todo: fill-history task init ?
|
||||
if (pTask->info.fillHistory == 0) {
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessTaskResumeReq(void* handle, int64_t sversion, char* msg, bool fromVnode){
|
||||
SVResumeStreamTaskReq* pReq = (SVResumeStreamTaskReq*)msg;
|
||||
SStreamMeta *pMeta = fromVnode ? ((STQ*)handle)->pStreamMeta : handle;
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
int32_t code = tqProcessTaskResumeImpl(handle, pTask, sversion, pReq->igUntreated, fromVnode);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
STaskId* pHTaskId = &pTask->hTaskInfo.id;
|
||||
SStreamTask* pHistoryTask = streamMetaAcquireTask(pMeta, pHTaskId->streamId, pHTaskId->taskId);
|
||||
if (pHistoryTask) {
|
||||
code = tqProcessTaskResumeImpl(handle, pHistoryTask, sversion, pReq->igUntreated, fromVnode);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tqStreamTasksGetTotalNum(SStreamMeta* pMeta) {
|
||||
return taosArrayGetSize(pMeta->pTaskList);
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cos.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tsdb.h"
|
||||
#include "tsdbDataFileRW.h"
|
||||
#include "tsdbReadUtil.h"
|
||||
|
@ -894,19 +895,56 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
}
|
||||
|
||||
int num_keys = TARRAY_SIZE(remainCols);
|
||||
int16_t *aCols = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *slotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
|
||||
int16_t *lastColIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastSlotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastrowColIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastrowSlotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
SArray* lastTmpColArray = NULL;
|
||||
SArray* lastTmpIndexArray = NULL;
|
||||
SArray* lastrowTmpColArray = NULL;
|
||||
SArray* lastrowTmpIndexArray = NULL;
|
||||
|
||||
int lastIndex = 0;
|
||||
int lastrowIndex = 0;
|
||||
|
||||
for (int i = 0; i < num_keys; ++i) {
|
||||
SIdxKey *idxKey = taosArrayGet(remainCols, i);
|
||||
aCols[i] = idxKey->key.cid;
|
||||
slotIds[i] = pr->pSlotIds[idxKey->idx];
|
||||
if (idxKey->key.ltype == CACHESCAN_RETRIEVE_LAST >> 3) {
|
||||
if(NULL == lastTmpIndexArray) {
|
||||
lastTmpIndexArray = taosArrayInit(num_keys, sizeof(int32_t));
|
||||
}
|
||||
taosArrayPush(lastTmpIndexArray, &(i));
|
||||
lastColIds[lastIndex] = idxKey->key.cid;
|
||||
lastSlotIds[lastIndex] = pr->pSlotIds[idxKey->idx];
|
||||
lastIndex++;
|
||||
} else {
|
||||
if(NULL == lastrowTmpIndexArray) {
|
||||
lastrowTmpIndexArray = taosArrayInit(num_keys, sizeof(int32_t));
|
||||
}
|
||||
taosArrayPush(lastrowTmpIndexArray, &(i));
|
||||
lastrowColIds[lastrowIndex] = idxKey->key.cid;
|
||||
lastrowSlotIds[lastrowIndex] = pr->pSlotIds[idxKey->idx];
|
||||
lastrowIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ltype) {
|
||||
mergeLastCid(uid, pTsdb, &pTmpColArray, pr, aCols, num_keys, slotIds);
|
||||
} else {
|
||||
mergeLastRowCid(uid, pTsdb, &pTmpColArray, pr, aCols, num_keys, slotIds);
|
||||
pTmpColArray = taosArrayInit(lastIndex + lastrowIndex, sizeof(SLastCol));
|
||||
|
||||
if(lastTmpIndexArray != NULL) {
|
||||
mergeLastCid(uid, pTsdb, &lastTmpColArray, pr, lastColIds, lastIndex, lastSlotIds);
|
||||
for(int i = 0; i < taosArrayGetSize(lastTmpColArray); i++) {
|
||||
taosArrayInsert(pTmpColArray, *(int32_t*)taosArrayGet(lastTmpIndexArray, i), taosArrayGet(lastTmpColArray, i));
|
||||
}
|
||||
}
|
||||
|
||||
if(lastrowTmpIndexArray != NULL) {
|
||||
mergeLastCid(uid, pTsdb, &lastrowTmpColArray, pr, lastrowColIds, lastrowIndex, lastrowSlotIds);
|
||||
for(int i = 0; i < taosArrayGetSize(lastrowTmpColArray); i++) {
|
||||
taosArrayInsert(pTmpColArray, *(int32_t*)taosArrayGet(lastrowTmpIndexArray, i), taosArrayGet(lastrowTmpColArray, i));
|
||||
}
|
||||
}
|
||||
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
|
@ -965,9 +1003,18 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
rocksMayWrite(pTsdb, false, true, false);
|
||||
}
|
||||
|
||||
taosArrayDestroy(lastrowTmpIndexArray);
|
||||
taosArrayDestroy(lastrowTmpColArray);
|
||||
taosArrayDestroy(lastTmpIndexArray);
|
||||
taosArrayDestroy(lastTmpColArray);
|
||||
|
||||
taosMemoryFree(lastColIds);
|
||||
taosMemoryFree(lastSlotIds);
|
||||
taosMemoryFree(lastrowColIds);
|
||||
taosMemoryFree(lastrowSlotIds);
|
||||
|
||||
taosArrayDestroy(pTmpColArray);
|
||||
|
||||
taosMemoryFree(aCols);
|
||||
taosMemoryFree(slotIds);
|
||||
|
||||
return code;
|
||||
|
@ -1057,6 +1104,15 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
int16_t cid = ((int16_t *)TARRAY_DATA(pCidList))[i];
|
||||
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
// for select last_row, last case
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pr->pFuncTypeList != NULL && taosArrayGetSize(pr->pFuncTypeList) > i) {
|
||||
funcType = ((int32_t *)TARRAY_DATA(pr->pFuncTypeList))[i];
|
||||
}
|
||||
if (((pr->type & CACHESCAN_RETRIEVE_LAST) == CACHESCAN_RETRIEVE_LAST) && FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
int8_t tempType = CACHESCAN_RETRIEVE_LAST_ROW | (pr->type ^ CACHESCAN_RETRIEVE_LAST);
|
||||
key->ltype = (tempType & CACHESCAN_RETRIEVE_LAST) >> 3;
|
||||
}
|
||||
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, ROCKS_KEY_LEN);
|
||||
if (h) {
|
||||
|
@ -1990,9 +2046,9 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow, bool *pIgnoreEarlie
|
|||
|
||||
if (SFSNEXTROW_FILESET == state->state) {
|
||||
_next_fileset:
|
||||
if (--state->iFileSet < 0) {
|
||||
clearLastFileSet(state);
|
||||
clearLastFileSet(state);
|
||||
|
||||
if (--state->iFileSet < 0) {
|
||||
*ppRow = NULL;
|
||||
return code;
|
||||
} else {
|
||||
|
@ -2862,7 +2918,9 @@ static int32_t mergeLastCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SC
|
|||
|
||||
taosArraySet(pColArray, iCol, &lastCol);
|
||||
int32_t aColIndex = taosArraySearchIdx(aColArray, &lastCol.colVal.cid, compareInt16Val, TD_EQ);
|
||||
taosArrayRemove(aColArray, aColIndex);
|
||||
if (aColIndex >= 0) {
|
||||
taosArrayRemove(aColArray, aColIndex);
|
||||
}
|
||||
} else if (!COL_VAL_IS_VALUE(tColVal) && !COL_VAL_IS_VALUE(pColVal) && !setNoneCol) {
|
||||
noneCol = iCol;
|
||||
setNoneCol = true;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "functionMgt.h"
|
||||
#include "taoserror.h"
|
||||
#include "tarray.h"
|
||||
#include "tcommon.h"
|
||||
|
@ -33,31 +34,69 @@ static void setFirstLastResColToNull(SColumnInfoData* pCol, int32_t row) {
|
|||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
static void saveOneRowForLastRaw(SLastCol* pColVal, SCacheRowsReader* pReader, const int32_t slotId,
|
||||
SColumnInfoData* pColInfoData, int32_t numOfRows) {
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
} else {
|
||||
varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData);
|
||||
|
||||
memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData);
|
||||
colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false);
|
||||
}
|
||||
} else {
|
||||
colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds,
|
||||
const int32_t* dstSlotIds, void** pRes, const char* idStr) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
// bool allNullRow = true;
|
||||
|
||||
if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
|
||||
uint64_t ts = TSKEY_MIN;
|
||||
SFirstLastRes* p = NULL;
|
||||
col_id_t colId = -1;
|
||||
|
||||
SArray* funcTypeBlockArray = taosArrayInit(pReader->numOfCols, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pReader->pFuncTypeList != NULL && taosArrayGetSize(pReader->pFuncTypeList) > i) {
|
||||
funcType = *(int32_t*)taosArrayGet(pReader->pFuncTypeList, i);
|
||||
}
|
||||
taosArrayInsert(funcTypeBlockArray, dstSlotIds[i], taosArrayGet(pReader->pFuncTypeList, i));
|
||||
|
||||
if (slotIds[i] == -1) {
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
setFirstLastResColToNull(pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
int32_t slotId = slotIds[i];
|
||||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i);
|
||||
colId = pColVal->colVal.cid;
|
||||
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
saveOneRowForLastRaw(pColVal, pReader, slotId, pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
|
||||
p = (SFirstLastRes*)varDataVal(pRes[i]);
|
||||
|
||||
p->ts = pColVal->ts;
|
||||
ts = p->ts;
|
||||
p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal);
|
||||
// allNullRow = p->isNull & allNullRow;
|
||||
|
||||
if (!p->isNull) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
varDataSetLen(p->buf, pColVal->colVal.value.nData);
|
||||
|
@ -77,6 +116,13 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
}
|
||||
for (int32_t idx = 0; idx < taosArrayGetSize(pBlock->pDataBlock); ++idx) {
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, idx);
|
||||
if (idx < funcTypeBlockArray->size) {
|
||||
int32_t funcType = *(int32_t*)taosArrayGet(funcTypeBlockArray, idx);
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCol->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID && pCol->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
if (ts == TSKEY_MIN) {
|
||||
colDataSetNULL(pCol, numOfRows);
|
||||
|
@ -95,6 +141,7 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
++pBlock->info.rows;
|
||||
taosArrayDestroy(funcTypeBlockArray);
|
||||
} else if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST_ROW)) {
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
|
@ -105,21 +152,8 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
continue;
|
||||
}
|
||||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i);
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
} else {
|
||||
varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData);
|
||||
|
||||
memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData);
|
||||
colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false);
|
||||
}
|
||||
} else {
|
||||
colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal));
|
||||
}
|
||||
saveOneRowForLastRaw(pColVal, pReader, slotId, pColInfoData, numOfRows);
|
||||
}
|
||||
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
|
@ -175,7 +209,8 @@ int32_t tsdbReuseCacherowsReader(void* reader, void* pTableIdList, int32_t numOf
|
|||
}
|
||||
|
||||
int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr) {
|
||||
SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr,
|
||||
SArray* pFuncTypeList) {
|
||||
*pReader = NULL;
|
||||
SCacheRowsReader* p = taosMemoryCalloc(1, sizeof(SCacheRowsReader));
|
||||
if (p == NULL) {
|
||||
|
@ -190,6 +225,7 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList,
|
|||
p->numOfCols = numOfCols;
|
||||
p->pCidList = pCidList;
|
||||
p->pSlotIds = pSlotIds;
|
||||
p->pFuncTypeList = pFuncTypeList;
|
||||
|
||||
if (numOfTables == 0) {
|
||||
*pReader = p;
|
||||
|
@ -391,7 +427,10 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
if (!COL_VAL_IS_VALUE(&p->colVal)) {
|
||||
hasNotNullRow = false;
|
||||
}
|
||||
continue;
|
||||
// For all of cols is null, the last null col of last table will be save
|
||||
if (i != pr->numOfTables - 1 || k != pr->numOfCols - 1 || hasRes) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
hasRes = true;
|
||||
|
|
|
@ -73,6 +73,7 @@ static int32_t getInitialDelIndex(const SArray* pDelSkyline, int32_t order
|
|||
static void resetTableListIndex(SReaderStatus* pStatus);
|
||||
static void getMemTableTimeRange(STsdbReader* pReader, int64_t* pMaxKey, int64_t* pMinKey);
|
||||
static void updateComposedBlockInfo(STsdbReader* pReader, double el, STableBlockScanInfo* pBlockScanInfo);
|
||||
static int32_t buildFromPreFilesetBuffer(STsdbReader* pReader);
|
||||
|
||||
static bool outOfTimeWindow(int64_t ts, STimeWindow* pWindow) { return (ts > pWindow->ekey) || (ts < pWindow->skey); }
|
||||
|
||||
|
@ -3040,6 +3041,17 @@ static ERetrieveType doReadDataFromSttFiles(STsdbReader* pReader) {
|
|||
return TSDB_READ_RETURN;
|
||||
}
|
||||
|
||||
if (pReader->status.bProcMemPreFileset) {
|
||||
code = buildFromPreFilesetBuffer(pReader);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
if (pResBlock->info.rows > 0) {
|
||||
pReader->status.processingMemPreFileSet = true;
|
||||
return TSDB_READ_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlockIter->numOfBlocks > 0) { // there are data blocks existed.
|
||||
return TSDB_READ_CONTINUE;
|
||||
} else { // all blocks in data file are checked, let's check the data in last files
|
||||
|
@ -4088,9 +4100,9 @@ void tsdbReaderClose2(STsdbReader* pReader) {
|
|||
size_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
|
||||
if (pReader->status.pTableMap != NULL) {
|
||||
destroyAllBlockScanInfo(pReader->status.pTableMap);
|
||||
clearBlockScanInfoBuf(&pReader->blockInfoBuf);
|
||||
pReader->status.pTableMap = NULL;
|
||||
}
|
||||
clearBlockScanInfoBuf(&pReader->blockInfoBuf);
|
||||
|
||||
if (pReader->pFileReader != NULL) {
|
||||
tsdbDataFileReaderClose(&pReader->pFileReader);
|
||||
|
@ -4108,8 +4120,10 @@ void tsdbReaderClose2(STsdbReader* pReader) {
|
|||
taosMemoryFreeClear(pReader->status.uidList.tableUidList);
|
||||
|
||||
qTrace("tsdb/reader-close: %p, untake snapshot", pReader);
|
||||
tsdbUntakeReadSnap2(pReader, pReader->pReadSnap, true);
|
||||
pReader->pReadSnap = NULL;
|
||||
void* p = pReader->pReadSnap;
|
||||
if ((p == atomic_val_compare_exchange_ptr((void**)&pReader->pReadSnap, p, NULL)) && (p != NULL)) {
|
||||
tsdbUntakeReadSnap2(pReader, p, true);
|
||||
}
|
||||
|
||||
tsem_destroy(&pReader->resumeAfterSuspend);
|
||||
tsdbReleaseReader(pReader);
|
||||
|
@ -4183,8 +4197,12 @@ int32_t tsdbReaderSuspend2(STsdbReader* pReader) {
|
|||
doSuspendCurrentReader(pReader);
|
||||
}
|
||||
|
||||
tsdbUntakeReadSnap2(pReader, pReader->pReadSnap, false);
|
||||
pReader->pReadSnap = NULL;
|
||||
// make sure only release once
|
||||
void* p = pReader->pReadSnap;
|
||||
if ((p == atomic_val_compare_exchange_ptr((void**)&pReader->pReadSnap, p, NULL)) && (p != NULL)) {
|
||||
tsdbUntakeReadSnap2(pReader, p, false);
|
||||
}
|
||||
|
||||
if (pReader->bFilesetDelimited) {
|
||||
pReader->status.memTableMinKey = INT64_MAX;
|
||||
pReader->status.memTableMaxKey = INT64_MIN;
|
||||
|
@ -4297,6 +4315,7 @@ static int32_t buildFromPreFilesetBuffer(STsdbReader* pReader) {
|
|||
} else {
|
||||
tsdbDebug("finished pre-fileset %d buffer processing. %s", fid, pReader->idStr);
|
||||
pStatus->bProcMemPreFileset = false;
|
||||
pStatus->processingMemPreFileSet = false;
|
||||
if (pReader->notifyFn) {
|
||||
STsdReaderNotifyInfo info = {0};
|
||||
info.duration.filesetId = fid;
|
||||
|
@ -4329,7 +4348,7 @@ static int32_t doTsdbNextDataBlockFilesetDelimited(STsdbReader* pReader) {
|
|||
pStatus->bProcMemFirstFileset, pReader->idStr);
|
||||
if (pStatus->bProcMemPreFileset) {
|
||||
if (pBlock->info.rows > 0) {
|
||||
if (pReader->notifyFn) {
|
||||
if (pReader->notifyFn && !pReader->status.processingMemPreFileSet) {
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
STsdReaderNotifyInfo info = {0};
|
||||
info.duration.filesetId = fid;
|
||||
|
|
|
@ -238,6 +238,7 @@ typedef struct SReaderStatus {
|
|||
int64_t prevFilesetStartKey;
|
||||
int64_t prevFilesetEndKey;
|
||||
bool bProcMemFirstFileset;
|
||||
bool processingMemPreFileSet;
|
||||
STableUidList procMemUidList;
|
||||
STableBlockScanInfo** pProcMemTableIter;
|
||||
} SReaderStatus;
|
||||
|
@ -347,6 +348,7 @@ typedef struct SCacheRowsReader {
|
|||
STsdbReadSnap* pReadSnap;
|
||||
char* idstr;
|
||||
int64_t lastTs;
|
||||
SArray* pFuncTypeList;
|
||||
} SCacheRowsReader;
|
||||
|
||||
int32_t tsdbCacheGetBatch(STsdb* pTsdb, tb_uid_t uid, SArray* pLastArray, SCacheRowsReader* pr, int8_t ltype);
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "tq.h"
|
||||
#include "sync.h"
|
||||
#include "tq.h"
|
||||
#include "tqCommon.h"
|
||||
#include "tsdb.h"
|
||||
#include "vnd.h"
|
||||
#include "tqCommon.h"
|
||||
|
||||
#define BATCH_ENABLE 0
|
||||
|
||||
|
@ -411,7 +411,7 @@ static int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
static int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgSendReq(pEpSet, pMsg);
|
||||
int32_t code = tmsgSendSyncReq(pEpSet, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
|
@ -477,8 +477,8 @@ static void vnodeSyncRollBackMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta
|
|||
}
|
||||
|
||||
static int32_t vnodeSnapshotStartRead(const SSyncFSM *pFsm, void *pParam, void **ppReader) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
int32_t code = vnodeSnapReaderOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapReader **)ppReader);
|
||||
SVnode *pVnode = pFsm->data;
|
||||
int32_t code = vnodeSnapReaderOpen(pVnode, (SSnapshotParam *)pParam, (SVSnapReader **)ppReader);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -555,7 +555,7 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx)
|
|||
walApplyVer(pVnode->pWal, commitIdx);
|
||||
pVnode->restored = true;
|
||||
|
||||
SStreamMeta* pMeta = pVnode->pTq->pStreamMeta;
|
||||
SStreamMeta *pMeta = pVnode->pTq->pStreamMeta;
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
if (pMeta->startInfo.tasksWillRestart) {
|
||||
|
@ -567,29 +567,29 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx)
|
|||
if (vnodeIsRoleLeader(pVnode)) {
|
||||
// start to restore all stream tasks
|
||||
if (tsDisableStream) {
|
||||
streamMetaWUnLock(pMeta);
|
||||
vInfo("vgId:%d, sync restore finished, not launch stream tasks, since stream tasks are disabled", vgId);
|
||||
} else {
|
||||
vInfo("vgId:%d sync restore finished, start to launch stream tasks", pVnode->config.vgId);
|
||||
tqStreamTaskResetStatus(pVnode->pTq->pStreamMeta);
|
||||
|
||||
{
|
||||
vInfo("vgId:%d sync restore finished, start to launch stream task(s)", pVnode->config.vgId);
|
||||
int32_t numOfTasks = tqStreamTasksGetTotalNum(pMeta);
|
||||
if (numOfTasks > 0) {
|
||||
if (pMeta->startInfo.taskStarting == 1) {
|
||||
pMeta->startInfo.restartCount += 1;
|
||||
tqDebug("vgId:%d in start tasks procedure, inc restartCounter by 1, remaining restart:%d", vgId,
|
||||
pMeta->startInfo.restartCount);
|
||||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
pMeta->startInfo.taskStarting = 1;
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqStreamTaskStartAsync(pMeta, &pVnode->msgCb, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
vInfo("vgId:%d, sync restore finished, not launch stream tasks since not leader", vgId);
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
}
|
||||
|
||||
static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct SColMatchItem {
|
|||
int32_t dstSlotId;
|
||||
bool needOutput;
|
||||
SDataType dataType;
|
||||
int32_t funcType;
|
||||
} SColMatchItem;
|
||||
|
||||
typedef struct SColMatchInfo {
|
||||
|
|
|
@ -200,6 +200,7 @@ typedef struct SExchangeInfo {
|
|||
uint64_t self;
|
||||
SLimitInfo limitInfo;
|
||||
int64_t openedTs; // start exec time stamp, todo: move to SLoadRemoteDataInfo
|
||||
char* pTaskId;
|
||||
} SExchangeInfo;
|
||||
|
||||
typedef struct SScanInfo {
|
||||
|
|
|
@ -273,6 +273,7 @@ SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
int32_t doAggregateImpl(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
for (int32_t k = 0; k < pOperator->exprSupp.numOfExprs; ++k) {
|
||||
if (functionNeedToExecute(&pCtx[k])) {
|
||||
// todo add a dummy funtion to avoid process check
|
||||
|
@ -280,7 +281,13 @@ int32_t doAggregateImpl(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx) {
|
|||
continue;
|
||||
}
|
||||
|
||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if ((&pCtx[k])->input.pData[0] == NULL) {
|
||||
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
|
||||
qError("%s aggregate function error happens, input data is NULL.", GET_TASKID(pOperator->pTaskInfo));
|
||||
} else {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||
return code;
|
||||
|
@ -562,7 +569,12 @@ void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pC
|
|||
} else {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if ((&pCtx[k])->input.pData[0] == NULL) {
|
||||
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
|
||||
qError("%s apply functions error, input data is NULL.", GET_TASKID(taskInfo));
|
||||
} else {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tmsg.h"
|
||||
|
||||
#include "executorInt.h"
|
||||
#include "functionMgt.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tcompare.h"
|
||||
|
@ -44,6 +45,7 @@ typedef struct SCacheRowsScanInfo {
|
|||
SArray* pCidList;
|
||||
int32_t indexOfBufferedRes;
|
||||
STableListInfo* pTableList;
|
||||
SArray* pFuncTypeList;
|
||||
} SCacheRowsScanInfo;
|
||||
|
||||
static SSDataBlock* doScanCache(SOperatorInfo* pOperator);
|
||||
|
@ -105,9 +107,15 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
}
|
||||
|
||||
SArray* pCidList = taosArrayInit(numOfCols, sizeof(int16_t));
|
||||
pInfo->pFuncTypeList = taosArrayInit(taosArrayGetSize(pScanNode->pFuncTypes), sizeof(int32_t));
|
||||
taosArrayAddAll(pInfo->pFuncTypeList, pScanNode->pFuncTypes);
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(pInfo->matchInfo.pList); ++i) {
|
||||
SColMatchItem* pColInfo = taosArrayGet(pInfo->matchInfo.pList, i);
|
||||
taosArrayPush(pCidList, &pColInfo->colId);
|
||||
if (pInfo->pFuncTypeList != NULL && taosArrayGetSize(pInfo->pFuncTypeList) > i) {
|
||||
pColInfo->funcType = *(int32_t*)taosArrayGet(pInfo->pFuncTypeList, i);
|
||||
}
|
||||
}
|
||||
pInfo->pCidList = pCidList;
|
||||
|
||||
|
@ -132,7 +140,7 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
uint64_t suid = tableListGetSuid(pTableListInfo);
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, totalTables,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pCidList, pInfo->pSlotIds,
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str);
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str, pScanNode->pFuncTypes);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -274,7 +282,7 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
if (NULL == pInfo->pLastrowReader) {
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, num,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pInfo->pCidList, pInfo->pSlotIds, suid, &pInfo->pLastrowReader,
|
||||
pTaskInfo->id.str);
|
||||
pTaskInfo->id.str, pInfo->pFuncTypeList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pInfo->currentGroupIndex += 1;
|
||||
taosArrayClear(pInfo->pUidList);
|
||||
|
@ -333,6 +341,7 @@ void destroyCacheScanOperator(void* param) {
|
|||
taosMemoryFree(pInfo->pSlotIds);
|
||||
taosMemoryFree(pInfo->pDstSlotIds);
|
||||
taosArrayDestroy(pInfo->pCidList);
|
||||
taosArrayDestroy(pInfo->pFuncTypeList);
|
||||
taosArrayDestroy(pInfo->pUidList);
|
||||
taosArrayDestroy(pInfo->matchInfo.pList);
|
||||
tableListDestroy(pInfo->pTableList);
|
||||
|
@ -405,6 +414,8 @@ int32_t removeRedundantTsCol(SLastRowScanPhysiNode* pScanNode, SColMatchInfo* pC
|
|||
SSlotDescNode* pDesc = (SSlotDescNode*)nodesListGetNode(pList, slotId);
|
||||
if (pDesc->dataType.type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
taosArrayPush(pMatchInfo, pColInfo);
|
||||
} else if (FUNCTION_TYPE_CACHE_LAST_ROW == pColInfo->funcType){
|
||||
taosArrayPush(pMatchInfo, pColInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -260,14 +260,17 @@ static int32_t initDataSource(int32_t numOfSources, SExchangeInfo* pInfo, const
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t len = strlen(id) + 1;
|
||||
pInfo->pTaskId = taosMemoryCalloc(1, len);
|
||||
strncpy(pInfo->pTaskId, id, len);
|
||||
for (int32_t i = 0; i < numOfSources; ++i) {
|
||||
SSourceDataInfo dataInfo = {0};
|
||||
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
|
||||
dataInfo.taskId = id;
|
||||
dataInfo.taskId = pInfo->pTaskId;
|
||||
dataInfo.index = i;
|
||||
SSourceDataInfo* pDs = taosArrayPush(pInfo->pSourceDataInfo, &dataInfo);
|
||||
if (pDs == NULL) {
|
||||
taosArrayDestroy(pInfo->pSourceDataInfo);
|
||||
taosArrayDestroyEx(pInfo->pSourceDataInfo, freeSourceDataInfo);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -383,6 +386,8 @@ void doDestroyExchangeOperatorInfo(void* param) {
|
|||
tSimpleHashCleanup(pExInfo->pHashSources);
|
||||
|
||||
tsem_destroy(&pExInfo->ready);
|
||||
taosMemoryFreeClear(pExInfo->pTaskId);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
@ -782,7 +787,7 @@ int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasic
|
|||
if (pIdx->inUseIdx < 0) {
|
||||
SSourceDataInfo dataInfo = {0};
|
||||
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
|
||||
dataInfo.taskId = GET_TASKID(pOperator->pTaskInfo);
|
||||
dataInfo.taskId = pExchangeInfo->pTaskId;
|
||||
dataInfo.index = pIdx->srcIdx;
|
||||
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
|
||||
dataInfo.srcOpType = pBasicParam->srcOpType;
|
||||
|
|
|
@ -1343,7 +1343,6 @@ int32_t extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
c.colId = pColNode->colId;
|
||||
c.srcSlotId = pColNode->slotId;
|
||||
c.dstSlotId = pNode->slotId;
|
||||
c.dataType = pColNode->node.resType;
|
||||
taosArrayPush(pList, &c);
|
||||
}
|
||||
}
|
||||
|
@ -1838,7 +1837,7 @@ static STimeWindow doCalculateTimeWindow(int64_t ts, SInterval* pInterval) {
|
|||
STimeWindow w = {0};
|
||||
|
||||
w.skey = taosTimeTruncate(ts, pInterval);
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
w.ekey = taosTimeGetIntervalEnd(w.skey, pInterval);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -1887,31 +1886,17 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
}
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
int64_t slidingStart = 0;
|
||||
if (pInterval->offset > 0) {
|
||||
slidingStart = taosTimeAdd(tw->skey, -1 * pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
} else {
|
||||
slidingStart = tw->skey;
|
||||
}
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (!IS_CALENDAR_TIME_DURATION(pInterval->slidingUnit)) {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert key to second
|
||||
int64_t key = convertTimePrecision(tw->skey, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
int64_t duration = pInterval->sliding;
|
||||
if (pInterval->slidingUnit == 'y') {
|
||||
duration *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + duration * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
slidingStart = taosTimeAdd(slidingStart, factor * pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
tw->skey = taosTimeAdd(slidingStart, pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
int64_t slidingEnd = taosTimeAdd(slidingStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
tw->ekey = taosTimeAdd(slidingEnd, pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
}
|
||||
|
||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||
|
|
|
@ -621,6 +621,10 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo
|
|||
} else {
|
||||
pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot);
|
||||
}
|
||||
|
||||
if(pRes == NULL) {
|
||||
st = taosGetTimestampUs();
|
||||
}
|
||||
|
||||
int32_t rowsThreshold = pTaskInfo->pSubplan->rowsThreshold;
|
||||
if (!pTaskInfo->pSubplan->dynamicRowThreshold || 4096 <= pTaskInfo->pSubplan->rowsThreshold) {
|
||||
|
@ -922,8 +926,8 @@ int32_t qStreamSourceScanParamForHistoryScanStep2(qTaskInfo_t tinfo, SVersionRan
|
|||
pStreamInfo->fillHistoryWindow = *pWindow;
|
||||
pStreamInfo->recoverStep = STREAM_RECOVER_STEP__PREPARE2;
|
||||
|
||||
qDebug("%s step 2. set param for stream scanner for scan-history data, verRange:%" PRId64 " - %" PRId64
|
||||
", window:%" PRId64 " - %" PRId64,
|
||||
qDebug("%s step 2. set param for stream scanner scan wal, verRange:%" PRId64 " - %" PRId64 ", window:%" PRId64
|
||||
" - %" PRId64,
|
||||
GET_TASKID(pTaskInfo), pStreamInfo->fillHistoryVer.minVer, pStreamInfo->fillHistoryVer.maxVer, pWindow->skey,
|
||||
pWindow->ekey);
|
||||
return 0;
|
||||
|
@ -1023,6 +1027,57 @@ int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t qResetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
||||
|
||||
while (1) {
|
||||
int32_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) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
STimeWindowAggSupp* pSup = &pInfo->twAggSup;
|
||||
|
||||
pSup->calTriggerSaved = 0;
|
||||
pSup->deleteMarkSaved = 0;
|
||||
qInfo("reset stream param for interval: %d, %" PRId64, pSup->calTrigger, pSup->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;
|
||||
STimeWindowAggSupp* pSup = &pInfo->twAggSup;
|
||||
|
||||
pSup->calTriggerSaved = 0;
|
||||
pSup->deleteMarkSaved = 0;
|
||||
qInfo("reset stream param for session: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark);
|
||||
|
||||
} else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE) {
|
||||
SStreamStateAggOperatorInfo* pInfo = pOperator->info;
|
||||
STimeWindowAggSupp* pSup = &pInfo->twAggSup;
|
||||
|
||||
pSup->calTriggerSaved = 0;
|
||||
pSup->deleteMarkSaved = 0;
|
||||
qInfo("reset stream param for state: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark);
|
||||
|
||||
} else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT) {
|
||||
SStreamEventAggOperatorInfo* pInfo = pOperator->info;
|
||||
STimeWindowAggSupp* pSup = &pInfo->twAggSup;
|
||||
|
||||
pSup->calTriggerSaved = 0;
|
||||
pSup->deleteMarkSaved = 0;
|
||||
qInfo("save stream param for state: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark);
|
||||
}
|
||||
|
||||
// iterate operator tree
|
||||
if (pOperator->numOfDownstream != 1 || pOperator->pDownstream[0] == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
pOperator = pOperator->pDownstream[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t qRestoreStreamOperatorOption(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
const char* id = GET_TASKID(pTaskInfo);
|
||||
|
@ -1078,7 +1133,7 @@ int32_t qStreamInfoResetTimewindowFilter(qTaskInfo_t tinfo) {
|
|||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
STimeWindow* pWindow = &pTaskInfo->streamInfo.fillHistoryWindow;
|
||||
|
||||
qDebug("%s remove scan-history filter window:%" PRId64 "-%" PRId64 ", set new window:%" PRId64 "-%" PRId64,
|
||||
qDebug("%s remove timeWindow filter:%" PRId64 "-%" PRId64 ", set new window:%" PRId64 "-%" PRId64,
|
||||
GET_TASKID(pTaskInfo), pWindow->skey, pWindow->ekey, INT64_MIN, INT64_MAX);
|
||||
|
||||
pWindow->skey = INT64_MIN;
|
||||
|
|
|
@ -448,7 +448,7 @@ STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key) {
|
|||
* if the realSkey > INT64_MAX - pInterval->interval, the query duration between
|
||||
* realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
|
||||
*/
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
win.ekey = taosTimeGetIntervalEnd(win.skey, pInterval);
|
||||
if (win.ekey < win.skey) {
|
||||
win.ekey = INT64_MAX;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef struct SProjectOperatorInfo {
|
|||
SLimitInfo limitInfo;
|
||||
bool mergeDataBlocks;
|
||||
SSDataBlock* pFinalRes;
|
||||
bool inputIgnoreGroup;
|
||||
} SProjectOperatorInfo;
|
||||
|
||||
typedef struct SIndefOperatorInfo {
|
||||
|
@ -109,7 +110,8 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhys
|
|||
pInfo->pFinalRes = createOneDataBlock(pResBlock, false);
|
||||
pInfo->binfo.inputTsOrder = pProjPhyNode->node.inputTsOrder;
|
||||
pInfo->binfo.outputTsOrder = pProjPhyNode->node.outputTsOrder;
|
||||
|
||||
pInfo->inputIgnoreGroup = pProjPhyNode->inputIgnoreGroup;
|
||||
|
||||
if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM || pTaskInfo->execModel == OPTR_EXEC_MODEL_QUEUE) {
|
||||
pInfo->mergeDataBlocks = false;
|
||||
} else {
|
||||
|
@ -300,6 +302,10 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
if (pProjectInfo->inputIgnoreGroup) {
|
||||
pBlock->info.id.groupId = 0;
|
||||
}
|
||||
|
||||
int32_t status = discardGroupDataBlock(pBlock, pLimitInfo);
|
||||
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
||||
continue;
|
||||
|
|
|
@ -427,6 +427,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) {
|
|||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
||||
for (int32_t i = 0; i < numOfCols; i++) {
|
||||
if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) {
|
||||
|
@ -435,6 +436,7 @@ static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void reloadFromDownStream(SOperatorInfo* downstream, SStreamIntervalOperatorInfo* pInfo) {
|
||||
SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore;
|
||||
|
@ -2891,6 +2893,14 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pSessionNode->window.watermark,
|
||||
.calTrigger = pSessionNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
.deleteMark = getDeleteMark(&pSessionNode->window, 0),
|
||||
};
|
||||
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, pSessionNode->gap,
|
||||
pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
|
@ -2898,13 +2908,6 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pSessionNode->window.watermark,
|
||||
.calTrigger = pSessionNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
|
||||
|
@ -3773,6 +3776,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
.calTrigger = pStateNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
.deleteMark = getDeleteMark(&pStateNode->window, 0),
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
@ -3846,6 +3850,7 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (type == STREAM_INVERT) {
|
||||
|
@ -3855,6 +3860,7 @@ static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SStreamIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
|
@ -3947,9 +3953,11 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
// caller. Note that all the time window are not close till now.
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true);
|
||||
#ifdef BUILD_NO_CALL
|
||||
if (pInfo->invertible) {
|
||||
setInverFunction(pSup->pCtx, pOperator->exprSupp.numOfExprs, pBlock->info.type);
|
||||
}
|
||||
#endif
|
||||
|
||||
doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
|
|
|
@ -450,7 +450,7 @@ int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBl
|
|||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
pNext->ekey = taosTimeGetIntervalEnd(pNext->skey, pInterval);
|
||||
} else {
|
||||
pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
pNext->skey = pNext->ekey - pInterval->interval + 1;
|
||||
|
@ -459,7 +459,7 @@ int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBl
|
|||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
pNext->ekey = taosTimeGetIntervalEnd(pNext->skey, pInterval);
|
||||
} else {
|
||||
pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
pNext->ekey = pNext->skey + pInterval->interval - 1;
|
||||
|
@ -1079,16 +1079,6 @@ static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator) {
|
|||
return (rows == 0) ? NULL : pBlock;
|
||||
}
|
||||
|
||||
static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (type == STREAM_INVERT) {
|
||||
fmSetInvertFunc(pCtx[i].functionId, &(pCtx[i].fpSet));
|
||||
} else if (type == STREAM_NORMAL) {
|
||||
fmSetNormalFunc(pCtx[i].functionId, &(pCtx[i].fpSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SExprSupp* pSup, int32_t numOfOutput) {
|
||||
SResultRow* pResult = getResultRowByPos(pResultBuf, p1, false);
|
||||
if (NULL == pResult) {
|
||||
|
|
|
@ -158,4 +158,32 @@ TEST(testCase, timewindow_gen) {
|
|||
|
||||
}
|
||||
|
||||
TEST(testCase, timewindow_natural) {
|
||||
osSetTimezone("CST");
|
||||
|
||||
int32_t precision = TSDB_TIME_PRECISION_MILLI;
|
||||
|
||||
SInterval interval2 = createInterval(17, 17, 13392000000, 'n', 'n', 0, precision);
|
||||
int64_t key = 1648970865984;
|
||||
STimeWindow w0 = getAlignQueryTimeWindow(&interval2, key);
|
||||
printTimeWindow(&w0, precision, key);
|
||||
ASSERT_GE(w0.ekey, key);
|
||||
|
||||
int64_t key1 = 1633446027072;
|
||||
STimeWindow w1 = {0};
|
||||
getInitialStartTimeWindow(&interval2, key1, &w1, true);
|
||||
printTimeWindow(&w1, precision, key1);
|
||||
STimeWindow w3 = getAlignQueryTimeWindow(&interval2, key1);
|
||||
printf("%ld win %ld, %ld\n", key1, w3.skey, w3.ekey);
|
||||
|
||||
int64_t key2 = 1648758398208;
|
||||
STimeWindow w2 = {0};
|
||||
getInitialStartTimeWindow(&interval2, key2, &w2, true);
|
||||
printTimeWindow(&w2, precision, key2);
|
||||
STimeWindow w4 = getAlignQueryTimeWindow(&interval2, key2);
|
||||
printf("%ld win %ld, %ld\n", key2, w3.skey, w3.ekey);
|
||||
|
||||
ASSERT_EQ(w3.skey, w4.skey);
|
||||
ASSERT_EQ(w3.ekey, w4.ekey);
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
|
@ -40,7 +40,9 @@ typedef struct SBuiltinFuncDefinition {
|
|||
FExecProcess processFunc;
|
||||
FScalarExecProcess sprocessFunc;
|
||||
FExecFinalize finalizeFunc;
|
||||
#ifdef BUILD_NO_CALL
|
||||
FExecProcess invertFunc;
|
||||
#endif
|
||||
FExecCombine combineFunc;
|
||||
const char* pPartialFunc;
|
||||
const char* pMergeFunc;
|
||||
|
|
|
@ -59,12 +59,19 @@ int32_t combineFunction(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
|||
EFuncDataRequired countDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
||||
bool getCountFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
int32_t countFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t countInvertFunction(SqlFunctionCtx* pCtx);
|
||||
#endif
|
||||
|
||||
EFuncDataRequired statisDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
||||
bool getSumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
int32_t sumFunction(SqlFunctionCtx* pCtx);
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t sumInvertFunction(SqlFunctionCtx* pCtx);
|
||||
#endif
|
||||
|
||||
int32_t sumCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
|
||||
bool minmaxFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
|
@ -81,7 +88,11 @@ int32_t avgFunction(SqlFunctionCtx* pCtx);
|
|||
int32_t avgFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t avgInvertFunction(SqlFunctionCtx* pCtx);
|
||||
#endif
|
||||
|
||||
int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
int32_t getAvgInfoSize();
|
||||
|
||||
|
@ -91,7 +102,11 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx);
|
|||
int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t stddevPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t stddevInvertFunction(SqlFunctionCtx* pCtx);
|
||||
#endif
|
||||
|
||||
int32_t stddevCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
int32_t getStddevInfoSize();
|
||||
|
||||
|
@ -99,7 +114,6 @@ bool getLeastSQRFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
|||
bool leastSQRFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t leastSQRFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t leastSQRFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t leastSQRInvertFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t leastSQRCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
|
||||
bool getPercentileFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
//
|
||||
// Created by slzhou on 22-4-20.
|
||||
//
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_FNLOG_H
|
||||
#define TDENGINE_FNLOG_H
|
||||
|
|
|
@ -256,13 +256,24 @@ static int32_t addDbPrecisonParam(SNodeList** pList, uint8_t precision) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SDataType* getSDataTypeFromNode(SNode* pNode) {
|
||||
if (pNode == NULL) return NULL;
|
||||
if (nodesIsExprNode(pNode)) {
|
||||
return &((SExprNode*)pNode)->resType;
|
||||
} else if (QUERY_NODE_COLUMN_REF == pNode->type) {
|
||||
return &((SColumnRefNode*)pNode)->resType;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// There is only one parameter of numeric type, and the return type is parameter type
|
||||
static int32_t translateInOutNum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
} else if (IS_NULL_TYPE(paraType)) {
|
||||
|
@ -279,7 +290,7 @@ static int32_t translateInNumOutDou(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -294,8 +305,8 @@ static int32_t translateIn2NumOutDou(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) ||
|
||||
(!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -311,12 +322,12 @@ static int32_t translateInOutStr(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pPara1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pPara1->resType.type || !IS_STR_DATA_TYPE(pPara1->resType.type)) {
|
||||
SDataType* pRestType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pRestType->type || !IS_STR_DATA_TYPE(pRestType->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = pPara1->resType.bytes, .type = pPara1->resType.type};
|
||||
pFunc->node.resType = (SDataType){.bytes = pRestType->bytes, .type = pRestType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -325,8 +336,8 @@ static int32_t translateTrimStr(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pPara1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pPara1->resType.type || !IS_STR_DATA_TYPE(pPara1->resType.type)) {
|
||||
SDataType* pRestType1 = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pRestType1->type || !IS_STR_DATA_TYPE(pRestType1->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -340,8 +351,8 @@ static int32_t translateTrimStr(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
numOfSpaces = countTrailingSpaces(pValue, isLtrim);
|
||||
}
|
||||
|
||||
int32_t resBytes = pPara1->resType.bytes - numOfSpaces;
|
||||
pFunc->node.resType = (SDataType){.bytes = resBytes, .type = pPara1->resType.type};
|
||||
int32_t resBytes = pRestType1->bytes - numOfSpaces;
|
||||
pFunc->node.resType = (SDataType){.bytes = resBytes, .type = pRestType1->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -359,13 +370,13 @@ static int32_t translateLogarithm(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -388,7 +399,7 @@ static int32_t translateSum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -411,7 +422,7 @@ static int32_t translateAvgPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -425,7 +436,7 @@ static int32_t translateAvgMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -440,7 +451,7 @@ static int32_t translateStddevPartial(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -454,7 +465,7 @@ static int32_t translateStddevMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -513,7 +524,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -522,7 +533,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, i);
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -575,15 +586,15 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param2
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -622,15 +633,15 @@ static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param2
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -652,14 +663,14 @@ static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
if (3 != numOfParams && 2 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != para1Type || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -713,8 +724,8 @@ static int32_t translateTopBot(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -737,7 +748,7 @@ static int32_t translateTopBot(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
pValue->notReserved = true;
|
||||
|
||||
// set result type
|
||||
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
SDataType* pType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -767,7 +778,7 @@ static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -781,7 +792,7 @@ static int32_t translateSpreadImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (isPartial) {
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -857,7 +868,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -865,6 +876,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
// param1
|
||||
if (2 == numOfParams) {
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -873,7 +885,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -891,7 +903,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -932,13 +944,13 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = 64, .type = TSDB_DATA_TYPE_BINARY};
|
||||
pFunc->node.resType = (SDataType){.bytes = LEASTSQUARES_BUFF_LENGTH, .type = TSDB_DATA_TYPE_BINARY};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1126,15 +1138,15 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1 ~ param3
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1184,15 +1196,15 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1 ~ param3
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1238,7 +1250,7 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type != TSDB_DATA_TYPE_BINARY) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type != TSDB_DATA_TYPE_BINARY) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1303,7 +1315,7 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1326,9 +1338,9 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BIGINT &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BIGINT &&
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1343,7 +1355,7 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1369,14 +1381,14 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BIGINT &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BIGINT &&
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (numOfParams == 4 &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1404,7 +1416,7 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t resType;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1431,8 +1443,7 @@ static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
||||
|
@ -1446,7 +1457,7 @@ static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType) || !IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1460,8 +1471,8 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
SDataType* pSDataType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t colType = pSDataType->type;
|
||||
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
@ -1476,14 +1487,14 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// set result type
|
||||
if (IS_STR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
pFunc->node.resType = (SDataType){.bytes = pSDataType->bytes, .type = colType};
|
||||
} else {
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[colType].bytes, .type = colType};
|
||||
}
|
||||
|
@ -1497,8 +1508,8 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
SDataType* pSDataType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t colType = pSDataType->type;
|
||||
|
||||
// param1 & param2
|
||||
for (int32_t i = 1; i < numOfParams; ++i) {
|
||||
|
@ -1518,7 +1529,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1526,7 +1537,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
// set result type
|
||||
if (IS_STR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
pFunc->node.resType = (SDataType){.bytes = pSDataType->bytes, .type = colType};
|
||||
} else {
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[colType].bytes, .type = colType};
|
||||
}
|
||||
|
@ -1538,7 +1549,7 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
@ -1580,7 +1591,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1598,7 +1609,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (isPartial) {
|
||||
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1645,14 +1656,14 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if ((!IS_NUMERIC_TYPE(paraType) && !IS_BOOLEAN_TYPE(paraType)) || QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 1));
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType) || QUERY_NODE_VALUE != nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1726,26 +1737,26 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (IS_NULL_TYPE(paraType) && QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
pFunc->node.resType = *getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
// first(col_list) will be rewritten as first(col)
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||
if (isPartial) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
|
||||
uint8_t pType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t pType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (IS_NULL_TYPE(pType) && QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1800,7 +1811,7 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_INTEGER_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType &&
|
||||
!IS_TIMESTAMP_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1808,7 +1819,7 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
// param1
|
||||
if (numOfParams == 2) {
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1852,7 +1863,7 @@ static int32_t translateLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (!IS_STR_DATA_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type)) {
|
||||
if (!IS_STR_DATA_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1883,7 +1894,7 @@ static int32_t translateConcatImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
/* For concat/concat_ws function, if params have NCHAR type, promote the final result to NCHAR */
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
if (TSDB_DATA_TYPE_VARBINARY == paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1898,8 +1909,8 @@ static int32_t translateConcatImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||
int32_t factor = 1;
|
||||
if (IS_NULL_TYPE(paraType)) {
|
||||
resultType = TSDB_DATA_TYPE_VARCHAR;
|
||||
|
@ -2007,7 +2018,7 @@ static int32_t translateToIso8601(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
}
|
||||
|
||||
// param0
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2048,13 +2059,13 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (para1Type == TSDB_DATA_TYPE_VARBINARY || !IS_STR_DATA_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2085,8 +2096,8 @@ static int32_t translateToTimestamp(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
if (LIST_LENGTH(pFunc->pParameterList) != 2) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_STR_DATA_TYPE(para1Type) || !IS_STR_DATA_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2099,8 +2110,8 @@ static int32_t translateToChar(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
if (LIST_LENGTH(pFunc->pParameterList) != 2) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
// currently only support to_char(timestamp, str)
|
||||
if (!IS_STR_DATA_TYPE(para2Type) || !IS_TIMESTAMP_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2115,8 +2126,8 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_STR_DATA_TYPE(para1Type) && !IS_INTEGER_TYPE(para1Type) && !IS_TIMESTAMP_TYPE(para1Type)) ||
|
||||
!IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2134,7 +2145,7 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_INTEGER_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2169,14 +2180,14 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_STR_DATA_TYPE(paraType) && !IS_INTEGER_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
if (!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type)) {
|
||||
if (!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
@ -2224,7 +2235,7 @@ static int32_t translateInStrOutGeom(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_STR_DATA_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2239,7 +2250,7 @@ static int32_t translateInGeomOutStr(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (para1Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2254,8 +2265,8 @@ static int32_t translateIn2NumOutGeom(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) ||
|
||||
(!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2271,8 +2282,8 @@ static int32_t translateIn2GeomOutBool(SFunctionNode* pFunc, char* pErrBuf, int3
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((para1Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para1Type)) ||
|
||||
(para2Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2366,7 +2377,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = countFunction,
|
||||
.sprocessFunc = countScalarFunction,
|
||||
.finalizeFunc = functionFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = countInvertFunction,
|
||||
#endif
|
||||
.combineFunc = combineFunction,
|
||||
.pPartialFunc = "count",
|
||||
.pMergeFunc = "sum"
|
||||
|
@ -2382,7 +2395,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = sumFunction,
|
||||
.sprocessFunc = sumScalarFunction,
|
||||
.finalizeFunc = functionFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = sumInvertFunction,
|
||||
#endif
|
||||
.combineFunc = sumCombine,
|
||||
.pPartialFunc = "sum",
|
||||
.pMergeFunc = "sum"
|
||||
|
@ -2427,7 +2442,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = stddevFunction,
|
||||
.sprocessFunc = stddevScalarFunction,
|
||||
.finalizeFunc = stddevFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = stddevInvertFunction,
|
||||
#endif
|
||||
.combineFunc = stddevCombine,
|
||||
.pPartialFunc = "_stddev_partial",
|
||||
.pMergeFunc = "_stddev_merge"
|
||||
|
@ -2441,7 +2458,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = stddevFunctionSetup,
|
||||
.processFunc = stddevFunction,
|
||||
.finalizeFunc = stddevPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = stddevInvertFunction,
|
||||
#endif
|
||||
.combineFunc = stddevCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2453,7 +2472,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = stddevFunctionSetup,
|
||||
.processFunc = stddevFunctionMerge,
|
||||
.finalizeFunc = stddevFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = stddevInvertFunction,
|
||||
#endif
|
||||
.combineFunc = stddevCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2466,7 +2487,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = leastSQRFunction,
|
||||
.sprocessFunc = leastSQRScalarFunction,
|
||||
.finalizeFunc = leastSQRFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = leastSQRCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2480,7 +2503,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = avgFunction,
|
||||
.sprocessFunc = avgScalarFunction,
|
||||
.finalizeFunc = avgFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = avgInvertFunction,
|
||||
#endif
|
||||
.combineFunc = avgCombine,
|
||||
.pPartialFunc = "_avg_partial",
|
||||
.pMergeFunc = "_avg_merge"
|
||||
|
@ -2495,7 +2520,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = avgFunctionSetup,
|
||||
.processFunc = avgFunction,
|
||||
.finalizeFunc = avgPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = avgInvertFunction,
|
||||
#endif
|
||||
.combineFunc = avgCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2507,7 +2534,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = avgFunctionSetup,
|
||||
.processFunc = avgFunctionMerge,
|
||||
.finalizeFunc = avgFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = avgInvertFunction,
|
||||
#endif
|
||||
.combineFunc = avgCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2521,7 +2550,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = percentileFunction,
|
||||
.sprocessFunc = percentileScalarFunction,
|
||||
.finalizeFunc = percentileFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = NULL,
|
||||
},
|
||||
{
|
||||
|
@ -2534,7 +2565,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = apercentileFunction,
|
||||
.sprocessFunc = apercentileScalarFunction,
|
||||
.finalizeFunc = apercentileFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = apercentileCombine,
|
||||
.pPartialFunc = "_apercentile_partial",
|
||||
.pMergeFunc = "_apercentile_merge",
|
||||
|
@ -2549,7 +2582,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = apercentileFunctionSetup,
|
||||
.processFunc = apercentileFunction,
|
||||
.finalizeFunc = apercentilePartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = apercentileCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2561,7 +2596,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = apercentileFunctionSetup,
|
||||
.processFunc = apercentileFunctionMerge,
|
||||
.finalizeFunc = apercentileFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = apercentileCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2607,7 +2644,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = spreadFunction,
|
||||
.sprocessFunc = spreadScalarFunction,
|
||||
.finalizeFunc = spreadFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = spreadCombine,
|
||||
.pPartialFunc = "_spread_partial",
|
||||
.pMergeFunc = "_spread_merge"
|
||||
|
@ -2622,7 +2661,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = spreadFunctionSetup,
|
||||
.processFunc = spreadFunction,
|
||||
.finalizeFunc = spreadPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = spreadCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2635,7 +2676,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = spreadFunctionSetup,
|
||||
.processFunc = spreadFunctionMerge,
|
||||
.finalizeFunc = spreadFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = spreadCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2649,7 +2692,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = elapsedFunctionSetup,
|
||||
.processFunc = elapsedFunction,
|
||||
.finalizeFunc = elapsedFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = elapsedCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2662,7 +2707,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = elapsedFunctionSetup,
|
||||
.processFunc = elapsedFunction,
|
||||
.finalizeFunc = elapsedPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = elapsedCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2675,7 +2722,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = elapsedFunctionSetup,
|
||||
.processFunc = elapsedFunctionMerge,
|
||||
.finalizeFunc = elapsedFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = elapsedCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2905,7 +2954,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = histogramFunction,
|
||||
.sprocessFunc = histogramScalarFunction,
|
||||
.finalizeFunc = histogramFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = histogramCombine,
|
||||
.pPartialFunc = "_histogram_partial",
|
||||
.pMergeFunc = "_histogram_merge",
|
||||
|
@ -2919,7 +2970,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = histogramFunctionSetup,
|
||||
.processFunc = histogramFunctionPartial,
|
||||
.finalizeFunc = histogramPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = histogramCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2931,7 +2984,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = functionSetup,
|
||||
.processFunc = histogramFunctionMerge,
|
||||
.finalizeFunc = histogramFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = histogramCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2944,7 +2999,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = hllFunction,
|
||||
.sprocessFunc = hllScalarFunction,
|
||||
.finalizeFunc = hllFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = hllCombine,
|
||||
.pPartialFunc = "_hyperloglog_partial",
|
||||
.pMergeFunc = "_hyperloglog_merge"
|
||||
|
@ -2958,7 +3015,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = functionSetup,
|
||||
.processFunc = hllFunction,
|
||||
.finalizeFunc = hllPartialFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = hllCombine,
|
||||
},
|
||||
{
|
||||
|
@ -2970,7 +3029,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = functionSetup,
|
||||
.processFunc = hllFunctionMerge,
|
||||
.finalizeFunc = hllFinalize,
|
||||
#ifdef BUILD_NO_CALL
|
||||
.invertFunc = NULL,
|
||||
#endif
|
||||
.combineFunc = hllCombine,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -549,6 +549,7 @@ int32_t countFunction(SqlFunctionCtx* pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t countInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
int64_t numOfElem = getNumOfElems(pCtx);
|
||||
|
||||
|
@ -559,6 +560,7 @@ int32_t countInvertFunction(SqlFunctionCtx* pCtx) {
|
|||
SET_VAL(pResInfo, *((int64_t*)buf), 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t combineFunction(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||
|
@ -642,6 +644,7 @@ _sum_over:
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t sumInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = 0;
|
||||
|
||||
|
@ -699,6 +702,7 @@ int32_t sumInvertFunction(SqlFunctionCtx* pCtx) {
|
|||
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t sumCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||
|
@ -828,6 +832,7 @@ int32_t minmaxFunctionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t setNullSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t rowIndex) {
|
||||
if (pCtx->subsidiaries.num <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -843,6 +848,7 @@ int32_t setNullSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuplePos* pTuplePos, int32_t rowIndex) {
|
||||
if (pCtx->subsidiaries.num <= 0) {
|
||||
|
@ -1230,6 +1236,7 @@ int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t stddevInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = 0;
|
||||
|
||||
|
@ -1294,6 +1301,7 @@ int32_t stddevInvertFunction(SqlFunctionCtx* pCtx) {
|
|||
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
@ -1568,9 +1576,19 @@ int32_t leastSQRFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
|
||||
param12 /= param[1][1];
|
||||
|
||||
char buf[512] = {0};
|
||||
char buf[LEASTSQUARES_BUFF_LENGTH] = {0};
|
||||
char slopBuf[64] = {0};
|
||||
char interceptBuf[64] = {0};
|
||||
int n = snprintf(slopBuf, 64, "%.6lf", param02);
|
||||
if (n > LEASTSQUARES_DOUBLE_ITEM_LENGTH) {
|
||||
snprintf(slopBuf, 64, "%." DOUBLE_PRECISION_DIGITS, param02);
|
||||
}
|
||||
n = snprintf(interceptBuf, 64, "%.6lf", param12);
|
||||
if (n > LEASTSQUARES_DOUBLE_ITEM_LENGTH) {
|
||||
snprintf(interceptBuf, 64, "%." DOUBLE_PRECISION_DIGITS, param12);
|
||||
}
|
||||
size_t len =
|
||||
snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{slop:%.6lf, intercept:%.6lf}", param02, param12);
|
||||
snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{slop:%s, intercept:%s}", slopBuf, interceptBuf);
|
||||
varDataSetLen(buf, len);
|
||||
|
||||
colDataSetVal(pCol, currentRow, buf, pResInfo->isNullRes);
|
||||
|
@ -1578,11 +1596,6 @@ int32_t leastSQRFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t leastSQRInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
// TODO
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t leastSQRCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||
SLeastSQRInfo* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
||||
|
@ -2124,7 +2137,7 @@ bool getGroupKeyFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
|||
}
|
||||
|
||||
static FORCE_INLINE TSKEY getRowPTs(SColumnInfoData* pTsColInfo, int32_t rowIndex) {
|
||||
if (pTsColInfo == NULL) {
|
||||
if (pTsColInfo == NULL || pTsColInfo->pData == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -724,6 +724,7 @@ int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t avgInvertFunction(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElem = 0;
|
||||
|
||||
|
@ -786,6 +787,7 @@ int32_t avgInvertFunction(SqlFunctionCtx* pCtx) {
|
|||
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||
|
|
|
@ -281,6 +281,7 @@ void fmFuncMgtDestroy() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t fmSetInvertFunc(int32_t funcId, SFuncExecFuncs* pFpSet) {
|
||||
if (fmIsUserDefinedFunc(funcId) || funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -314,6 +315,7 @@ bool fmIsInvertible(int32_t funcId) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
// function has same input/output type
|
||||
bool fmIsSameInOutType(int32_t funcId) {
|
||||
|
|
|
@ -241,6 +241,29 @@ static SVgroupsInfo* vgroupsInfoClone(const SVgroupsInfo* pSrc) {
|
|||
return pDst;
|
||||
}
|
||||
|
||||
static SArray* functParamClone(const SArray* pSrc) {
|
||||
int32_t len = sizeof(SArray) + pSrc->capacity * pSrc->elemSize;
|
||||
|
||||
SArray* pDst = taosArrayInit(pSrc->capacity, pSrc->elemSize);
|
||||
if (NULL == pDst) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < TARRAY_SIZE(pSrc); ++i) {
|
||||
SFunctParam* pFunctParam = taosArrayGet(pSrc, i);
|
||||
SFunctParam* pNewFunctParam = (SFunctParam*)taosArrayPush(pDst, pFunctParam);
|
||||
|
||||
if (NULL == pNewFunctParam) {
|
||||
return NULL;
|
||||
}
|
||||
pNewFunctParam->type = pFunctParam->type;
|
||||
pNewFunctParam->pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
||||
memcpy(pNewFunctParam->pCol, pFunctParam->pCol, sizeof(SColumn));
|
||||
}
|
||||
|
||||
return pDst;
|
||||
}
|
||||
|
||||
|
||||
static int32_t realTableNodeCopy(const SRealTableNode* pSrc, SRealTableNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
|
||||
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
|
||||
|
@ -434,6 +457,7 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
|
|||
COPY_SCALAR_FIELD(onlyMetaCtbIdx);
|
||||
COPY_SCALAR_FIELD(filesetDelimited);
|
||||
COPY_SCALAR_FIELD(isCountByTag);
|
||||
CLONE_OBJECT_FIELD(pFuncTypes, functParamClone);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -475,6 +499,7 @@ static int32_t logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode
|
|||
CLONE_NODE_LIST_FIELD(pProjections);
|
||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||
COPY_SCALAR_FIELD(ignoreGroupId);
|
||||
COPY_SCALAR_FIELD(inputIgnoreGroup);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -717,6 +742,15 @@ static int32_t physiPartitionCopy(const SPartitionPhysiNode* pSrc, SPartitionPhy
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t physiProjectCopy(const SProjectPhysiNode* pSrc, SProjectPhysiNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, physiNodeCopy);
|
||||
CLONE_NODE_LIST_FIELD(pProjections);
|
||||
COPY_SCALAR_FIELD(mergeDataBlock);
|
||||
COPY_SCALAR_FIELD(ignoreGroupId);
|
||||
COPY_SCALAR_FIELD(inputIgnoreGroup);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
|
||||
COPY_SCALAR_FIELD(dataBlockId);
|
||||
CLONE_NODE_LIST_FIELD(pSlots);
|
||||
|
@ -951,6 +985,9 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||
code = physiPartitionCopy((const SPartitionPhysiNode*)pNode, (SPartitionPhysiNode*)pDst);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
code = physiProjectCopy((const SProjectPhysiNode*)pNode, (SProjectPhysiNode*)pDst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -786,6 +786,7 @@ static int32_t jsonToLogicScanNode(const SJson* pJson, void* pObj) {
|
|||
|
||||
static const char* jkProjectLogicPlanProjections = "Projections";
|
||||
static const char* jkProjectLogicPlanIgnoreGroupId = "IgnoreGroupId";
|
||||
static const char* jkProjectLogicPlanInputIgnoreGroup= "InputIgnoreGroup";
|
||||
|
||||
static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SProjectLogicNode* pNode = (const SProjectLogicNode*)pObj;
|
||||
|
@ -797,6 +798,9 @@ static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkProjectLogicPlanIgnoreGroupId, pNode->ignoreGroupId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkProjectLogicPlanInputIgnoreGroup, pNode->inputIgnoreGroup);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -811,7 +815,9 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkProjectLogicPlanIgnoreGroupId, &pNode->ignoreGroupId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkProjectLogicPlanInputIgnoreGroup, &pNode->inputIgnoreGroup);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1786,6 +1792,24 @@ static int32_t jsonToPhysiTagScanNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkLastRowScanPhysiPlanGroupTags = "GroupTags";
|
||||
static const char* jkLastRowScanPhysiPlanGroupSort = "GroupSort";
|
||||
static const char* jkLastRowScanPhysiPlanTargets = "Targets";
|
||||
static const char* jkLastRowScanPhysiPlanFuncType = "FuncType";
|
||||
static const char* jkLastRowScanPhysiPlanFuncTypes = "FuncTypes";
|
||||
|
||||
static int32_t funcTypeToJson(const void* pObj, SJson* pJson) {
|
||||
const int32_t* pNode = (const int32_t*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkLastRowScanPhysiPlanFuncType, *pNode);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToFuncType(const SJson* pJson, void* pObj) {
|
||||
int32_t* pNode = (int32_t*)pObj;
|
||||
|
||||
int32_t code = tjsonGetIntValue(pJson, jkLastRowScanPhysiPlanFuncType, pNode);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int32_t physiLastRowScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SLastRowScanPhysiNode* pNode = (const SLastRowScanPhysiNode*)pObj;
|
||||
|
@ -1800,6 +1824,9 @@ static int32_t physiLastRowScanNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkLastRowScanPhysiPlanTargets, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddTArray(pJson, jkLastRowScanPhysiPlanFuncTypes, funcTypeToJson, pNode->pFuncTypes);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1817,6 +1844,9 @@ static int32_t jsonToPhysiLastRowScanNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkLastRowScanPhysiPlanTargets, &pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonToTArray(pJson, jkLastRowScanPhysiPlanFuncTypes, jsonToFuncType, &pNode->pFuncTypes, sizeof(int32_t));
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2045,6 +2075,7 @@ static int32_t jsonToPhysiSysTableScanNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkProjectPhysiPlanProjections = "Projections";
|
||||
static const char* jkProjectPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||
static const char* jkProjectPhysiPlanIgnoreGroupId = "IgnoreGroupId";
|
||||
static const char* jkProjectPhysiPlanInputIgnoreGroup = "InputIgnoreGroup";
|
||||
|
||||
static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SProjectPhysiNode* pNode = (const SProjectPhysiNode*)pObj;
|
||||
|
@ -2059,7 +2090,9 @@ static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkProjectPhysiPlanIgnoreGroupId, pNode->ignoreGroupId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkProjectPhysiPlanInputIgnoreGroup, pNode->inputIgnoreGroup);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -2076,7 +2109,9 @@ static int32_t jsonToPhysiProjectNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkProjectPhysiPlanIgnoreGroupId, &pNode->ignoreGroupId);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkProjectPhysiPlanInputIgnoreGroup, &pNode->inputIgnoreGroup);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,3 +194,21 @@ bool nodesEqualNode(const SNode* a, const SNode* b) {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nodeListNodeEqual(const SNodeList* a, const SNode* b) {
|
||||
if (NULL == a || NULL == b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LIST_LENGTH(a) < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SNode *na;
|
||||
FOREACH(na, a) {
|
||||
if (nodesEqualNode(na, b)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -65,10 +65,14 @@ typedef int32_t (*FSetObject)(STlv* pTlv, void* pObj);
|
|||
|
||||
static int32_t nodeToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
static int32_t nodeListToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
static int32_t SArrayToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
|
||||
static int32_t msgToNode(STlvDecoder* pDecoder, void** pObj);
|
||||
static int32_t msgToNodeFromTlv(STlv* pTlv, void** pObj);
|
||||
static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj);
|
||||
static int32_t msgToNodeListFromTlv(STlv* pTlv, void** pObj);
|
||||
static int32_t msgToSArray(STlv* pTlv, void** pObj);
|
||||
|
||||
|
||||
static int32_t initTlvEncoder(STlvEncoder* pEncoder) {
|
||||
pEncoder->allocSize = NODES_MSG_DEFAULT_LEN;
|
||||
|
@ -2053,7 +2057,8 @@ enum {
|
|||
PHY_LAST_ROW_SCAN_CODE_GROUP_TAGS,
|
||||
PHY_LAST_ROW_SCAN_CODE_GROUP_SORT,
|
||||
PHY_LAST_ROW_SCAN_CODE_IGNULL,
|
||||
PHY_LAST_ROW_SCAN_CODE_TARGETS
|
||||
PHY_LAST_ROW_SCAN_CODE_TARGETS,
|
||||
PHY_LAST_ROW_SCAN_CODE_FUNCTYPES
|
||||
};
|
||||
|
||||
static int32_t physiLastRowScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
@ -2072,6 +2077,9 @@ static int32_t physiLastRowScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeObj(pEncoder, PHY_LAST_ROW_SCAN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeObj(pEncoder, PHY_LAST_ROW_SCAN_CODE_FUNCTYPES, SArrayToMsg, pNode->pFuncTypes);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2098,6 +2106,10 @@ static int32_t msgToPhysiLastRowScanNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_LAST_ROW_SCAN_CODE_TARGETS:
|
||||
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
|
||||
break;
|
||||
case PHY_LAST_ROW_SCAN_CODE_FUNCTYPES:
|
||||
code = msgToSArray(pTlv, (void**)&pNode->pFuncTypes);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2355,7 +2367,8 @@ enum {
|
|||
PHY_PROJECT_CODE_BASE_NODE = 1,
|
||||
PHY_PROJECT_CODE_PROJECTIONS,
|
||||
PHY_PROJECT_CODE_MERGE_DATA_BLOCK,
|
||||
PHY_PROJECT_CODE_IGNORE_GROUP_ID
|
||||
PHY_PROJECT_CODE_IGNORE_GROUP_ID,
|
||||
PHY_PROJECT_CODE_INPUT_IGNORE_GROUP
|
||||
};
|
||||
|
||||
static int32_t physiProjectNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
@ -2371,6 +2384,9 @@ static int32_t physiProjectNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, PHY_PROJECT_CODE_IGNORE_GROUP_ID, pNode->ignoreGroupId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, PHY_PROJECT_CODE_INPUT_IGNORE_GROUP, pNode->inputIgnoreGroup);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2394,6 +2410,9 @@ static int32_t msgToPhysiProjectNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_PROJECT_CODE_IGNORE_GROUP_ID:
|
||||
code = tlvDecodeBool(pTlv, &pNode->ignoreGroupId);
|
||||
break;
|
||||
case PHY_PROJECT_CODE_INPUT_IGNORE_GROUP:
|
||||
code = tlvDecodeBool(pTlv, &pNode->inputIgnoreGroup);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4461,6 +4480,31 @@ static int32_t nodeListToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
enum {
|
||||
SARRAY_CODE_CAPACITY = 1,
|
||||
SARRAY_CODE_ELEMSIZE,
|
||||
SARRAY_CODE_SIZE,
|
||||
SARRAY_CODE_PDATA
|
||||
};
|
||||
|
||||
static int32_t SArrayToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
const SArray* pArray = (const SArray*)pObj;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_CAPACITY, pArray->capacity);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_ELEMSIZE, pArray->elemSize);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_SIZE, pArray->size);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && pArray->capacity * pArray->elemSize > 0 && pArray->pData != NULL) {
|
||||
code = tlvEncodeBinary(pEncoder, SARRAY_CODE_PDATA, pArray->pData, pArray->capacity * pArray->elemSize);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj) {
|
||||
SNodeList* pList = nodesMakeList();
|
||||
|
@ -4481,6 +4525,67 @@ static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t msgToSArray(STlv* pTlv, void** pObj){
|
||||
SArray* pArray = NULL;
|
||||
uint32_t capacity = 0;
|
||||
uint32_t elemSize = 0;
|
||||
uint32_t actualSize;
|
||||
int32_t decodeFieldNum = 0;;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
STlvDecoder decoder = {.bufSize = pTlv->len, .offset = 0, .pBuf = pTlv->value};
|
||||
STlv* pTlvTemp = NULL;
|
||||
STlv* pDataTlv = NULL;
|
||||
|
||||
tlvForEach(&decoder, pTlvTemp, code) {
|
||||
switch (pTlvTemp->type) {
|
||||
case SARRAY_CODE_CAPACITY:
|
||||
code = tlvDecodeI32(pTlvTemp, &capacity);
|
||||
break;
|
||||
case SARRAY_CODE_ELEMSIZE:
|
||||
code = tlvDecodeI32(pTlvTemp, &elemSize);
|
||||
break;
|
||||
case SARRAY_CODE_SIZE:
|
||||
code = tlvDecodeI32(pTlvTemp, &actualSize);
|
||||
break;
|
||||
case SARRAY_CODE_PDATA:
|
||||
if (decodeFieldNum < 3) {
|
||||
pDataTlv = pTlvTemp;
|
||||
break;
|
||||
}
|
||||
pArray = taosArrayInit(capacity, elemSize);
|
||||
if (NULL == pArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pArray->size = actualSize;
|
||||
if (TSDB_CODE_SUCCESS != code || pTlvTemp == NULL) {
|
||||
taosArrayDestroy(pArray);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
code = tlvDecodeBinary(pTlvTemp, pArray->pData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
decodeFieldNum++;
|
||||
}
|
||||
|
||||
if (pDataTlv != NULL) {
|
||||
pArray = taosArrayInit(capacity, elemSize);
|
||||
if (NULL == pArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pArray->size = actualSize;
|
||||
if (TSDB_CODE_SUCCESS != code || pTlvTemp == NULL) {
|
||||
taosArrayDestroy(pArray);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
code = tlvDecodeBinary(pDataTlv, pArray->pData);
|
||||
}
|
||||
*pObj = pArray;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t msgToNodeListFromTlv(STlv* pTlv, void** pObj) {
|
||||
STlvDecoder decoder = {.bufSize = pTlv->len, .offset = 0, .pBuf = pTlv->value};
|
||||
return msgToNodeList(&decoder, pObj);
|
||||
|
|
|
@ -364,7 +364,7 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
case QUERY_NODE_LEFT_VALUE:
|
||||
return makeNode(type, sizeof(SLeftValueNode));
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return makeNode(type, sizeof(SColumnDefNode));
|
||||
return makeNode(type, sizeof(SColumnRefNode));
|
||||
case QUERY_NODE_WHEN_THEN:
|
||||
return makeNode(type, sizeof(SWhenThenNode));
|
||||
case QUERY_NODE_CASE_WHEN:
|
||||
|
@ -745,6 +745,8 @@ static void destroyTableCfg(STableCfg* pCfg) {
|
|||
|
||||
static void destroySmaIndex(void* pIndex) { taosMemoryFree(((STableIndexInfo*)pIndex)->expr); }
|
||||
|
||||
static void destroyFuncParam(void* pValue) { taosMemoryFree(((SFunctParam*)pValue)->pCol); }
|
||||
|
||||
static void destroyHintValue(EHintOption option, void* value) {
|
||||
switch (option) {
|
||||
default:
|
||||
|
@ -1250,6 +1252,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyList(pLogicNode->pGroupTags);
|
||||
nodesDestroyList(pLogicNode->pTags);
|
||||
nodesDestroyNode(pLogicNode->pSubtable);
|
||||
taosArrayDestroyEx(pLogicNode->pFuncTypes, destroyFuncParam);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN: {
|
||||
|
@ -1382,6 +1385,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
destroyScanPhysiNode((SScanPhysiNode*)pNode);
|
||||
nodesDestroyList(pPhyNode->pGroupTags);
|
||||
nodesDestroyList(pPhyNode->pTargets);
|
||||
taosArrayDestroy(pPhyNode->pFuncTypes);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
|
@ -2244,6 +2248,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
|||
FOREACH(pn, pCxt->pFuncs) {
|
||||
if (nodesEqualNode(pn, pNode)) {
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound) {
|
||||
|
@ -2266,6 +2271,20 @@ static int32_t funcNodeEqual(const void* pLeft, const void* pRight, size_t len)
|
|||
return nodesEqualNode(*(const SNode**)pLeft, *(const SNode**)pRight) ? 0 : 1;
|
||||
}
|
||||
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList* pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SCollectFuncsCxt cxt = {.errCode = TSDB_CODE_SUCCESS,
|
||||
.classifier = classifier,
|
||||
.tableAlias = tableAlias,
|
||||
.pFuncs = pFuncs};
|
||||
|
||||
nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
|
|
@ -370,6 +370,18 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
|||
return (SNode*)val;
|
||||
}
|
||||
|
||||
static bool hasHint(SNodeList* pHintList, EHintOption hint) {
|
||||
if (!pHintList) return false;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pHintList) {
|
||||
SHintNode* pHint = (SHintNode*)pNode;
|
||||
if (pHint->option == hint) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool addHintNodeToList(SAstCreateContext* pCxt, SNodeList** ppHintList, EHintOption opt, SToken* paramList,
|
||||
int32_t paramNum) {
|
||||
void* value = NULL;
|
||||
|
@ -383,6 +395,10 @@ bool addHintNodeToList(SAstCreateContext* pCxt, SNodeList** ppHintList, EHintOpt
|
|||
}
|
||||
case HINT_SORT_FOR_GROUP:
|
||||
if (paramNum > 0) return true;
|
||||
if (hasHint(*ppHintList, HINT_PARTITION_FIRST)) return true;
|
||||
break;
|
||||
case HINT_PARTITION_FIRST:
|
||||
if (paramNum > 0 || hasHint(*ppHintList, HINT_SORT_FOR_GROUP)) return true;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
|
@ -454,6 +470,14 @@ SNodeList* createHintNodeList(SAstCreateContext* pCxt, const SToken* pLiteral) {
|
|||
}
|
||||
opt = HINT_SORT_FOR_GROUP;
|
||||
break;
|
||||
case TK_PARTITION_FIRST:
|
||||
lastComma = false;
|
||||
if (0 != opt || inParamList) {
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
opt = HINT_PARTITION_FIRST;
|
||||
break;
|
||||
case TK_NK_LP:
|
||||
lastComma = false;
|
||||
if (0 == opt || inParamList) {
|
||||
|
|
|
@ -177,6 +177,7 @@ static SKeyword keywordTable[] = {
|
|||
{"PAGES", TK_PAGES},
|
||||
{"PAGESIZE", TK_PAGESIZE},
|
||||
{"PARTITION", TK_PARTITION},
|
||||
{"PARTITION_FIRST", TK_PARTITION_FIRST},
|
||||
{"PASS", TK_PASS},
|
||||
{"PORT", TK_PORT},
|
||||
{"PPS", TK_PPS},
|
||||
|
|
|
@ -1098,22 +1098,31 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
|
|||
static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** pCol, bool* pFound) {
|
||||
SNodeList* pProjectionList = getProjectListFromCurrStmt(pCxt->pCurrStmt);
|
||||
SNode* pNode;
|
||||
SNode* pFoundNode = NULL;
|
||||
*pFound = false;
|
||||
FOREACH(pNode, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
if (0 == strcmp((*pCol)->colName, pExpr->userAlias)) {
|
||||
SColumnRefNode* pColRef = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
if (NULL == pColRef) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
if (true == *pFound) {
|
||||
if(nodesEqualNode(pFoundNode, pNode)) {
|
||||
continue;
|
||||
}
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ORDERBY_AMBIGUOUS, (*pCol)->colName);
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
strcpy(pColRef->colName, pExpr->aliasName);
|
||||
nodesDestroyNode(*(SNode**)pCol);
|
||||
*(SNode**)pCol = (SNode*)pColRef;
|
||||
*pFound = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
pFoundNode = pNode;
|
||||
}
|
||||
}
|
||||
*pFound = false;
|
||||
if (*pFound) {
|
||||
SNode* pNew = nodesCloneNode(pFoundNode);
|
||||
if (NULL == pNew) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
nodesDestroyNode(*(SNode**)pCol);
|
||||
*(SNode**)pCol = (SNode*)pNew;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -2768,6 +2777,31 @@ static EDealRes doCheckAggColCoexist(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t checkIsEmptyResult(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (pSelect->timeRange.skey > pSelect->timeRange.ekey
|
||||
&& !pSelect->hasCountFunc) {
|
||||
pSelect->isEmptyResult = true;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t resetSelectFuncNumWithoutDup(SSelectStmt* pSelect) {
|
||||
if (pSelect->selectFuncNum <= 1) return TSDB_CODE_SUCCESS;
|
||||
pSelect->selectFuncNum = 0;
|
||||
SNodeList* pNodeList = nodesMakeList();
|
||||
int32_t code = nodesCollectSelectFuncs(pSelect, SQL_CLAUSE_FROM, NULL, fmIsSelectFunc, pNodeList);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(pNodeList);
|
||||
return code;
|
||||
}
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pNodeList) {
|
||||
pSelect->selectFuncNum = calcSelectFuncNum((SFunctionNode*)pNode, pSelect->selectFuncNum);
|
||||
}
|
||||
nodesDestroyList(pNodeList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow ||
|
||||
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
|
||||
|
@ -2781,7 +2815,8 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
if (!pSelect->isDistinct) {
|
||||
nodesRewriteExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
}
|
||||
if (1 == pSelect->selectFuncNum && !pSelect->hasOtherVectorFunc) {
|
||||
if (((!cxt.existCol && 0 < pSelect->selectFuncNum) || (cxt.existCol && 1 == pSelect->selectFuncNum) )
|
||||
&& !pSelect->hasOtherVectorFunc) {
|
||||
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
||||
}
|
||||
if (cxt.existCol) {
|
||||
|
@ -3293,7 +3328,11 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinPare
|
|||
((SSelectStmt*)pTempTable->pSubquery)->isEmptyResult && isSelectStmt(pCxt->pCurrStmt)) {
|
||||
((SSelectStmt*)pCxt->pCurrStmt)->isEmptyResult = true;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pTempTable->pSubquery) && isSelectStmt(pCxt->pCurrStmt)) {
|
||||
SSelectStmt* pSubStmt = (SSelectStmt*)pTempTable->pSubquery;
|
||||
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
|
||||
pCurrSmt->timeLineResMode = pSubStmt->timeLineResMode;
|
||||
}
|
||||
pTempTable->table.precision = getStmtPrecision(pTempTable->pSubquery);
|
||||
pTempTable->table.singleTable = stmtIsSingleTable(pTempTable->pSubquery);
|
||||
code = addNamespace(pCxt, pTempTable);
|
||||
|
@ -3592,13 +3631,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
|
|||
} else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
|
||||
} else {
|
||||
SColumnRefNode* pCol = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
if (NULL == pCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
strcpy(pCol->colName, ((SExprNode*)nodesListGetNode(pProjectionList, pos - 1))->aliasName);
|
||||
((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
|
||||
nodesDestroyNode(pExpr);
|
||||
// No longer using SColumnRefNode, processing in replaceOrderByAliasImpl function
|
||||
}
|
||||
} else {
|
||||
*pOther = true;
|
||||
|
@ -4543,9 +4576,6 @@ static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = getQueryTimeRange(pCxt, pSelect->pWhere, &pSelect->timeRange);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && pSelect->timeRange.skey > pSelect->timeRange.ekey) {
|
||||
pSelect->isEmptyResult = true;
|
||||
}
|
||||
if (pSelect->pWhere != NULL) {
|
||||
setTableVgroupsFromEqualTbnameCond(pCxt, pSelect);
|
||||
}
|
||||
|
@ -4621,12 +4651,12 @@ typedef struct SReplaceOrderByAliasCxt {
|
|||
|
||||
static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
||||
SReplaceOrderByAliasCxt* pCxt = pContext;
|
||||
if (QUERY_NODE_COLUMN_REF == nodeType(*pNode)) {
|
||||
SNodeList* pProjectionList = pCxt->pProjectionList;
|
||||
SNode* pProject = NULL;
|
||||
SNodeList* pProjectionList = pCxt->pProjectionList;
|
||||
SNode* pProject = NULL;
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
FOREACH(pProject, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pProject;
|
||||
if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->aliasName)) {
|
||||
if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->userAlias) && nodeType(*pNode) == nodeType(pProject)) {
|
||||
SNode* pNew = nodesCloneNode(pProject);
|
||||
if (NULL == pNew) {
|
||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -4638,7 +4668,29 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
} else if (QUERY_NODE_ORDER_BY_EXPR == nodeType(*pNode)) {
|
||||
STranslateContext* pTransCxt = pCxt->pTranslateCxt;
|
||||
SNode* pExpr = ((SOrderByExprNode*)*pNode)->pExpr;
|
||||
if (QUERY_NODE_VALUE == nodeType(pExpr)) {
|
||||
SValueNode* pVal = (SValueNode*)pExpr;
|
||||
if (DEAL_RES_ERROR == translateValue(pTransCxt, pVal)) {
|
||||
return pTransCxt->errCode;
|
||||
}
|
||||
int32_t pos = getPositionValue(pVal);
|
||||
if (0 < pos && pos <= LIST_LENGTH(pProjectionList)) {
|
||||
SNode* pNew = nodesCloneNode(nodesListGetNode(pProjectionList, pos - 1));
|
||||
if (NULL == pNew) {
|
||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
((SExprNode*)pNew)->orderAlias = true;
|
||||
((SOrderByExprNode*)*pNode)->pExpr = pNew;
|
||||
nodesDestroyNode(pExpr);
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -4711,6 +4763,10 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
code = translateOrderBy(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkIsEmptyResult(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
resetSelectFuncNumWithoutDup(pSelect);
|
||||
code = checkAggColCoexist(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -190,6 +190,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "invalid ip range";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
case TSDB_CODE_PAR_ORDERBY_AMBIGUOUS:
|
||||
return "ORDER BY \"%s\" is ambiguous";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
|
|
@ -413,6 +413,28 @@ TEST_F(ParserSelectTest, semanticCheck) {
|
|||
|
||||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 order by COUNT(*)");
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 order by last(c2)");
|
||||
|
||||
run("SELECT c1 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT ts FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT c2 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT * FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT last(ts) FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT last(ts), ts, c1 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT ts, last(ts) FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT first(ts), c2 FROM t1 order by last(c1)", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT c1 FROM t1 order by concat(c2, 'abc')");
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION);
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ int32_t validateQueryPlan(SPlanContext* pCxt, SQueryPlan* pPlan);
|
|||
|
||||
bool getBatchScanOptionFromHint(SNodeList* pList);
|
||||
bool getSortForGroupOptHint(SNodeList* pList);
|
||||
bool getOptHint(SNodeList* pList, EHintOption hint);
|
||||
SLogicNode* getLogicNodeRootNode(SLogicNode* pCurr);
|
||||
int32_t collectTableAliasFromNodes(SNode* pNode, SSHashObj** ppRes);
|
||||
bool isPartTableAgg(SAggLogicNode* pAgg);
|
||||
|
|
|
@ -2750,17 +2750,30 @@ static bool lastRowScanOptCheckColNum(int32_t lastColNum, col_id_t lastColId,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
||||
static bool isNeedSplitCacheLastFunc(SFunctionNode* pFunc, SScanLogicNode* pScan) {
|
||||
int32_t funcType = pFunc->funcType;
|
||||
if ((FUNCTION_TYPE_LAST_ROW != funcType || (FUNCTION_TYPE_LAST_ROW == funcType && TSDB_CACHE_MODEL_LAST_VALUE == pScan->cacheLastMode)) &&
|
||||
(FUNCTION_TYPE_LAST != funcType || (FUNCTION_TYPE_LAST == funcType && (TSDB_CACHE_MODEL_LAST_ROW == pScan->cacheLastMode ||
|
||||
QUERY_NODE_OPERATOR == nodeType(nodesListGetNode(pFunc->pParameterList, 0)) || QUERY_NODE_VALUE == nodeType(nodesListGetNode(pFunc->pParameterList, 0))))) &&
|
||||
FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, int8_t cacheLastModel, bool* hasOtherFunc) {
|
||||
bool hasNonPKSelectFunc = false;
|
||||
SNode* pFunc = NULL;
|
||||
int32_t lastColNum = 0, selectNonPKColNum = 0;
|
||||
col_id_t lastColId = -1, selectNonPKColId = -1;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(((SAggLogicNode*)pNode)->node.pChildren, 0);
|
||||
uint32_t needSplitFuncCount = 0;
|
||||
FOREACH(pFunc, ((SAggLogicNode*)pNode)->pAggFuncs) {
|
||||
SFunctionNode* pAggFunc = (SFunctionNode*)pFunc;
|
||||
SNode* pParam = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (FUNCTION_TYPE_LAST == pAggFunc->funcType) {
|
||||
SNode* pPar = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pPar)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pPar;
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pParam;
|
||||
if (pCol->colType != COLUMN_TYPE_COLUMN) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2769,13 +2782,18 @@ static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
|||
lastColNum++;
|
||||
}
|
||||
}
|
||||
if (QUERY_NODE_VALUE == nodeType(nodesListGetNode(pAggFunc->pParameterList, 0))) {
|
||||
else if (QUERY_NODE_VALUE == nodeType(pParam) || QUERY_NODE_OPERATOR == nodeType(pParam)) {
|
||||
needSplitFuncCount++;
|
||||
*hasOtherFunc = true;
|
||||
}
|
||||
if (!lastRowScanOptCheckColNum(lastColNum, lastColId, selectNonPKColNum, selectNonPKColId)) {
|
||||
return false;
|
||||
}
|
||||
if (!lastRowScanOptCheckColNum(lastColNum, lastColId, selectNonPKColNum, selectNonPKColId))
|
||||
return false;
|
||||
if (TSDB_CACHE_MODEL_LAST_ROW == cacheLastModel) {
|
||||
needSplitFuncCount++;
|
||||
*hasOtherFunc = true;
|
||||
}
|
||||
} else if (FUNCTION_TYPE_SELECT_VALUE == pAggFunc->funcType) {
|
||||
SNode* pParam = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pParam;
|
||||
if (COLUMN_TYPE_COLUMN == pCol->colType && PRIMARYKEY_TIMESTAMP_COL_ID != pCol->colId) {
|
||||
|
@ -2797,15 +2815,21 @@ static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
|||
}
|
||||
} else if (FUNCTION_TYPE_LAST_ROW != pAggFunc->funcType) {
|
||||
*hasOtherFunc = true;
|
||||
needSplitFuncCount++;
|
||||
} else if (FUNCTION_TYPE_LAST_ROW == pAggFunc->funcType && TSDB_CACHE_MODEL_LAST_VALUE == cacheLastModel) {
|
||||
*hasOtherFunc = true;
|
||||
needSplitFuncCount++;
|
||||
}
|
||||
}
|
||||
if (needSplitFuncCount >= ((SAggLogicNode*)pNode)->pAggFuncs->length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckLastCache(SAggLogicNode* pAgg, SScanLogicNode* pScan) {
|
||||
// Only one of LAST and LASTROW can appear
|
||||
if (pAgg->hasLastRow == pAgg->hasLast || (!pAgg->hasLast && !pAgg->hasLastRow) || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
if ((pAgg->hasLastRow == pAgg->hasLast && !pAgg->hasLastRow) || (!pAgg->hasLast && !pAgg->hasLastRow) || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
!hasSuitableCache(pScan->cacheLastMode, pAgg->hasLastRow, pAgg->hasLast) ||
|
||||
IS_TSWINDOW_SPECIFIED(pScan->scanRange)) {
|
||||
return false;
|
||||
|
@ -2827,7 +2851,7 @@ static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
|||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
if (!lastRowScanOptCheckFuncList(pNode, pScan->cacheLastMode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2842,6 +2866,7 @@ typedef struct SLastRowScanOptSetColDataTypeCxt {
|
|||
bool doAgg;
|
||||
SNodeList* pLastCols;
|
||||
SNodeList* pOtherCols;
|
||||
int32_t funcType;
|
||||
} SLastRowScanOptSetColDataTypeCxt;
|
||||
|
||||
static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) {
|
||||
|
@ -2864,7 +2889,7 @@ static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCols, bool erase) {
|
||||
static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCols, SNodeList* pLastRowCols, bool erase) {
|
||||
SNode* pTarget = NULL;
|
||||
WHERE_EACH(pTarget, pTargets) {
|
||||
bool found = false;
|
||||
|
@ -2876,6 +2901,10 @@ static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCo
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!found && nodeListNodeEqual(pLastRowCols, pTarget)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found && erase) {
|
||||
ERASE_NODE(pTargets);
|
||||
continue;
|
||||
|
@ -2884,7 +2913,7 @@ static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCo
|
|||
}
|
||||
}
|
||||
|
||||
static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pList1, SNodeList* pList2) {
|
||||
static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pList1, SNodeList* pList2, SNodeList* pList3) {
|
||||
SNode* pTarget = NULL;
|
||||
WHERE_EACH(pTarget, pTargets) {
|
||||
bool found = false;
|
||||
|
@ -2903,6 +2932,11 @@ static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pL
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && nodeListNodeEqual(pList3, pTarget)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ERASE_NODE(pTargets);
|
||||
continue;
|
||||
|
@ -2911,6 +2945,33 @@ static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pL
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t lastRowScanBuildFuncTypes(SScanLogicNode* pScan, SColumnNode* pColNode, int32_t funcType) {
|
||||
SFunctParam* pFuncTypeParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
if (NULL == pFuncTypeParam) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pFuncTypeParam->type = funcType;
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
pScan->pFuncTypes = taosArrayInit(pScan->pScanCols->length, sizeof(SFunctParam));
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
pFuncTypeParam->pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
||||
if (NULL == pFuncTypeParam->pCol) {
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pFuncTypeParam->pCol->colId = pColNode->colId;
|
||||
strcpy(pFuncTypeParam->pCol->name, pColNode->colName);
|
||||
taosArrayPush(pScan->pFuncTypes, pFuncTypeParam);
|
||||
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, lastRowScanOptMayBeOptimized);
|
||||
|
||||
|
@ -2922,10 +2983,16 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
SNode* pNode = NULL;
|
||||
SColumnNode* pPKTsCol = NULL;
|
||||
SColumnNode* pNonPKCol = NULL;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
pScan->scanType = SCAN_TYPE_LAST_ROW;
|
||||
pScan->igLastNull = pAgg->hasLast ? true : false;
|
||||
SArray* isDuplicateCol = taosArrayInit(pScan->pScanCols->length, sizeof(bool));
|
||||
SNodeList* pLastRowCols = NULL;
|
||||
|
||||
FOREACH(pNode, pAgg->pAggFuncs) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
int32_t funcType = pFunc->funcType;
|
||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (FUNCTION_TYPE_LAST_ROW == funcType || FUNCTION_TYPE_LAST == funcType) {
|
||||
int32_t len = snprintf(pFunc->functionName, sizeof(pFunc->functionName),
|
||||
FUNCTION_TYPE_LAST_ROW == funcType ? "_cache_last_row" : "_cache_last");
|
||||
|
@ -2935,6 +3002,61 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
nodesClearList(cxt.pLastCols);
|
||||
return code;
|
||||
}
|
||||
cxt.funcType = pFunc->funcType;
|
||||
// add duplicate cols which be removed for both last_row, last
|
||||
if (pAgg->hasLast && pAgg->hasLastRow) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParamNode)) {
|
||||
SNode* pColNode = NULL;
|
||||
int i = 0;
|
||||
FOREACH(pColNode, pScan->pScanCols) {
|
||||
bool isDup = false;
|
||||
bool* isDuplicate = taosArrayGet(isDuplicateCol, i);
|
||||
if (NULL == isDuplicate) {
|
||||
taosArrayInsert(isDuplicateCol, i, &isDup);
|
||||
isDuplicate = taosArrayGet(isDuplicateCol, i);
|
||||
}
|
||||
i++;
|
||||
if (nodesEqualNode(pParamNode, pColNode)) {
|
||||
if (*isDuplicate) {
|
||||
if (0 == strncmp(((SColumnNode*)pColNode)->colName, "#dup_col.", 9)) {
|
||||
continue;
|
||||
}
|
||||
SNode* newColNode = nodesCloneNode(pColNode);
|
||||
sprintf(((SColumnNode*)newColNode)->colName, "#dup_col.%p", newColNode);
|
||||
sprintf(((SColumnNode*)pParamNode)->colName, "#dup_col.%p", newColNode);
|
||||
|
||||
nodesListAppend(pScan->pScanCols, newColNode);
|
||||
isDup = true;
|
||||
taosArrayInsert(isDuplicateCol, pScan->pScanCols->length, &isDup);
|
||||
nodesListAppend(pScan->node.pTargets, nodesCloneNode(newColNode));
|
||||
if (funcType != FUNCTION_TYPE_LAST) {
|
||||
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(newColNode));
|
||||
}
|
||||
|
||||
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)newColNode, pFunc->funcType);
|
||||
} else {
|
||||
isDup = true;
|
||||
*isDuplicate = isDup;
|
||||
if (funcType != FUNCTION_TYPE_LAST && !nodeListNodeEqual(cxt.pLastCols, pColNode)) {
|
||||
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
|
||||
}
|
||||
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
|
||||
}
|
||||
continue;
|
||||
}else if (nodeListNodeEqual(pFunc->pParameterList, pColNode)) {
|
||||
if (funcType != FUNCTION_TYPE_LAST && ((SColumnNode*)pColNode)->colId == PRIMARYKEY_TIMESTAMP_COL_ID &&
|
||||
!nodeListNodeEqual(pLastRowCols, pColNode)) {
|
||||
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
|
||||
|
||||
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
|
||||
isDup = true;
|
||||
*isDuplicate = isDup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FUNCTION_TYPE_LAST == funcType) {
|
||||
nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt);
|
||||
nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1));
|
||||
|
@ -2956,15 +3078,13 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
}
|
||||
}
|
||||
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
pScan->scanType = SCAN_TYPE_LAST_ROW;
|
||||
pScan->igLastNull = pAgg->hasLast ? true : false;
|
||||
if (NULL != cxt.pLastCols) {
|
||||
cxt.doAgg = false;
|
||||
lastRowScanOptSetLastTargets(pScan->pScanCols, cxt.pLastCols, true);
|
||||
cxt.funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
lastRowScanOptSetLastTargets(pScan->pScanCols, cxt.pLastCols, pLastRowCols, true);
|
||||
nodesWalkExprs(pScan->pScanPseudoCols, lastRowScanOptSetColDataType, &cxt);
|
||||
lastRowScanOptSetLastTargets(pScan->node.pTargets, cxt.pLastCols, false);
|
||||
lastRowScanOptRemoveUslessTargets(pScan->node.pTargets, cxt.pLastCols, cxt.pOtherCols);
|
||||
lastRowScanOptSetLastTargets(pScan->node.pTargets, cxt.pLastCols, pLastRowCols, false);
|
||||
lastRowScanOptRemoveUslessTargets(pScan->node.pTargets, cxt.pLastCols, cxt.pOtherCols, pLastRowCols);
|
||||
if (pPKTsCol && pScan->node.pTargets->length == 1) {
|
||||
// when select last(ts),ts from ..., we add another ts to targets
|
||||
sprintf(pPKTsCol->colName, "#sel_val.%p", pPKTsCol);
|
||||
|
@ -2977,10 +3097,12 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
}
|
||||
nodesClearList(cxt.pLastCols);
|
||||
}
|
||||
|
||||
pAgg->hasLastRow = false;
|
||||
pAgg->hasLast = false;
|
||||
|
||||
pCxt->optimized = true;
|
||||
taosArrayDestroy(isDuplicateCol);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2998,7 +3120,7 @@ static bool splitCacheLastFuncOptMayBeOptimized(SLogicNode* pNode) {
|
|||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
if (!lastRowScanOptCheckFuncList(pNode, pScan->cacheLastMode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3019,6 +3141,16 @@ static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg,
|
|||
|
||||
pNew->hasLastRow = false;
|
||||
pNew->hasLast = false;
|
||||
SNode* pFuncNode = NULL;
|
||||
FOREACH(pFuncNode, pFunc) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pFuncNode;
|
||||
if (FUNCTION_TYPE_LAST_ROW == pFunc->funcType) {
|
||||
pNew->hasLastRow = true;
|
||||
} else if (FUNCTION_TYPE_LAST == pFunc->funcType) {
|
||||
pNew->hasLast = true;
|
||||
}
|
||||
}
|
||||
|
||||
pNew->hasTimeLineFunc = pAgg->hasTimeLineFunc;
|
||||
pNew->hasGroupKeyOptimized = false;
|
||||
pNew->onlyHasKeepOrderFunc = pAgg->onlyHasKeepOrderFunc;
|
||||
|
@ -3143,21 +3275,31 @@ static int32_t splitCacheLastFuncOptimize(SOptimizeContext* pCxt, SLogicSubplan*
|
|||
if (NULL == pAgg) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
SNode* pNode = NULL;
|
||||
SNodeList* pAggFuncList = NULL;
|
||||
|
||||
{
|
||||
bool hasLast = false;
|
||||
bool hasLastRow = false;
|
||||
WHERE_EACH(pNode, pAgg->pAggFuncs) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
int32_t funcType = pFunc->funcType;
|
||||
if (FUNCTION_TYPE_LAST_ROW != funcType && FUNCTION_TYPE_LAST != funcType &&
|
||||
FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) {
|
||||
|
||||
if (isNeedSplitCacheLastFunc(pFunc, pScan)) {
|
||||
nodesListMakeStrictAppend(&pAggFuncList, nodesCloneNode(pNode));
|
||||
ERASE_NODE(pAgg->pAggFuncs);
|
||||
continue;
|
||||
}
|
||||
if (FUNCTION_TYPE_LAST_ROW == funcType ) {
|
||||
hasLastRow = true;
|
||||
} else if (FUNCTION_TYPE_LAST == funcType) {
|
||||
hasLast = true;
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
pAgg->hasLast = hasLast;
|
||||
pAgg->hasLastRow = hasLastRow;
|
||||
}
|
||||
|
||||
if (NULL == pAggFuncList) {
|
||||
|
@ -3229,6 +3371,7 @@ static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) {
|
|||
NULL != pChild->pConditions || NULL != pChild->pLimit || NULL != pChild->pSlimit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3267,7 +3410,9 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
|
|||
|
||||
static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pSelfNode) {
|
||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSelfNode->pChildren, 0);
|
||||
|
||||
if (((SProjectLogicNode*)pChild)->ignoreGroupId) {
|
||||
((SProjectLogicNode*)pSelfNode)->inputIgnoreGroup = true;
|
||||
}
|
||||
SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS};
|
||||
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt);
|
||||
int32_t code = cxt.errCode;
|
||||
|
@ -3432,7 +3577,11 @@ static bool pushDownLimitTo(SLogicNode* pNodeWithLimit, SLogicNode* pNodeLimitPu
|
|||
}
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
if (nodeType(pNodeWithLimit) == QUERY_NODE_LOGIC_PLAN_PROJECT && pNodeWithLimit->pLimit) {
|
||||
swapLimit(pNodeWithLimit, pNodeLimitPushTo);
|
||||
if (((SProjectLogicNode*)pNodeWithLimit)->inputIgnoreGroup) {
|
||||
cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_LIMIT);
|
||||
} else {
|
||||
swapLimit(pNodeWithLimit, pNodeLimitPushTo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
@ -4247,7 +4396,8 @@ static int32_t partitionColsOpt(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
|||
}
|
||||
}
|
||||
return code;
|
||||
} else if (pNode->node.pParent && nodeType(pNode->node.pParent) == QUERY_NODE_LOGIC_PLAN_AGG) {
|
||||
} else if (pNode->node.pParent && nodeType(pNode->node.pParent) == QUERY_NODE_LOGIC_PLAN_AGG &&
|
||||
!getOptHint(pRootNode->pHint, HINT_PARTITION_FIRST)) {
|
||||
// Check if we can delete partition node
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)pNode->node.pParent;
|
||||
FOREACH(node, pNode->pPartitionKeys) {
|
||||
|
|
|
@ -562,9 +562,36 @@ static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSu
|
|||
|
||||
pScan->groupSort = pScanLogicNode->groupSort;
|
||||
pScan->ignoreNull = pScanLogicNode->igLastNull;
|
||||
|
||||
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
|
||||
|
||||
return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode);
|
||||
int32_t code = createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && pScanLogicNode->pFuncTypes != NULL) {
|
||||
pScan->pFuncTypes = taosArrayInit(taosArrayGetSize(pScanLogicNode->pFuncTypes), sizeof(int32_t));
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SNode* pTargetNode = NULL;
|
||||
int funcTypeIndex = 0;
|
||||
FOREACH(pTargetNode, ((SScanPhysiNode*)pScan)->pScanCols) {
|
||||
if (((STargetNode*)pTargetNode)->pExpr->type != QUERY_NODE_COLUMN) {
|
||||
continue;
|
||||
}
|
||||
SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pTargetNode)->pExpr;
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(pScanLogicNode->pFuncTypes); ++i) {
|
||||
SFunctParam* pFunctParam = taosArrayGet(pScanLogicNode->pFuncTypes, i);
|
||||
if (pColNode->colId == pFunctParam->pCol->colId &&
|
||||
0 == strncmp(pColNode->colName, pFunctParam->pCol->name, strlen(pColNode->colName))) {
|
||||
taosArrayInsert(pScan->pFuncTypes, funcTypeIndex, &pFunctParam->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
funcTypeIndex++;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createTableCountScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
|
||||
|
@ -1564,6 +1591,7 @@ static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChild
|
|||
|
||||
pProject->mergeDataBlock = projectCanMergeDataBlock(pProjectLogicNode);
|
||||
pProject->ignoreGroupId = pProjectLogicNode->ignoreGroupId;
|
||||
pProject->inputIgnoreGroup = pProjectLogicNode->inputIgnoreGroup;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (0 == LIST_LENGTH(pChildren)) {
|
||||
|
|
|
@ -1164,8 +1164,10 @@ static int32_t stbSplSplitSortNode(SSplitContext* pCxt, SStableSplitInfo* pInfo)
|
|||
|
||||
static int32_t stbSplGetSplitNodeForScan(SStableSplitInfo* pInfo, SLogicNode** pSplitNode) {
|
||||
*pSplitNode = pInfo->pSplitNode;
|
||||
if (NULL != pInfo->pSplitNode->pParent && QUERY_NODE_LOGIC_PLAN_PROJECT == nodeType(pInfo->pSplitNode->pParent) &&
|
||||
NULL == pInfo->pSplitNode->pParent->pLimit && NULL == pInfo->pSplitNode->pParent->pSlimit) {
|
||||
if (NULL != pInfo->pSplitNode->pParent &&
|
||||
QUERY_NODE_LOGIC_PLAN_PROJECT == nodeType(pInfo->pSplitNode->pParent) &&
|
||||
NULL == pInfo->pSplitNode->pParent->pLimit && NULL == pInfo->pSplitNode->pParent->pSlimit &&
|
||||
!((SProjectLogicNode*)pInfo->pSplitNode->pParent)->inputIgnoreGroup) {
|
||||
*pSplitNode = pInfo->pSplitNode->pParent;
|
||||
if (NULL != pInfo->pSplitNode->pLimit) {
|
||||
(*pSplitNode)->pLimit = nodesCloneNode(pInfo->pSplitNode->pLimit);
|
||||
|
|
|
@ -432,6 +432,7 @@ bool getBatchScanOptionFromHint(SNodeList* pList) {
|
|||
}
|
||||
|
||||
bool getSortForGroupOptHint(SNodeList* pList) {
|
||||
if (!pList) return false;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pList) {
|
||||
SHintNode* pHint = (SHintNode*)pNode;
|
||||
|
@ -442,6 +443,18 @@ bool getSortForGroupOptHint(SNodeList* pList) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool getOptHint(SNodeList* pList, EHintOption hint) {
|
||||
if (!pList) return false;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pList) {
|
||||
SHintNode* pHint = (SHintNode*)pNode;
|
||||
if (pHint->option == hint) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t collectTableAliasFromNodes(SNode* pNode, SSHashObj** ppRes) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SLogicNode* pCurr = (SLogicNode*)pNode;
|
||||
|
|
|
@ -2427,9 +2427,19 @@ int32_t leastSQRScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPa
|
|||
|
||||
matrix12 /= matrix[1][1];
|
||||
|
||||
char buf[64] = {0};
|
||||
size_t len = snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{slop:%.6lf, intercept:%.6lf}", matrix02,
|
||||
matrix12);
|
||||
char buf[LEASTSQUARES_BUFF_LENGTH] = {0};
|
||||
char slopBuf[64] = {0};
|
||||
char interceptBuf[64] = {0};
|
||||
int n = snprintf(slopBuf, 64, "%.6lf", matrix02);
|
||||
if (n > LEASTSQUARES_DOUBLE_ITEM_LENGTH) {
|
||||
snprintf(slopBuf, 64, "%." DOUBLE_PRECISION_DIGITS, matrix02);
|
||||
}
|
||||
n = snprintf(interceptBuf, 64, "%.6lf", matrix12);
|
||||
if (n > LEASTSQUARES_DOUBLE_ITEM_LENGTH) {
|
||||
snprintf(interceptBuf, 64, "%." DOUBLE_PRECISION_DIGITS, matrix12);
|
||||
}
|
||||
size_t len =
|
||||
snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{slop:%s, intercept:%s}", slopBuf, interceptBuf);
|
||||
varDataSetLen(buf, len);
|
||||
colDataSetVal(pOutputData, 0, buf, false);
|
||||
}
|
||||
|
|
|
@ -52,10 +52,10 @@ typedef enum {
|
|||
SCH_ALL,
|
||||
} SCH_POLICY;
|
||||
|
||||
#define SCHEDULE_DEFAULT_MAX_JOB_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_MAX_TASK_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_POLICY SCH_LOAD_SEQ
|
||||
#define SCHEDULE_DEFAULT_MAX_NODE_NUM 20
|
||||
#define SCHEDULE_DEFAULT_MAX_JOB_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_MAX_TASK_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_POLICY SCH_LOAD_SEQ
|
||||
#define SCHEDULE_DEFAULT_MAX_NODE_NUM 20
|
||||
|
||||
#define SCH_DEFAULT_TASK_TIMEOUT_USEC 5000000
|
||||
#define SCH_MAX_TASK_TIMEOUT_USEC 300000000
|
||||
|
@ -68,8 +68,9 @@ typedef struct SSchDebug {
|
|||
} SSchDebug;
|
||||
|
||||
typedef struct SSchTrans {
|
||||
void *pTrans;
|
||||
void *pHandle;
|
||||
void *pTrans;
|
||||
void *pHandle;
|
||||
int64_t pHandleId;
|
||||
} SSchTrans;
|
||||
|
||||
typedef struct SSchHbTrans {
|
||||
|
@ -299,7 +300,7 @@ typedef struct SSchJob {
|
|||
void *fetchRes; // TODO free it or not
|
||||
bool fetched;
|
||||
bool noMoreRetry;
|
||||
int64_t resNumOfRows; // from int32_t to int64_t
|
||||
int64_t resNumOfRows; // from int32_t to int64_t
|
||||
SSchResInfo userRes;
|
||||
char *sql;
|
||||
SQueryProfileSummary summary;
|
||||
|
@ -334,14 +335,15 @@ extern SSchedulerMgmt schMgmt;
|
|||
(!SCH_IS_DATA_BIND_QRY_TASK(_task)))
|
||||
|
||||
#define SCH_UPDATE_REDIRECT_CODE(job, _code) atomic_val_compare_exchange_32(&((job)->redirectCode), 0, _code)
|
||||
#define SCH_GET_REDIRECT_CODE(job, _code) (((!NO_RET_REDIRECT_ERROR(_code)) || (job)->redirectCode == 0) ? (_code) : (job)->redirectCode)
|
||||
#define SCH_GET_REDIRECT_CODE(job, _code) \
|
||||
(((!NO_RET_REDIRECT_ERROR(_code)) || (job)->redirectCode == 0) ? (_code) : (job)->redirectCode)
|
||||
|
||||
#define SCH_SET_TASK_STATUS(task, st) atomic_store_8(&(task)->status, st)
|
||||
#define SCH_GET_TASK_STATUS(task) atomic_load_8(&(task)->status)
|
||||
#define SCH_GET_TASK_STATUS_STR(task) jobTaskStatusStr(SCH_GET_TASK_STATUS(task))
|
||||
|
||||
#define SCH_TASK_ALREADY_LAUNCHED(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_EXEC)
|
||||
#define SCH_TASK_EXEC_DONE(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_PART_SUCC)
|
||||
#define SCH_TASK_EXEC_DONE(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_PART_SUCC)
|
||||
|
||||
#define SCH_GET_TASK_HANDLE(_task) ((_task) ? (_task)->handle : NULL)
|
||||
#define SCH_SET_TASK_HANDLE(_task, _handle) ((_task)->handle = (_handle))
|
||||
|
@ -362,8 +364,8 @@ extern SSchedulerMgmt schMgmt;
|
|||
#define SCH_JOB_NEED_FLOW_CTRL(_job) ((_job)->attr.needFlowCtrl)
|
||||
#define SCH_TASK_NEED_FLOW_CTRL(_job, _task) \
|
||||
(SCH_IS_DATA_BIND_QRY_TASK(_task) && SCH_JOB_NEED_FLOW_CTRL(_job) && SCH_IS_LEVEL_UNFINISHED((_task)->level))
|
||||
#define SCH_FETCH_TYPE(_pSrcTask) (SCH_IS_DATA_BIND_QRY_TASK(_pSrcTask) ? TDMT_SCH_FETCH : TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_TASK_NEED_FETCH(_task) ((_task)->plan->subplanType != SUBPLAN_TYPE_MODIFY)
|
||||
#define SCH_FETCH_TYPE(_pSrcTask) (SCH_IS_DATA_BIND_QRY_TASK(_pSrcTask) ? TDMT_SCH_FETCH : TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_TASK_NEED_FETCH(_task) ((_task)->plan->subplanType != SUBPLAN_TYPE_MODIFY)
|
||||
#define SCH_MULTI_LEVEL_LAUNCHED(_job) ((_job)->levelIdx != ((_job)->levelNum - 1))
|
||||
|
||||
#define SCH_SET_JOB_TYPE(_job, type) \
|
||||
|
@ -380,25 +382,26 @@ extern SSchedulerMgmt schMgmt;
|
|||
#define SCH_JOB_NEED_WAIT(_job) (!SCH_IS_QUERY_JOB(_job))
|
||||
#define SCH_JOB_NEED_DROP(_job) (SCH_IS_QUERY_JOB(_job))
|
||||
#define SCH_IS_EXPLAIN_JOB(_job) (EXPLAIN_MODE_ANALYZE == (_job)->attr.explainMode)
|
||||
#define SCH_NETWORK_ERR(_code) ((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define SCH_NETWORK_ERR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
||||
(_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define SCH_REDIRECT_MSGTYPE(_msgType) \
|
||||
((_msgType) == TDMT_SCH_LINK_BROKEN || (_msgType) == TDMT_SCH_QUERY || (_msgType) == TDMT_SCH_MERGE_QUERY || \
|
||||
(_msgType) == TDMT_SCH_FETCH || (_msgType) == TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_LOW_LEVEL_NETWORK_ERR(_job, _task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level == (_job)->levelIdx))
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level == (_job)->levelIdx))
|
||||
#define SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level > (_job)->levelIdx))
|
||||
#define SCH_TASK_RETRY_NETWORK_ERR(_task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && (_task)->redirectCtx.inRedirect)
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level > (_job)->levelIdx))
|
||||
#define SCH_TASK_RETRY_NETWORK_ERR(_task, _code) (SCH_NETWORK_ERR(_code) && (_task)->redirectCtx.inRedirect)
|
||||
|
||||
#define SCH_JOB_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code))
|
||||
#define SCH_TASKSET_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && \
|
||||
(NEED_SCHEDULER_REDIRECT_ERROR(_code) || SCH_LOW_LEVEL_NETWORK_ERR((_job), (_task), (_code)) || SCH_TASK_RETRY_NETWORK_ERR((_task), (_code))))
|
||||
#define SCH_JOB_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code))
|
||||
#define SCH_TASKSET_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && \
|
||||
(NEED_SCHEDULER_REDIRECT_ERROR(_code) || SCH_LOW_LEVEL_NETWORK_ERR((_job), (_task), (_code)) || \
|
||||
SCH_TASK_RETRY_NETWORK_ERR((_task), (_code))))
|
||||
#define SCH_TASK_NEED_RETRY(_msgType, _code) \
|
||||
((SCH_REDIRECT_MSGTYPE(_msgType) && SCH_NETWORK_ERR(_code)) || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
|
||||
((SCH_REDIRECT_MSGTYPE(_msgType) && SCH_NETWORK_ERR(_code)) || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
|
||||
#define SCH_IS_LEVEL_UNFINISHED(_level) ((_level)->taskLaunchedNum < (_level)->taskNum)
|
||||
#define SCH_GET_CUR_EP(_addr) (&(_addr)->epSet.eps[(_addr)->epSet.inUse])
|
||||
|
@ -488,50 +491,51 @@ extern SSchedulerMgmt schMgmt;
|
|||
|
||||
#define TD_RWLATCH_WRITE_FLAG_COPY 0x40000000
|
||||
|
||||
#define SCH_LOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before read lock"); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) > 0, "invalid lock value after read lock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before write lock"); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) == TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value after write lock"); \
|
||||
} \
|
||||
#define SCH_LOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before read lock"); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) > 0, "invalid lock value after read lock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before write lock"); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) == TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value after write lock"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SCH_UNLOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32((_lock)) > 0, "invalid lock value before read unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after read unlock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32((_lock)) & TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value before write unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after write unlock"); \
|
||||
} \
|
||||
#define SCH_UNLOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32((_lock)) > 0, "invalid lock value before read unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after read unlock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32((_lock)) & TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value before write unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after write unlock"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SCH_RESET_JOB_LEVEL_IDX(_job) do { \
|
||||
(_job)->levelIdx = (_job)->levelNum - 1; \
|
||||
SCH_JOB_DLOG("set job levelIdx to %d", (_job)->levelIdx); \
|
||||
} while (0)
|
||||
#define SCH_RESET_JOB_LEVEL_IDX(_job) \
|
||||
do { \
|
||||
(_job)->levelIdx = (_job)->levelNum - 1; \
|
||||
SCH_JOB_DLOG("set job levelIdx to %d", (_job)->levelIdx); \
|
||||
} while (0)
|
||||
|
||||
void schDeregisterTaskHb(SSchJob *pJob, SSchTask *pTask);
|
||||
void schCleanClusterHb(void *pTrans);
|
||||
int32_t schLaunchTask(SSchJob *job, SSchTask *task);
|
||||
int32_t schDelayLaunchTask(SSchJob *pJob, SSchTask *pTask);
|
||||
int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType, void* param);
|
||||
int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType, void *param);
|
||||
SSchJob *schAcquireJob(int64_t refId);
|
||||
int32_t schReleaseJob(int64_t refId);
|
||||
void schFreeFlowCtrl(SSchJob *pJob);
|
||||
|
|
|
@ -505,7 +505,7 @@ int32_t schHandleLinkBrokenCallback(void *param, SDataBuf *pMsg, int32_t code) {
|
|||
taosMemoryFree(pMsg->pEpSet);
|
||||
|
||||
SSchHbCallbackParam *hbParam = (SSchHbCallbackParam *)param;
|
||||
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL};
|
||||
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL, .pHandleId = 0};
|
||||
SCH_ERR_RET(schUpdateHbConnection(&hbParam->nodeEpId, &trans));
|
||||
|
||||
SCH_ERR_RET(schBuildAndSendHbMsg(&hbParam->nodeEpId, NULL));
|
||||
|
@ -537,6 +537,7 @@ int32_t schHandleHbCallback(void *param, SDataBuf *pMsg, int32_t code) {
|
|||
SSchTrans trans = {0};
|
||||
trans.pTrans = pParam->pTrans;
|
||||
trans.pHandle = pMsg->handle;
|
||||
trans.pHandleId = pMsg->handleRefId;
|
||||
|
||||
SCH_ERR_JRET(schUpdateHbConnection(&rsp.epId, &trans));
|
||||
SCH_ERR_JRET(schProcessOnTaskStatusRsp(&rsp.epId, rsp.taskStatus));
|
||||
|
|
|
@ -42,7 +42,7 @@ char *schDumpEpSet(SEpSet *pEpSet) {
|
|||
}
|
||||
|
||||
int32_t maxSize = 1024;
|
||||
char *str = taosMemoryMalloc(maxSize);
|
||||
char *str = taosMemoryMalloc(maxSize);
|
||||
if (NULL == str) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ char *schGetOpStr(SCH_OP_TYPE type) {
|
|||
}
|
||||
|
||||
void schFreeHbTrans(SSchHbTrans *pTrans) {
|
||||
rpcReleaseHandle(pTrans->trans.pHandle, TAOS_CONN_CLIENT);
|
||||
rpcReleaseHandle((void *)pTrans->trans.pHandleId, TAOS_CONN_CLIENT);
|
||||
|
||||
schFreeRpcCtx(&pTrans->rpcCtx);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ int32_t schEnsureHbConnection(SSchJob *pJob, SSchTask *pTask) {
|
|||
if (!tsEnableQueryHb) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
|
||||
SQueryNodeEpId epId = {0};
|
||||
|
||||
|
@ -234,7 +234,8 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchTrans *trans) {
|
|||
hb = taosHashGet(schMgmt.hbConnections, epId, sizeof(SQueryNodeEpId));
|
||||
if (NULL == hb) {
|
||||
SCH_UNLOCK(SCH_READ, &schMgmt.hbLock);
|
||||
qInfo("taosHashGet hb connection not exists, nodeId:%d, fqdn:%s, port:%d", epId->nodeId, epId->ep.fqdn, epId->ep.port);
|
||||
qInfo("taosHashGet hb connection not exists, nodeId:%d, fqdn:%s, port:%d", epId->nodeId, epId->ep.fqdn,
|
||||
epId->ep.port);
|
||||
SCH_ERR_RET(TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ extern "C" {
|
|||
#define stError(...) do { if (stDebugFlag & DEBUG_ERROR) { taosPrintLog("STM ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} while(0)
|
||||
#define stWarn(...) do { if (stDebugFlag & DEBUG_WARN) { taosPrintLog("STM WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} while(0)
|
||||
#define stInfo(...) do { if (stDebugFlag & DEBUG_INFO) { taosPrintLog("STM ", DEBUG_INFO, 255, __VA_ARGS__); }} while(0)
|
||||
#define stDebug(...) do { if (stDebugFlag & DEBUG_DEBUG) { taosPrintLog("STM ", DEBUG_DEBUG, tqDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define stTrace(...) do { if (stDebugFlag & DEBUG_TRACE) { taosPrintLog("STM ", DEBUG_TRACE, tqDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define stDebug(...) do { if (stDebugFlag & DEBUG_DEBUG) { taosPrintLog("STM ", DEBUG_DEBUG, stDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define stTrace(...) do { if (stDebugFlag & DEBUG_TRACE) { taosPrintLog("STM ", DEBUG_TRACE, stDebugFlag, __VA_ARGS__); }} while(0)
|
||||
// clang-format on
|
||||
|
||||
typedef struct {
|
||||
|
@ -92,6 +92,9 @@ extern int32_t streamBackendId;
|
|||
extern int32_t streamBackendCfWrapperId;
|
||||
extern int32_t taskDbWrapperId;
|
||||
|
||||
int32_t streamTimerInit();
|
||||
void streamTimerCleanUp();
|
||||
|
||||
void streamRetryDispatchData(SStreamTask* pTask, int64_t waitDuration);
|
||||
int32_t streamDispatchStreamBlock(SStreamTask* pTask);
|
||||
void destroyDispatchMsg(SStreamDispatchReq* pReq, int32_t numOfVgroups);
|
||||
|
@ -117,7 +120,7 @@ int32_t streamTaskSendCheckpointSourceRsp(SStreamTask* pTask);
|
|||
void streamTaskSetCheckpointFailedId(SStreamTask* pTask);
|
||||
int32_t streamTaskGetNumOfDownstream(const SStreamTask* pTask);
|
||||
int32_t streamTaskInitTokenBucket(STokenBucket* pBucket, int32_t numCap, int32_t numRate, float quotaRate, const char*);
|
||||
STaskId streamTaskExtractKey(const SStreamTask* pTask);
|
||||
STaskId streamTaskGetTaskId(const SStreamTask* pTask);
|
||||
void streamTaskInitForLaunchHTask(SHistoryTaskInfo* pInfo);
|
||||
void streamTaskSetRetryInfoForLaunch(SHistoryTaskInfo* pInfo);
|
||||
int32_t streamTaskBuildScanhistoryRspMsg(SStreamTask* pTask, SStreamScanHistoryFinishReq* pReq, void** pBuffer,
|
||||
|
|
|
@ -23,11 +23,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
// moore finite state machine for stream task
|
||||
typedef struct SStreamTaskState {
|
||||
ETaskStatus state;
|
||||
char* name;
|
||||
} SStreamTaskState;
|
||||
|
||||
typedef int32_t (*__state_trans_fn)(SStreamTask*);
|
||||
typedef int32_t (*__state_trans_succ_fn)(SStreamTask*);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue