Merge branch '3.0' into enh/killQuery
This commit is contained in:
commit
f9c9afe61a
|
@ -130,6 +130,9 @@ def pre_test(){
|
||||||
def pre_test_win(){
|
def pre_test_win(){
|
||||||
bat '''
|
bat '''
|
||||||
hostname
|
hostname
|
||||||
|
taskkill /f /t /im python.exe
|
||||||
|
taskkill /f /t /im bash.exe
|
||||||
|
taskkill /f /t /im taosd.exe
|
||||||
ipconfig
|
ipconfig
|
||||||
set
|
set
|
||||||
date /t
|
date /t
|
||||||
|
|
|
@ -222,6 +222,7 @@ void blockDataCleanup(SSDataBlock* pDataBlock);
|
||||||
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize);
|
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize);
|
||||||
|
|
||||||
int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n);
|
int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n);
|
||||||
|
int32_t blockDataKeepFirstNRows(SSDataBlock* pBlock, size_t n);
|
||||||
|
|
||||||
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||||
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||||
|
@ -235,6 +236,7 @@ SColumnInfoData* bdGetColumnInfoData(SSDataBlock* pBlock, int32_t index);
|
||||||
void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress);
|
void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress);
|
||||||
const char* blockDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData);
|
const char* blockDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData);
|
||||||
|
|
||||||
|
void blockDebugShowDataBlock(SSDataBlock* pBlock, const char* flag);
|
||||||
void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag);
|
void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag);
|
||||||
// for debug
|
// for debug
|
||||||
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf);
|
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf);
|
||||||
|
|
|
@ -78,6 +78,7 @@ int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag);
|
||||||
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag);
|
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag);
|
||||||
int32_t tTagToValArray(const STag *pTag, SArray **ppArray);
|
int32_t tTagToValArray(const STag *pTag, SArray **ppArray);
|
||||||
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove
|
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove
|
||||||
|
int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf);
|
||||||
|
|
||||||
// STRUCT =================
|
// STRUCT =================
|
||||||
struct STColumn {
|
struct STColumn {
|
||||||
|
|
|
@ -436,15 +436,16 @@ typedef struct {
|
||||||
int32_t ttl;
|
int32_t ttl;
|
||||||
int32_t numOfColumns;
|
int32_t numOfColumns;
|
||||||
int32_t numOfTags;
|
int32_t numOfTags;
|
||||||
|
int32_t numOfFuncs;
|
||||||
int32_t commentLen;
|
int32_t commentLen;
|
||||||
int32_t ast1Len;
|
int32_t ast1Len;
|
||||||
int32_t ast2Len;
|
int32_t ast2Len;
|
||||||
SArray* pColumns; // array of SField
|
SArray* pColumns; // array of SField
|
||||||
SArray* pTags; // array of SField
|
SArray* pTags; // array of SField
|
||||||
char* comment;
|
SArray* pFuncs;
|
||||||
|
char* pComment;
|
||||||
char* pAst1;
|
char* pAst1;
|
||||||
char* pAst2;
|
char* pAst2;
|
||||||
SArray* pFuncs;
|
|
||||||
} SMCreateStbReq;
|
} SMCreateStbReq;
|
||||||
|
|
||||||
int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq);
|
int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq);
|
||||||
|
|
|
@ -233,10 +233,12 @@ enum {
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_PING, "sync-ping", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_PING, "sync-ping", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_PING_REPLY, "sync-ping-reply", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_PING_REPLY, "sync-ping-reply", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_CLIENT_REQUEST, "sync-client-request", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_CLIENT_REQUEST, "sync-client-request", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_SYNC_CLIENT_REQUEST_BATCH, "sync-client-request-batch", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_CLIENT_REQUEST_REPLY, "sync-client-request-reply", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_CLIENT_REQUEST_REPLY, "sync-client-request-reply", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_REQUEST_VOTE, "sync-request-vote", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_REQUEST_VOTE, "sync-request-vote", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_REQUEST_VOTE_REPLY, "sync-request-vote-reply", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_REQUEST_VOTE_REPLY, "sync-request-vote-reply", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_APPEND_ENTRIES, "sync-append-entries", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_APPEND_ENTRIES, "sync-append-entries", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_SYNC_APPEND_ENTRIES_BATCH, "sync-append-entries-batch", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_APPEND_ENTRIES_REPLY, "sync-append-entries-reply", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_APPEND_ENTRIES_REPLY, "sync-append-entries-reply", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_NOOP, "sync-noop", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_NOOP, "sync-noop", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_SYNC_UNKNOWN, "sync-unknown", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_SYNC_UNKNOWN, "sync-unknown", NULL, NULL)
|
||||||
|
|
|
@ -34,6 +34,7 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_ELAPSED,
|
FUNCTION_TYPE_ELAPSED,
|
||||||
FUNCTION_TYPE_IRATE,
|
FUNCTION_TYPE_IRATE,
|
||||||
FUNCTION_TYPE_LAST_ROW,
|
FUNCTION_TYPE_LAST_ROW,
|
||||||
|
FUNCTION_TYPE_LAST_ROWT, //TODO: removed
|
||||||
FUNCTION_TYPE_MAX,
|
FUNCTION_TYPE_MAX,
|
||||||
FUNCTION_TYPE_MIN,
|
FUNCTION_TYPE_MIN,
|
||||||
FUNCTION_TYPE_MODE,
|
FUNCTION_TYPE_MODE,
|
||||||
|
@ -195,6 +196,7 @@ bool fmIsIntervalInterpoFunc(int32_t funcId);
|
||||||
bool fmIsInterpFunc(int32_t funcId);
|
bool fmIsInterpFunc(int32_t funcId);
|
||||||
bool fmIsLastRowFunc(int32_t funcId);
|
bool fmIsLastRowFunc(int32_t funcId);
|
||||||
bool fmIsSystemInfoFunc(int32_t funcId);
|
bool fmIsSystemInfoFunc(int32_t funcId);
|
||||||
|
bool fmIsImplicitTsFunc(int32_t funcId);
|
||||||
|
|
||||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ typedef struct SIndefRowsFuncLogicNode {
|
||||||
SNodeList* pFuncs;
|
SNodeList* pFuncs;
|
||||||
bool isTailFunc;
|
bool isTailFunc;
|
||||||
bool isUniqueFunc;
|
bool isUniqueFunc;
|
||||||
|
bool isTimeLineFunc;
|
||||||
} SIndefRowsFuncLogicNode;
|
} SIndefRowsFuncLogicNode;
|
||||||
|
|
||||||
typedef struct SInterpFuncLogicNode {
|
typedef struct SInterpFuncLogicNode {
|
||||||
|
|
|
@ -251,7 +251,7 @@ typedef struct SSelectStmt {
|
||||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
bool isEmptyResult;
|
bool isEmptyResult;
|
||||||
bool isTimeOrderQuery;
|
bool isTimeLineResult;
|
||||||
bool hasAggFuncs;
|
bool hasAggFuncs;
|
||||||
bool hasRepeatScanFuncs;
|
bool hasRepeatScanFuncs;
|
||||||
bool hasIndefiniteRowsFunc;
|
bool hasIndefiniteRowsFunc;
|
||||||
|
@ -261,6 +261,7 @@ typedef struct SSelectStmt {
|
||||||
bool hasTailFunc;
|
bool hasTailFunc;
|
||||||
bool hasInterpFunc;
|
bool hasInterpFunc;
|
||||||
bool hasLastRowFunc;
|
bool hasLastRowFunc;
|
||||||
|
bool hasTimeLineFunc;
|
||||||
bool groupSort;
|
bool groupSort;
|
||||||
} SSelectStmt;
|
} SSelectStmt;
|
||||||
|
|
||||||
|
|
|
@ -249,13 +249,6 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
||||||
((_code) == TSDB_CODE_RPC_REDIRECT || (_code) == TSDB_CODE_NODE_NOT_DEPLOYED || \
|
((_code) == TSDB_CODE_RPC_REDIRECT || (_code) == TSDB_CODE_NODE_NOT_DEPLOYED || \
|
||||||
(_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_APP_NOT_READY)
|
(_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_APP_NOT_READY)
|
||||||
|
|
||||||
#define NEED_SCHEDULER_RETRY_ERROR(_code) \
|
|
||||||
(NEED_SCHEDULER_REDIRECT_ERROR(_code) || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
|
||||||
(_code) == TSDB_CODE_SCH_TIMEOUT_ERROR || (_code) == TSDB_CODE_RPC_BROKEN_LINK)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define REQUEST_TOTAL_EXEC_TIMES 2
|
#define REQUEST_TOTAL_EXEC_TIMES 2
|
||||||
|
|
||||||
#define qFatal(...) \
|
#define qFatal(...) \
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern "C" {
|
||||||
|
|
||||||
extern bool gRaftDetailLog;
|
extern bool gRaftDetailLog;
|
||||||
|
|
||||||
|
#define SYNC_MAX_BATCH_SIZE 100
|
||||||
#define SYNC_INDEX_BEGIN 0
|
#define SYNC_INDEX_BEGIN 0
|
||||||
#define SYNC_INDEX_INVALID -1
|
#define SYNC_INDEX_INVALID -1
|
||||||
#define SYNC_TERM_INVALID 0xFFFFFFFFFFFFFFFF
|
#define SYNC_TERM_INVALID 0xFFFFFFFFFFFFFFFF
|
||||||
|
@ -120,7 +121,7 @@ typedef struct SSyncFSM {
|
||||||
int32_t (*FpGetSnapshot)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot, void* pReaderParam, void** ppReader);
|
int32_t (*FpGetSnapshot)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot, void* pReaderParam, void** ppReader);
|
||||||
int32_t (*FpGetSnapshotInfo)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot);
|
int32_t (*FpGetSnapshotInfo)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot);
|
||||||
|
|
||||||
int32_t (*FpSnapshotStartRead)(struct SSyncFSM* pFsm, void** ppReader);
|
int32_t (*FpSnapshotStartRead)(struct SSyncFSM* pFsm, void* pReaderParam, void** ppReader);
|
||||||
int32_t (*FpSnapshotStopRead)(struct SSyncFSM* pFsm, void* pReader);
|
int32_t (*FpSnapshotStopRead)(struct SSyncFSM* pFsm, void* pReader);
|
||||||
int32_t (*FpSnapshotDoRead)(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len);
|
int32_t (*FpSnapshotDoRead)(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len);
|
||||||
|
|
||||||
|
@ -164,6 +165,7 @@ typedef struct SSyncLogStore {
|
||||||
bool (*syncLogIsEmpty)(struct SSyncLogStore* pLogStore);
|
bool (*syncLogIsEmpty)(struct SSyncLogStore* pLogStore);
|
||||||
int32_t (*syncLogEntryCount)(struct SSyncLogStore* pLogStore);
|
int32_t (*syncLogEntryCount)(struct SSyncLogStore* pLogStore);
|
||||||
int32_t (*syncLogRestoreFromSnapshot)(struct SSyncLogStore* pLogStore, SyncIndex index);
|
int32_t (*syncLogRestoreFromSnapshot)(struct SSyncLogStore* pLogStore, SyncIndex index);
|
||||||
|
bool (*syncLogExist)(struct SSyncLogStore* pLogStore, SyncIndex index);
|
||||||
|
|
||||||
SyncIndex (*syncLogWriteIndex)(struct SSyncLogStore* pLogStore);
|
SyncIndex (*syncLogWriteIndex)(struct SSyncLogStore* pLogStore);
|
||||||
SyncIndex (*syncLogLastIndex)(struct SSyncLogStore* pLogStore);
|
SyncIndex (*syncLogLastIndex)(struct SSyncLogStore* pLogStore);
|
||||||
|
@ -179,6 +181,7 @@ typedef struct SSyncInfo {
|
||||||
bool isStandBy;
|
bool isStandBy;
|
||||||
bool snapshotEnable;
|
bool snapshotEnable;
|
||||||
SyncGroupId vgId;
|
SyncGroupId vgId;
|
||||||
|
int32_t batchSize;
|
||||||
SSyncCfg syncCfg;
|
SSyncCfg syncCfg;
|
||||||
char path[TSDB_FILENAME_LEN];
|
char path[TSDB_FILENAME_LEN];
|
||||||
SWal* pWal;
|
SWal* pWal;
|
||||||
|
@ -202,6 +205,7 @@ SyncGroupId syncGetVgId(int64_t rid);
|
||||||
void syncGetEpSet(int64_t rid, SEpSet* pEpSet);
|
void syncGetEpSet(int64_t rid, SEpSet* pEpSet);
|
||||||
void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet);
|
void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet);
|
||||||
int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak);
|
int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak);
|
||||||
|
// int32_t syncProposeBatch(int64_t rid, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize);
|
||||||
bool syncEnvIsStart();
|
bool syncEnvIsStart();
|
||||||
const char* syncStr(ESyncState state);
|
const char* syncStr(ESyncState state);
|
||||||
bool syncIsRestoreFinish(int64_t rid);
|
bool syncIsRestoreFinish(int64_t rid);
|
||||||
|
|
|
@ -219,6 +219,34 @@ void syncClientRequestPrint2(char* s, const SyncClientRequest* pMsg);
|
||||||
void syncClientRequestLog(const SyncClientRequest* pMsg);
|
void syncClientRequestLog(const SyncClientRequest* pMsg);
|
||||||
void syncClientRequestLog2(char* s, const SyncClientRequest* pMsg);
|
void syncClientRequestLog2(char* s, const SyncClientRequest* pMsg);
|
||||||
|
|
||||||
|
// ---------------------------------------------
|
||||||
|
typedef struct SOffsetAndContLen {
|
||||||
|
int32_t offset;
|
||||||
|
int32_t contLen;
|
||||||
|
} SOffsetAndContLen;
|
||||||
|
|
||||||
|
typedef struct SRaftMeta {
|
||||||
|
uint64_t seqNum;
|
||||||
|
bool isWeak;
|
||||||
|
} SRaftMeta;
|
||||||
|
|
||||||
|
// block1:
|
||||||
|
// block2: SRaftMeta array
|
||||||
|
// block3: rpc msg array (with pCont)
|
||||||
|
|
||||||
|
typedef struct SyncClientRequestBatch {
|
||||||
|
uint32_t bytes;
|
||||||
|
int32_t vgId;
|
||||||
|
uint32_t msgType; // SyncClientRequestBatch msgType
|
||||||
|
uint32_t dataCount;
|
||||||
|
uint32_t dataLen; // user RpcMsg.contLen
|
||||||
|
char data[]; // user RpcMsg.pCont
|
||||||
|
} SyncClientRequestBatch;
|
||||||
|
|
||||||
|
SyncClientRequestBatch* syncClientRequestBatchBuild(SRpcMsg* rpcMsgArr, SRaftMeta* raftArr, int32_t arrSize,
|
||||||
|
int32_t vgId);
|
||||||
|
void syncClientRequestBatch2RpcMsg(const SyncClientRequestBatch* pSyncMsg, SRpcMsg* pRpcMsg);
|
||||||
|
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
typedef struct SyncClientRequestReply {
|
typedef struct SyncClientRequestReply {
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
|
@ -325,22 +353,58 @@ void syncAppendEntriesLog(const SyncAppendEntries* pMsg);
|
||||||
void syncAppendEntriesLog2(char* s, const SyncAppendEntries* pMsg);
|
void syncAppendEntriesLog2(char* s, const SyncAppendEntries* pMsg);
|
||||||
|
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
// define ahead
|
||||||
|
/*
|
||||||
|
typedef struct SOffsetAndContLen {
|
||||||
|
int32_t offset;
|
||||||
|
int32_t contLen;
|
||||||
|
} SOffsetAndContLen;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// block1: SOffsetAndContLen
|
||||||
|
// block2: SOffsetAndContLen Array
|
||||||
|
// block3: SRpcMsg Array
|
||||||
|
// block4: SRpcMsg pCont Array
|
||||||
|
|
||||||
typedef struct SyncAppendEntriesBatch {
|
typedef struct SyncAppendEntriesBatch {
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
uint32_t msgType;
|
uint32_t msgType;
|
||||||
SRaftId srcId;
|
SRaftId srcId;
|
||||||
SRaftId destId;
|
SRaftId destId;
|
||||||
|
|
||||||
// private data
|
// private data
|
||||||
SyncTerm term;
|
SyncTerm term;
|
||||||
SyncIndex prevLogIndex;
|
SyncIndex prevLogIndex;
|
||||||
SyncTerm prevLogTerm;
|
SyncTerm prevLogTerm;
|
||||||
SyncIndex commitIndex;
|
SyncIndex commitIndex;
|
||||||
SyncTerm privateTerm;
|
SyncTerm privateTerm;
|
||||||
|
int32_t dataCount;
|
||||||
uint32_t dataLen;
|
uint32_t dataLen;
|
||||||
char data[];
|
char data[];
|
||||||
} SyncAppendEntriesBatch;
|
} SyncAppendEntriesBatch;
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SRpcMsg* rpcMsgArr, int32_t arrSize, int32_t vgId);
|
||||||
|
void syncAppendEntriesBatchDestroy(SyncAppendEntriesBatch* pMsg);
|
||||||
|
void syncAppendEntriesBatchSerialize(const SyncAppendEntriesBatch* pMsg, char* buf, uint32_t bufLen);
|
||||||
|
void syncAppendEntriesBatchDeserialize(const char* buf, uint32_t len, SyncAppendEntriesBatch* pMsg);
|
||||||
|
char* syncAppendEntriesBatchSerialize2(const SyncAppendEntriesBatch* pMsg, uint32_t* len);
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchDeserialize2(const char* buf, uint32_t len);
|
||||||
|
void syncAppendEntriesBatch2RpcMsg(const SyncAppendEntriesBatch* pMsg, SRpcMsg* pRpcMsg);
|
||||||
|
void syncAppendEntriesBatchFromRpcMsg(const SRpcMsg* pRpcMsg, SyncAppendEntriesBatch* pMsg);
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchFromRpcMsg2(const SRpcMsg* pRpcMsg);
|
||||||
|
cJSON* syncAppendEntriesBatch2Json(const SyncAppendEntriesBatch* pMsg);
|
||||||
|
char* syncAppendEntriesBatch2Str(const SyncAppendEntriesBatch* pMsg);
|
||||||
|
void syncAppendEntriesBatch2RpcMsgArray(SyncAppendEntriesBatch* pSyncMsg, SRpcMsg* rpcMsgArr, int32_t maxArrSize,
|
||||||
|
int32_t* pRetArrSize);
|
||||||
|
|
||||||
|
// for debug ----------------------
|
||||||
|
void syncAppendEntriesBatchPrint(const SyncAppendEntriesBatch* pMsg);
|
||||||
|
void syncAppendEntriesBatchPrint2(char* s, const SyncAppendEntriesBatch* pMsg);
|
||||||
|
void syncAppendEntriesBatchLog(const SyncAppendEntriesBatch* pMsg);
|
||||||
|
void syncAppendEntriesBatchLog2(char* s, const SyncAppendEntriesBatch* pMsg);
|
||||||
|
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
typedef struct SyncAppendEntriesReply {
|
typedef struct SyncAppendEntriesReply {
|
||||||
uint32_t bytes;
|
uint32_t bytes;
|
||||||
|
@ -542,6 +606,7 @@ int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg);
|
||||||
int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg);
|
int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg);
|
||||||
int32_t syncNodeOnTimeoutCb(SSyncNode* ths, SyncTimeout* pMsg);
|
int32_t syncNodeOnTimeoutCb(SSyncNode* ths, SyncTimeout* pMsg);
|
||||||
int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg, SyncIndex* pRetIndex);
|
int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg, SyncIndex* pRetIndex);
|
||||||
|
int32_t syncNodeOnClientRequestBatchCb(SSyncNode* ths, SyncClientRequestBatch* pMsg);
|
||||||
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg);
|
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg);
|
||||||
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg);
|
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg);
|
||||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
||||||
|
|
|
@ -61,45 +61,23 @@ extern "C" {
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WAL_HEAD_VER 0
|
#define WAL_PROTO_VER 0
|
||||||
#define WAL_NOSUFFIX_LEN 20
|
#define WAL_NOSUFFIX_LEN 20
|
||||||
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN + 1)
|
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN + 1)
|
||||||
#define WAL_LOG_SUFFIX "log"
|
#define WAL_LOG_SUFFIX "log"
|
||||||
#define WAL_INDEX_SUFFIX "idx"
|
#define WAL_INDEX_SUFFIX "idx"
|
||||||
#define WAL_REFRESH_MS 1000
|
#define WAL_REFRESH_MS 1000
|
||||||
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead))
|
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalCkHead))
|
||||||
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
|
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
|
||||||
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
|
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
|
||||||
#define WAL_MAGIC 0xFAFBFCFDULL
|
#define WAL_MAGIC 0xFAFBFCFDULL
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_WAL_NOLOG = 0,
|
TAOS_WAL_NOLOG = 0,
|
||||||
TAOS_WAL_WRITE = 1,
|
TAOS_WAL_WRITE = 1,
|
||||||
TAOS_WAL_FSYNC = 2,
|
TAOS_WAL_FSYNC = 2,
|
||||||
} EWalType;
|
} EWalType;
|
||||||
|
|
||||||
// used by sync module
|
|
||||||
typedef struct {
|
|
||||||
int8_t isWeek;
|
|
||||||
uint64_t seqNum;
|
|
||||||
uint64_t term;
|
|
||||||
} SSyncLogMeta;
|
|
||||||
|
|
||||||
typedef struct SWalReadHead {
|
|
||||||
int8_t headVer;
|
|
||||||
int8_t reserved;
|
|
||||||
int16_t msgType;
|
|
||||||
int32_t bodyLen;
|
|
||||||
int64_t ingestTs; // not implemented
|
|
||||||
int64_t version;
|
|
||||||
|
|
||||||
// sync meta
|
|
||||||
SSyncLogMeta syncMeta;
|
|
||||||
|
|
||||||
char body[];
|
|
||||||
} SWalReadHead;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
int32_t fsyncPeriod; // millisecond
|
int32_t fsyncPeriod; // millisecond
|
||||||
|
@ -110,13 +88,6 @@ typedef struct {
|
||||||
EWalType level; // wal level
|
EWalType level; // wal level
|
||||||
} SWalCfg;
|
} SWalCfg;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t magic;
|
|
||||||
uint32_t cksumHead;
|
|
||||||
uint32_t cksumBody;
|
|
||||||
SWalReadHead head;
|
|
||||||
} SWalHead;
|
|
||||||
|
|
||||||
typedef struct SWalVer {
|
typedef struct SWalVer {
|
||||||
int64_t firstVer;
|
int64_t firstVer;
|
||||||
int64_t verInSnapshotting;
|
int64_t verInSnapshotting;
|
||||||
|
@ -125,6 +96,35 @@ typedef struct SWalVer {
|
||||||
int64_t lastVer;
|
int64_t lastVer;
|
||||||
} SWalVer;
|
} SWalVer;
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
// used by sync module
|
||||||
|
typedef struct {
|
||||||
|
int8_t isWeek;
|
||||||
|
uint64_t seqNum;
|
||||||
|
uint64_t term;
|
||||||
|
} SSyncLogMeta;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int8_t protoVer;
|
||||||
|
int64_t version;
|
||||||
|
int16_t msgType;
|
||||||
|
int32_t bodyLen;
|
||||||
|
int64_t ingestTs; // not implemented
|
||||||
|
|
||||||
|
// sync meta
|
||||||
|
SSyncLogMeta syncMeta;
|
||||||
|
|
||||||
|
char body[];
|
||||||
|
} SWalCont;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t magic;
|
||||||
|
uint32_t cksumHead;
|
||||||
|
uint32_t cksumBody;
|
||||||
|
SWalCont head;
|
||||||
|
} SWalCkHead;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef struct SWal {
|
typedef struct SWal {
|
||||||
// cfg
|
// cfg
|
||||||
SWalCfg cfg;
|
SWalCfg cfg;
|
||||||
|
@ -134,7 +134,7 @@ typedef struct SWal {
|
||||||
TdFilePtr pWriteLogTFile;
|
TdFilePtr pWriteLogTFile;
|
||||||
TdFilePtr pWriteIdxTFile;
|
TdFilePtr pWriteIdxTFile;
|
||||||
int32_t writeCur;
|
int32_t writeCur;
|
||||||
SArray *fileInfoSet;
|
SArray *fileInfoSet; // SArray<SWalFileInfo>
|
||||||
// status
|
// status
|
||||||
int64_t totSize;
|
int64_t totSize;
|
||||||
int64_t lastRollSeq;
|
int64_t lastRollSeq;
|
||||||
|
@ -146,7 +146,7 @@ typedef struct SWal {
|
||||||
// path
|
// path
|
||||||
char path[WAL_PATH_LEN];
|
char path[WAL_PATH_LEN];
|
||||||
// reusable write head
|
// reusable write head
|
||||||
SWalHead writeHead;
|
SWalCkHead writeHead;
|
||||||
} SWal; // WAL HANDLE
|
} SWal; // WAL HANDLE
|
||||||
|
|
||||||
typedef struct SWalReadHandle {
|
typedef struct SWalReadHandle {
|
||||||
|
@ -158,11 +158,8 @@ typedef struct SWalReadHandle {
|
||||||
int64_t capacity;
|
int64_t capacity;
|
||||||
int64_t status; // if cursor valid
|
int64_t status; // if cursor valid
|
||||||
TdThreadMutex mutex;
|
TdThreadMutex mutex;
|
||||||
SWalHead *pHead;
|
SWalCkHead *pHead;
|
||||||
} SWalReadHandle;
|
} SWalReadHandle;
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
// typedef int32_t (*FWalWrite)(void *ahandle, void *pHead);
|
|
||||||
|
|
||||||
// module initialization
|
// module initialization
|
||||||
int32_t walInit();
|
int32_t walInit();
|
||||||
|
@ -174,9 +171,9 @@ int32_t walAlter(SWal *, SWalCfg *pCfg);
|
||||||
void walClose(SWal *);
|
void walClose(SWal *);
|
||||||
|
|
||||||
// write
|
// write
|
||||||
int64_t walWriteWithSyncInfo(SWal *, int64_t index, tmsg_t msgType, SSyncLogMeta syncMeta, const void *body,
|
int32_t walWriteWithSyncInfo(SWal *, int64_t index, tmsg_t msgType, SSyncLogMeta syncMeta, const void *body,
|
||||||
int32_t bodyLen);
|
int32_t bodyLen);
|
||||||
int64_t walWrite(SWal *, int64_t index, tmsg_t msgType, const void *body, int32_t bodyLen);
|
int32_t walWrite(SWal *, int64_t index, tmsg_t msgType, const void *body, int32_t bodyLen);
|
||||||
void walFsync(SWal *, bool force);
|
void walFsync(SWal *, bool force);
|
||||||
|
|
||||||
// apis for lifecycle management
|
// apis for lifecycle management
|
||||||
|
@ -196,9 +193,9 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver);
|
||||||
|
|
||||||
// only for tq usage
|
// only for tq usage
|
||||||
void walSetReaderCapacity(SWalReadHandle *pRead, int32_t capacity);
|
void walSetReaderCapacity(SWalReadHandle *pRead, int32_t capacity);
|
||||||
int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalHead *pHead);
|
int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalCkHead *pHead);
|
||||||
int32_t walFetchBody(SWalReadHandle *pRead, SWalHead **ppHead);
|
int32_t walFetchBody(SWalReadHandle *pRead, SWalCkHead **ppHead);
|
||||||
int32_t walSkipFetchBody(SWalReadHandle *pRead, const SWalHead *pHead);
|
int32_t walSkipFetchBody(SWalReadHandle *pRead, const SWalCkHead *pHead);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t refId;
|
int64_t refId;
|
||||||
|
@ -210,6 +207,8 @@ void walCloseRef(SWalRef *);
|
||||||
int32_t walRefVer(SWalRef *, int64_t ver);
|
int32_t walRefVer(SWalRef *, int64_t ver);
|
||||||
int32_t walUnrefVer(SWal *);
|
int32_t walUnrefVer(SWal *);
|
||||||
|
|
||||||
|
bool walLogExist(SWal *, int64_t ver);
|
||||||
|
|
||||||
// lifecycle check
|
// lifecycle check
|
||||||
bool walIsEmpty(SWal *);
|
bool walIsEmpty(SWal *);
|
||||||
int64_t walGetFirstVer(SWal *);
|
int64_t walGetFirstVer(SWal *);
|
||||||
|
|
|
@ -25,17 +25,17 @@ extern "C" {
|
||||||
// If the error is in a third-party library, place this header file under the third-party library header file.
|
// If the error is in a third-party library, place this header file under the third-party library header file.
|
||||||
// When you want to use this feature, you should find or add the same function in the following sectio
|
// When you want to use this feature, you should find or add the same function in the following sectio
|
||||||
#ifndef ALLOW_FORBID_FUNC
|
#ifndef ALLOW_FORBID_FUNC
|
||||||
#define open OPEN_FUNC_TAOS_FORBID
|
#define open OPEN_FUNC_TAOS_FORBID
|
||||||
#define fopen FOPEN_FUNC_TAOS_FORBID
|
#define fopen FOPEN_FUNC_TAOS_FORBID
|
||||||
#define access ACCESS_FUNC_TAOS_FORBID
|
#define access ACCESS_FUNC_TAOS_FORBID
|
||||||
#define stat STAT_FUNC_TAOS_FORBID
|
#define stat STAT_FUNC_TAOS_FORBID
|
||||||
#define lstat LSTAT_FUNC_TAOS_FORBID
|
#define lstat LSTAT_FUNC_TAOS_FORBID
|
||||||
#define fstat FSTAT_FUNC_TAOS_FORBID
|
#define fstat FSTAT_FUNC_TAOS_FORBID
|
||||||
#define close CLOSE_FUNC_TAOS_FORBID
|
#define close CLOSE_FUNC_TAOS_FORBID
|
||||||
#define fclose FCLOSE_FUNC_TAOS_FORBID
|
#define fclose FCLOSE_FUNC_TAOS_FORBID
|
||||||
#define fsync FSYNC_FUNC_TAOS_FORBID
|
#define fsync FSYNC_FUNC_TAOS_FORBID
|
||||||
#define getline GETLINE_FUNC_TAOS_FORBID
|
#define getline GETLINE_FUNC_TAOS_FORBID
|
||||||
// #define fflush FFLUSH_FUNC_TAOS_FORBID
|
// #define fflush FFLUSH_FUNC_TAOS_FORBID
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
|
@ -43,54 +43,54 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct TdFile *TdFilePtr;
|
typedef struct TdFile *TdFilePtr;
|
||||||
|
|
||||||
#define TD_FILE_CREATE 0x0001
|
#define TD_FILE_CREATE 0x0001
|
||||||
#define TD_FILE_WRITE 0x0002
|
#define TD_FILE_WRITE 0x0002
|
||||||
#define TD_FILE_READ 0x0004
|
#define TD_FILE_READ 0x0004
|
||||||
#define TD_FILE_TRUNC 0x0008
|
#define TD_FILE_TRUNC 0x0008
|
||||||
#define TD_FILE_APPEND 0x0010
|
#define TD_FILE_APPEND 0x0010
|
||||||
#define TD_FILE_TEXT 0x0020
|
#define TD_FILE_TEXT 0x0020
|
||||||
#define TD_FILE_AUTO_DEL 0x0040
|
#define TD_FILE_AUTO_DEL 0x0040
|
||||||
#define TD_FILE_EXCL 0x0080
|
#define TD_FILE_EXCL 0x0080
|
||||||
#define TD_FILE_STREAM 0x0100 // Only support taosFprintfFile, taosGetLineFile, taosEOFFile
|
#define TD_FILE_STREAM 0x0100 // Only support taosFprintfFile, taosGetLineFile, taosEOFFile
|
||||||
TdFilePtr taosOpenFile(const char *path,int32_t tdFileOptions);
|
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions);
|
||||||
|
|
||||||
#define TD_FILE_ACCESS_EXIST_OK 0x1
|
#define TD_FILE_ACCESS_EXIST_OK 0x1
|
||||||
#define TD_FILE_ACCESS_READ_OK 0x2
|
#define TD_FILE_ACCESS_READ_OK 0x2
|
||||||
#define TD_FILE_ACCESS_WRITE_OK 0x4
|
#define TD_FILE_ACCESS_WRITE_OK 0x4
|
||||||
bool taosCheckAccessFile(const char *pathname, int mode);
|
bool taosCheckAccessFile(const char *pathname, int mode);
|
||||||
|
|
||||||
int32_t taosLockFile(TdFilePtr pFile);
|
int32_t taosLockFile(TdFilePtr pFile);
|
||||||
int32_t taosUnLockFile(TdFilePtr pFile);
|
int32_t taosUnLockFile(TdFilePtr pFile);
|
||||||
|
|
||||||
int32_t taosUmaskFile(int32_t maskVal);
|
int32_t taosUmaskFile(int32_t maskVal);
|
||||||
|
|
||||||
int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime);
|
int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime);
|
||||||
int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno);
|
int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno);
|
||||||
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime);
|
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime);
|
||||||
bool taosCheckExistFile(const char *pathname);
|
bool taosCheckExistFile(const char *pathname);
|
||||||
|
|
||||||
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence);
|
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence);
|
||||||
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t length);
|
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t length);
|
||||||
int32_t taosFsyncFile(TdFilePtr pFile);
|
int32_t taosFsyncFile(TdFilePtr pFile);
|
||||||
|
|
||||||
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count);
|
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count);
|
||||||
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset);
|
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset);
|
||||||
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count);
|
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count);
|
||||||
void taosFprintfFile(TdFilePtr pFile, const char *format, ...);
|
void taosFprintfFile(TdFilePtr pFile, const char *format, ...);
|
||||||
|
|
||||||
int64_t taosGetLineFile(TdFilePtr pFile, char ** __restrict ptrBuf);
|
int64_t taosGetLineFile(TdFilePtr pFile, char **__restrict ptrBuf);
|
||||||
int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf);
|
int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf);
|
||||||
|
|
||||||
int32_t taosEOFFile(TdFilePtr pFile);
|
int32_t taosEOFFile(TdFilePtr pFile);
|
||||||
|
|
||||||
int64_t taosCloseFile(TdFilePtr *ppFile);
|
int32_t taosCloseFile(TdFilePtr *ppFile);
|
||||||
|
|
||||||
int32_t taosRenameFile(const char *oldName, const char *newName);
|
int32_t taosRenameFile(const char *oldName, const char *newName);
|
||||||
int64_t taosCopyFile(const char *from, const char *to);
|
int64_t taosCopyFile(const char *from, const char *to);
|
||||||
int32_t taosRemoveFile(const char *path);
|
int32_t taosRemoveFile(const char *path);
|
||||||
|
|
||||||
void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, char *dstPath);
|
void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, char *dstPath);
|
||||||
|
|
||||||
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size);
|
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size);
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,13 @@ extern "C" {
|
||||||
})
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __COMPAR_FN_T
|
||||||
|
#define __COMPAR_FN_T
|
||||||
|
typedef int32_t (*__compar_fn_t)(const void *, const void *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -388,6 +388,10 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_QRY_TASK_MSG_ERROR TAOS_DEF_ERROR_CODE(0, 0x0719)
|
#define TSDB_CODE_QRY_TASK_MSG_ERROR TAOS_DEF_ERROR_CODE(0, 0x0719)
|
||||||
#define TSDB_CODE_QRY_JOB_FREED TAOS_DEF_ERROR_CODE(0, 0x071A)
|
#define TSDB_CODE_QRY_JOB_FREED TAOS_DEF_ERROR_CODE(0, 0x071A)
|
||||||
#define TSDB_CODE_QRY_TASK_STATUS_ERROR TAOS_DEF_ERROR_CODE(0, 0x071B)
|
#define TSDB_CODE_QRY_TASK_STATUS_ERROR TAOS_DEF_ERROR_CODE(0, 0x071B)
|
||||||
|
//json
|
||||||
|
#define TSDB_CODE_QRY_JSON_IN_ERROR TAOS_DEF_ERROR_CODE(0, 0x071C)
|
||||||
|
#define TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR TAOS_DEF_ERROR_CODE(0, 0x071D)
|
||||||
|
#define TSDB_CODE_QRY_JSON_IN_GROUP_ERROR TAOS_DEF_ERROR_CODE(0, 0x071E)
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800)
|
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800)
|
||||||
|
@ -423,6 +427,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910)
|
#define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910)
|
||||||
#define TSDB_CODE_SYN_PROPOSE_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0911)
|
#define TSDB_CODE_SYN_PROPOSE_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0911)
|
||||||
#define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912)
|
#define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912)
|
||||||
|
#define TSDB_CODE_SYN_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913)
|
||||||
#define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF)
|
#define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF)
|
||||||
|
|
||||||
// tq
|
// tq
|
||||||
|
@ -572,6 +577,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x265B)
|
#define TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x265B)
|
||||||
#define TSDB_CODE_PAR_INVALID_TABLE_OPTION TAOS_DEF_ERROR_CODE(0, 0x265C)
|
#define TSDB_CODE_PAR_INVALID_TABLE_OPTION TAOS_DEF_ERROR_CODE(0, 0x265C)
|
||||||
#define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D)
|
#define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D)
|
||||||
|
#define TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN TAOS_DEF_ERROR_CODE(0, 0x265E)
|
||||||
|
|
||||||
//planner
|
//planner
|
||||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||||
|
|
|
@ -44,6 +44,8 @@ uint32_t ip2uint(const char *const ip_addr);
|
||||||
void taosIp2String(uint32_t ip, char *str);
|
void taosIp2String(uint32_t ip, char *str);
|
||||||
void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
||||||
|
|
||||||
|
void *tmemmem(const char *haystack, int hlen, const char *needle, int nlen);
|
||||||
|
|
||||||
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
|
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
|
||||||
T_MD5_CTX context;
|
T_MD5_CTX context;
|
||||||
tMD5Init(&context);
|
tMD5Init(&context);
|
||||||
|
@ -59,10 +61,10 @@ static FORCE_INLINE void taosEncryptPass_c(uint8_t *inBuf, size_t len, char *tar
|
||||||
tMD5Final(&context);
|
tMD5Final(&context);
|
||||||
char buf[TSDB_PASSWORD_LEN + 1];
|
char buf[TSDB_PASSWORD_LEN + 1];
|
||||||
|
|
||||||
sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", context.digest[0],
|
sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", context.digest[0], context.digest[1],
|
||||||
context.digest[1], context.digest[2], context.digest[3], context.digest[4], context.digest[5],
|
context.digest[2], context.digest[3], context.digest[4], context.digest[5], context.digest[6],
|
||||||
context.digest[6], context.digest[7], context.digest[8], context.digest[9], context.digest[10],
|
context.digest[7], context.digest[8], context.digest[9], context.digest[10], context.digest[11],
|
||||||
context.digest[11], context.digest[12], context.digest[13], context.digest[14], context.digest[15]);
|
context.digest[12], context.digest[13], context.digest[14], context.digest[15]);
|
||||||
memcpy(target, buf, TSDB_PASSWORD_LEN);
|
memcpy(target, buf, TSDB_PASSWORD_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -782,6 +782,7 @@ int32_t handleQueryExecRsp(SRequestObj* pRequest) {
|
||||||
void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
||||||
SRequestObj* pRequest = (SRequestObj*)param;
|
SRequestObj* pRequest = (SRequestObj*)param;
|
||||||
pRequest->code = code;
|
pRequest->code = code;
|
||||||
|
pRequest->body.resInfo.execRes = pResult->res;
|
||||||
|
|
||||||
if (TDMT_VND_SUBMIT == pRequest->type || TDMT_VND_DELETE == pRequest->type ||
|
if (TDMT_VND_SUBMIT == pRequest->type || TDMT_VND_DELETE == pRequest->type ||
|
||||||
TDMT_VND_CREATE_TABLE == pRequest->type) {
|
TDMT_VND_CREATE_TABLE == pRequest->type) {
|
||||||
|
@ -790,6 +791,8 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
||||||
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosMemoryFree(pResult);
|
||||||
|
|
||||||
tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code,
|
tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code,
|
||||||
tstrerror(code), pRequest->requestId);
|
tstrerror(code), pRequest->requestId);
|
||||||
|
|
||||||
|
|
|
@ -1609,8 +1609,8 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
/*printf("send poll\n");*/
|
/*printf("send poll\n");*/
|
||||||
|
|
||||||
char offsetFormatBuf[50];
|
char offsetFormatBuf[80];
|
||||||
tFormatOffset(offsetFormatBuf, 50, &pVg->currentOffsetNew);
|
tFormatOffset(offsetFormatBuf, 80, &pVg->currentOffsetNew);
|
||||||
tscDebug("consumer %ld send poll to %s : vg %d, epoch %d, req offset %s, reqId %lu", tmq->consumerId,
|
tscDebug("consumer %ld send poll to %s : vg %d, epoch %d, req offset %s, reqId %lu", tmq->consumerId,
|
||||||
pTopic->topicName, pVg->vgId, tmq->epoch, offsetFormatBuf, pReq->reqId);
|
pTopic->topicName, pVg->vgId, tmq->epoch, offsetFormatBuf, pReq->reqId);
|
||||||
/*printf("send vg %d %ld\n", pVg->vgId, pVg->currentOffset);*/
|
/*printf("send vg %d %ld\n", pVg->vgId, pVg->currentOffset);*/
|
||||||
|
|
|
@ -716,7 +716,12 @@ int32_t dataBlockCompar(const void* p1, const void* p2, const void* param) {
|
||||||
|
|
||||||
void* left1 = colDataGetData(pColInfoData, left);
|
void* left1 = colDataGetData(pColInfoData, left);
|
||||||
void* right1 = colDataGetData(pColInfoData, right);
|
void* right1 = colDataGetData(pColInfoData, right);
|
||||||
|
if (pColInfoData->info.type == TSDB_DATA_TYPE_JSON) {
|
||||||
|
if (tTagIsJson(left1) || tTagIsJson(right1)) {
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
__compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
|
__compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
|
||||||
|
|
||||||
int ret = fn(left1, right1);
|
int ret = fn(left1, right1);
|
||||||
|
@ -890,9 +895,9 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
|
||||||
SBlockOrderInfo* pOrder = taosArrayGet(pOrderInfo, 0);
|
SBlockOrderInfo* pOrder = taosArrayGet(pOrderInfo, 0);
|
||||||
|
|
||||||
int64_t p0 = taosGetTimestampUs();
|
int64_t p0 = taosGetTimestampUs();
|
||||||
|
|
||||||
__compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
|
__compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order);
|
||||||
qsort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn);
|
taosSort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn);
|
||||||
|
|
||||||
int64_t p1 = taosGetTimestampUs();
|
int64_t p1 = taosGetTimestampUs();
|
||||||
uDebug("blockDataSort easy cost:%" PRId64 ", rows:%d\n", p1 - p0, pDataBlock->info.rows);
|
uDebug("blockDataSort easy cost:%" PRId64 ", rows:%d\n", p1 - p0, pDataBlock->info.rows);
|
||||||
|
@ -919,6 +924,7 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
taosqsort(index, rows, sizeof(int32_t), &helper, dataBlockCompar);
|
taosqsort(index, rows, sizeof(int32_t), &helper, dataBlockCompar);
|
||||||
|
if(terrno) return terrno;
|
||||||
|
|
||||||
int64_t p1 = taosGetTimestampUs();
|
int64_t p1 = taosGetTimestampUs();
|
||||||
|
|
||||||
|
@ -1218,7 +1224,7 @@ int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src) {
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SColumnInfoData* pDst = taosArrayGet(dst->pDataBlock, i);
|
SColumnInfoData* pDst = taosArrayGet(dst->pDataBlock, i);
|
||||||
SColumnInfoData* pSrc = taosArrayGet(src->pDataBlock, i);
|
SColumnInfoData* pSrc = taosArrayGet(src->pDataBlock, i);
|
||||||
if (pSrc->pData == NULL) {
|
if (pSrc->pData == NULL && (!IS_VAR_DATA_TYPE(pSrc->info.type))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,9 +1437,39 @@ static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t colDataMoveVarData(SColumnInfoData* pColInfoData, size_t start, size_t end){
|
||||||
|
int32_t dataOffset = -1;
|
||||||
|
int32_t dataLen = 0;
|
||||||
|
int32_t beigin = start;
|
||||||
|
while(beigin < end){
|
||||||
|
int32_t offset = pColInfoData->varmeta.offset[beigin];
|
||||||
|
if(offset == -1) {
|
||||||
|
beigin++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(start != 0) {
|
||||||
|
pColInfoData->varmeta.offset[beigin] = dataLen;
|
||||||
|
}
|
||||||
|
char *data = pColInfoData->pData + offset;
|
||||||
|
if(dataOffset == -1) dataOffset = offset; // mark the begin of data
|
||||||
|
int32_t type = pColInfoData->info.type;
|
||||||
|
if (type == TSDB_DATA_TYPE_JSON) {
|
||||||
|
dataLen += getJsonValueLen(data);
|
||||||
|
} else {
|
||||||
|
dataLen += varDataTLen(data);
|
||||||
|
}
|
||||||
|
beigin++;
|
||||||
|
}
|
||||||
|
if(dataOffset > 0){
|
||||||
|
memmove(pColInfoData->pData, pColInfoData->pData + dataOffset, dataLen);
|
||||||
|
memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[start], (end - start) * sizeof(int32_t));
|
||||||
|
}
|
||||||
|
return dataLen;
|
||||||
|
}
|
||||||
|
|
||||||
static void colDataTrimFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
|
static void colDataTrimFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
|
||||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||||
memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[n], (total - n) * sizeof(int32_t));
|
pColInfoData->varmeta.length = colDataMoveVarData(pColInfoData, n, total);
|
||||||
memset(&pColInfoData->varmeta.offset[total - n], 0, n);
|
memset(&pColInfoData->varmeta.offset[total - n], 0, n);
|
||||||
} else {
|
} else {
|
||||||
int32_t bytes = pColInfoData->info.bytes;
|
int32_t bytes = pColInfoData->info.bytes;
|
||||||
|
@ -1461,6 +1497,33 @@ int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void colDataKeepFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_t total) {
|
||||||
|
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||||
|
pColInfoData->varmeta.length = colDataMoveVarData(pColInfoData, 0, n);
|
||||||
|
memset(&pColInfoData->varmeta.offset[n], 0, total - n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t blockDataKeepFirstNRows(SSDataBlock* pBlock, size_t n) {
|
||||||
|
if (n == 0) {
|
||||||
|
blockDataCleanup(pBlock);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBlock->info.rows <= n) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
|
size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||||
|
colDataKeepFirstNRows(pColInfoData, n, pBlock->info.rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
pBlock->info.rows = n;
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
|
int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
|
||||||
int64_t tbUid = pBlock->info.uid;
|
int64_t tbUid = pBlock->info.uid;
|
||||||
int16_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
int16_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
||||||
|
@ -1605,6 +1668,13 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blockDebugShowDataBlock(SSDataBlock* pBlock, const char* flag) {
|
||||||
|
SArray* dataBlocks = taosArrayInit(1, sizeof(SSDataBlock));
|
||||||
|
taosArrayPush(dataBlocks, pBlock);
|
||||||
|
blockDebugShowDataBlocks(dataBlocks, flag);
|
||||||
|
taosArrayDestroy(dataBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag) {
|
void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag) {
|
||||||
char pBuf[128] = {0};
|
char pBuf[128] = {0};
|
||||||
int32_t sz = taosArrayGetSize(dataBlocks);
|
int32_t sz = taosArrayGetSize(dataBlocks);
|
||||||
|
|
|
@ -931,9 +931,9 @@ int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
|
||||||
|
|
||||||
// sort
|
// sort
|
||||||
if (isJson) {
|
if (isJson) {
|
||||||
qsort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
|
taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
|
||||||
} else {
|
} else {
|
||||||
qsort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
|
taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get size
|
// get size
|
||||||
|
|
|
@ -503,6 +503,7 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq
|
||||||
if (tEncodeI32(&encoder, pReq->ttl) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->ttl) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->numOfColumns) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->numOfColumns) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->numOfTags) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->numOfTags) < 0) return -1;
|
||||||
|
if (tEncodeI32(&encoder, pReq->numOfFuncs) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->commentLen) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->commentLen) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->ast1Len) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->ast1Len) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->ast2Len) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->ast2Len) < 0) return -1;
|
||||||
|
@ -510,21 +511,26 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq
|
||||||
for (int32_t i = 0; i < pReq->numOfColumns; ++i) {
|
for (int32_t i = 0; i < pReq->numOfColumns; ++i) {
|
||||||
SField *pField = taosArrayGet(pReq->pColumns, i);
|
SField *pField = taosArrayGet(pReq->pColumns, i);
|
||||||
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
|
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
|
||||||
|
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
|
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
|
||||||
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
||||||
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
|
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
|
||||||
SField *pField = taosArrayGet(pReq->pTags, i);
|
SField *pField = taosArrayGet(pReq->pTags, i);
|
||||||
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
|
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
|
||||||
|
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
|
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
|
||||||
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
||||||
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pReq->numOfFuncs; ++i) {
|
||||||
|
const char *pFunc = taosArrayGet(pReq->pFuncs, i);
|
||||||
|
if (tEncodeCStr(&encoder, pFunc) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReq->commentLen > 0) {
|
if (pReq->commentLen > 0) {
|
||||||
if (tEncodeCStr(&encoder, pReq->comment) < 0) return -1;
|
if (tEncodeCStr(&encoder, pReq->pComment) < 0) return -1;
|
||||||
}
|
}
|
||||||
if (pReq->ast1Len > 0) {
|
if (pReq->ast1Len > 0) {
|
||||||
if (tEncodeBinary(&encoder, pReq->pAst1, pReq->ast1Len) < 0) return -1;
|
if (tEncodeBinary(&encoder, pReq->pAst1, pReq->ast1Len) < 0) return -1;
|
||||||
|
@ -533,13 +539,6 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq
|
||||||
if (tEncodeBinary(&encoder, pReq->pAst2, pReq->ast2Len) < 0) return -1;
|
if (tEncodeBinary(&encoder, pReq->pAst2, pReq->ast2Len) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfFuncs = taosArrayGetSize(pReq->pFuncs);
|
|
||||||
if (tEncodeI32(&encoder, numOfFuncs) < 0) return -1;
|
|
||||||
for (int32_t i = 0; i < numOfFuncs; ++i) {
|
|
||||||
const char *pFunc = taosArrayGet(pReq->pFuncs, i);
|
|
||||||
if (tEncodeCStr(&encoder, pFunc) < 0) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tEndEncode(&encoder);
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
int32_t tlen = encoder.pos;
|
int32_t tlen = encoder.pos;
|
||||||
|
@ -561,13 +560,15 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
|
||||||
if (tDecodeI32(&decoder, &pReq->ttl) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->ttl) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->numOfColumns) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->numOfColumns) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->numOfTags) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->numOfTags) < 0) return -1;
|
||||||
|
if (tDecodeI32(&decoder, &pReq->numOfFuncs) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->commentLen) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->commentLen) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->ast1Len) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->ast1Len) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->ast2Len) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->ast2Len) < 0) return -1;
|
||||||
|
|
||||||
pReq->pColumns = taosArrayInit(pReq->numOfColumns, sizeof(SField));
|
pReq->pColumns = taosArrayInit(pReq->numOfColumns, sizeof(SField));
|
||||||
pReq->pTags = taosArrayInit(pReq->numOfTags, sizeof(SField));
|
pReq->pTags = taosArrayInit(pReq->numOfTags, sizeof(SField));
|
||||||
if (pReq->pColumns == NULL || pReq->pTags == NULL) {
|
pReq->pFuncs = taosArrayInit(pReq->numOfFuncs, TSDB_FUNC_NAME_LEN);
|
||||||
|
if (pReq->pColumns == NULL || pReq->pTags == NULL || pReq->pFuncs == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -575,9 +576,9 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
|
||||||
for (int32_t i = 0; i < pReq->numOfColumns; ++i) {
|
for (int32_t i = 0; i < pReq->numOfColumns; ++i) {
|
||||||
SField field = {0};
|
SField field = {0};
|
||||||
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
|
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
|
||||||
|
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
|
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
|
||||||
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
|
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
|
||||||
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
|
|
||||||
if (taosArrayPush(pReq->pColumns, &field) == NULL) {
|
if (taosArrayPush(pReq->pColumns, &field) == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -587,19 +588,28 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
|
||||||
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
|
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
|
||||||
SField field = {0};
|
SField field = {0};
|
||||||
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
|
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
|
||||||
|
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
|
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
|
||||||
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
|
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
|
||||||
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
|
|
||||||
if (taosArrayPush(pReq->pTags, &field) == NULL) {
|
if (taosArrayPush(pReq->pTags, &field) == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pReq->numOfFuncs; ++i) {
|
||||||
|
char pFunc[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
|
if (tDecodeCStrTo(&decoder, pFunc) < 0) return -1;
|
||||||
|
if (taosArrayPush(pReq->pFuncs, pFunc) == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pReq->commentLen > 0) {
|
if (pReq->commentLen > 0) {
|
||||||
pReq->comment = taosMemoryMalloc(pReq->commentLen + 1);
|
pReq->pComment = taosMemoryMalloc(pReq->commentLen + 1);
|
||||||
if (pReq->comment == NULL) return -1;
|
if (pReq->pComment == NULL) return -1;
|
||||||
if (tDecodeCStrTo(&decoder, pReq->comment) < 0) return -1;
|
if (tDecodeCStrTo(&decoder, pReq->pComment) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReq->ast1Len > 0) {
|
if (pReq->ast1Len > 0) {
|
||||||
|
@ -614,23 +624,7 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
|
||||||
if (tDecodeCStrTo(&decoder, pReq->pAst2) < 0) return -1;
|
if (tDecodeCStrTo(&decoder, pReq->pAst2) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfFuncs = 0;
|
|
||||||
if (tDecodeI32(&decoder, &numOfFuncs) < 0) return -1;
|
|
||||||
if (numOfFuncs > 0) {
|
|
||||||
pReq->pFuncs = taosArrayInit(numOfFuncs, TSDB_FUNC_NAME_LEN);
|
|
||||||
if (NULL == pReq->pFuncs) return -1;
|
|
||||||
}
|
|
||||||
for (int32_t i = 0; i < numOfFuncs; ++i) {
|
|
||||||
char pFunc[TSDB_FUNC_NAME_LEN] = {0};
|
|
||||||
if (tDecodeCStrTo(&decoder, pFunc) < 0) return -1;
|
|
||||||
if (taosArrayPush(pReq->pFuncs, pFunc) == NULL) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tEndDecode(&decoder);
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -638,10 +632,10 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
|
||||||
void tFreeSMCreateStbReq(SMCreateStbReq *pReq) {
|
void tFreeSMCreateStbReq(SMCreateStbReq *pReq) {
|
||||||
taosArrayDestroy(pReq->pColumns);
|
taosArrayDestroy(pReq->pColumns);
|
||||||
taosArrayDestroy(pReq->pTags);
|
taosArrayDestroy(pReq->pTags);
|
||||||
taosMemoryFreeClear(pReq->comment);
|
taosArrayDestroy(pReq->pFuncs);
|
||||||
|
taosMemoryFreeClear(pReq->pComment);
|
||||||
taosMemoryFreeClear(pReq->pAst1);
|
taosMemoryFreeClear(pReq->pAst1);
|
||||||
taosMemoryFreeClear(pReq->pAst2);
|
taosMemoryFreeClear(pReq->pAst2);
|
||||||
taosArrayDestroy(pReq->pFuncs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tSerializeSMDropStbReq(void *buf, int32_t bufLen, SMDropStbReq *pReq) {
|
int32_t tSerializeSMDropStbReq(void *buf, int32_t bufLen, SMDropStbReq *pReq) {
|
||||||
|
|
|
@ -155,7 +155,8 @@ void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uin
|
||||||
void taosVariantDestroy(SVariant *pVar) {
|
void taosVariantDestroy(SVariant *pVar) {
|
||||||
if (pVar == NULL) return;
|
if (pVar == NULL) return;
|
||||||
|
|
||||||
if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR) {
|
if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR
|
||||||
|
|| pVar->nType == TSDB_DATA_TYPE_JSON) {
|
||||||
taosMemoryFreeClear(pVar->pz);
|
taosMemoryFreeClear(pVar->pz);
|
||||||
pVar->nLen = 0;
|
pVar->nLen = 0;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +185,8 @@ void taosVariantAssign(SVariant *pDst, const SVariant *pSrc) {
|
||||||
if (pSrc == NULL || pDst == NULL) return;
|
if (pSrc == NULL || pDst == NULL) return;
|
||||||
|
|
||||||
pDst->nType = pSrc->nType;
|
pDst->nType = pSrc->nType;
|
||||||
if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR) {
|
if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR
|
||||||
|
|| pSrc->nType == TSDB_DATA_TYPE_JSON) {
|
||||||
int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE;
|
int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE;
|
||||||
char *p = taosMemoryRealloc(pDst->pz, len);
|
char *p = taosMemoryRealloc(pDst->pz, len);
|
||||||
assert(p);
|
assert(p);
|
||||||
|
@ -976,6 +978,7 @@ char *taosVariantGet(SVariant *pVar, int32_t type) {
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
return (char *)&pVar->d;
|
return (char *)&pVar->d;
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
case TSDB_DATA_TYPE_JSON:
|
||||||
return (char *)pVar->pz;
|
return (char *)pVar->pz;
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
return (char *)pVar->ucs4;
|
return (char *)pVar->ucs4;
|
||||||
|
|
|
@ -341,11 +341,12 @@ typedef struct {
|
||||||
int32_t colVer;
|
int32_t colVer;
|
||||||
int32_t smaVer;
|
int32_t smaVer;
|
||||||
int32_t nextColId;
|
int32_t nextColId;
|
||||||
int64_t watermark[2];
|
|
||||||
int64_t maxdelay[2];
|
int64_t maxdelay[2];
|
||||||
|
int64_t watermark[2];
|
||||||
int32_t ttl;
|
int32_t ttl;
|
||||||
int32_t numOfColumns;
|
int32_t numOfColumns;
|
||||||
int32_t numOfTags;
|
int32_t numOfTags;
|
||||||
|
int32_t numOfFuncs;
|
||||||
int32_t commentLen;
|
int32_t commentLen;
|
||||||
int32_t ast1Len;
|
int32_t ast1Len;
|
||||||
int32_t ast2Len;
|
int32_t ast2Len;
|
||||||
|
|
|
@ -47,6 +47,7 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, S
|
||||||
void *mndBuildCreateVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *cntlen, bool standby);
|
void *mndBuildCreateVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *cntlen, bool standby);
|
||||||
void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
||||||
void *mndBuildAlterVnodeReq(SMnode *, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
void *mndBuildAlterVnodeReq(SMnode *, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
||||||
|
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -645,7 +645,7 @@ static int32_t mndSetAlterDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
if (pVgroup->dbUid == pNew->uid) {
|
if (mndVgroupInDb(pVgroup, pNew->uid)) {
|
||||||
if (mndBuildAlterVgroupAction(pMnode, pTrans, pNew, pVgroup, pArray) != 0) {
|
if (mndBuildAlterVgroupAction(pMnode, pTrans, pNew, pVgroup, pArray) != 0) {
|
||||||
sdbCancelFetch(pSdb, pIter);
|
sdbCancelFetch(pSdb, pIter);
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
|
@ -1006,7 +1006,7 @@ static int32_t mndGetDBTableNum(SDbObj *pDb, SMnode *pMnode) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
if (pVgroup->dbUid == pDb->uid) {
|
if (mndVgroupInDb(pVgroup, pDb->uid)) {
|
||||||
numOfTables += pVgroup->numOfTables / TSDB_TABLE_NUM_UNIT;
|
numOfTables += pVgroup->numOfTables / TSDB_TABLE_NUM_UNIT;
|
||||||
vindex++;
|
vindex++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,10 +225,11 @@ int32_t mndAddShuffleSinkTasksToStream(SMnode* pMnode, SStreamObj* pStream) {
|
||||||
SVgObj* pVgroup;
|
SVgObj* pVgroup;
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (strcmp(pVgroup->dbName, pStream->targetDb) != 0) {
|
if (!mndVgroupInDb(pVgroup, pStream->targetDbUid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
||||||
if (pTask == NULL) {
|
if (pTask == NULL) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
|
@ -420,10 +421,11 @@ int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) {
|
||||||
SVgObj* pVgroup;
|
SVgObj* pVgroup;
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pStream->sourceDbUid) {
|
if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
||||||
if (pInnerTask == NULL) {
|
if (pInnerTask == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -483,10 +485,11 @@ int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) {
|
||||||
SVgObj* pVgroup;
|
SVgObj* pVgroup;
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pStream->sourceDbUid) {
|
if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
||||||
if (pTask == NULL) {
|
if (pTask == NULL) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
|
@ -559,7 +562,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pTopic->dbUid) {
|
if (!mndVgroupInDb(pVgroup, pTopic->dbUid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,6 +396,8 @@ static int32_t mndSetUpdateSmaStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb
|
||||||
stbObj.pColumns = NULL;
|
stbObj.pColumns = NULL;
|
||||||
stbObj.numOfTags = 0;
|
stbObj.numOfTags = 0;
|
||||||
stbObj.pTags = NULL;
|
stbObj.pTags = NULL;
|
||||||
|
stbObj.numOfFuncs = 0;
|
||||||
|
stbObj.pFuncs = NULL;
|
||||||
stbObj.updateTime = taosGetTimestampMs();
|
stbObj.updateTime = taosGetTimestampMs();
|
||||||
stbObj.lock = 0;
|
stbObj.lock = 0;
|
||||||
stbObj.smaVer++;
|
stbObj.smaVer++;
|
||||||
|
@ -408,47 +410,6 @@ static int32_t mndSetUpdateSmaStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int32_t mndSetCreateSmaRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSmaObj *pSma) {
|
|
||||||
SSdb *pSdb = pMnode->pSdb;
|
|
||||||
SVgObj *pVgroup = NULL;
|
|
||||||
void *pIter = NULL;
|
|
||||||
int32_t contLen;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
|
||||||
if (pIter == NULL) break;
|
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *pReq = mndBuildVCreateSmaReq(pMnode, pVgroup, pSma, &contLen);
|
|
||||||
if (pReq == NULL) {
|
|
||||||
sdbCancelFetch(pSdb, pIter);
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
STransAction action = {0};
|
|
||||||
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
|
||||||
action.pCont = pReq;
|
|
||||||
action.contLen = contLen;
|
|
||||||
action.msgType = TDMT_VND_CREATE_SMA;
|
|
||||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
|
||||||
taosMemoryFree(pReq);
|
|
||||||
sdbCancelFetch(pSdb, pIter);
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
|
static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
|
||||||
SSmaObj *pSma) {
|
SSmaObj *pSma) {
|
||||||
SVnodeGid *pVgid = pVgroup->vnodeGid + 0;
|
SVnodeGid *pVgid = pVgroup->vnodeGid + 0;
|
||||||
|
@ -621,7 +582,6 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
|
||||||
if (mndSetCreateSmaCommitLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
if (mndSetCreateSmaCommitLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
||||||
if (mndSetCreateSmaVgroupCommitLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
|
if (mndSetCreateSmaVgroupCommitLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
|
||||||
if (mndSetUpdateSmaStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
if (mndSetUpdateSmaStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
||||||
// if (mndSetCreateSmaRedoActions(pMnode, pTrans, pDb, &smaObj) != 0) goto _OVER;
|
|
||||||
if (mndSetCreateSmaVgroupRedoActions(pMnode, pTrans, pDb, &streamObj.fixedSinkVg, &smaObj) != 0) goto _OVER;
|
if (mndSetCreateSmaVgroupRedoActions(pMnode, pTrans, pDb, &streamObj.fixedSinkVg, &smaObj) != 0) goto _OVER;
|
||||||
if (mndScheduleStream(pMnode, &streamObj) != 0) goto _OVER;
|
if (mndScheduleStream(pMnode, &streamObj) != 0) goto _OVER;
|
||||||
if (mndPersistStream(pMnode, pTrans, &streamObj) != 0) goto _OVER;
|
if (mndPersistStream(pMnode, pTrans, &streamObj) != 0) goto _OVER;
|
||||||
|
@ -770,49 +730,6 @@ static int32_t mndSetDropSmaVgroupCommitLogs(SMnode *pMnode, STrans *pTrans, SVg
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int32_t mndSetDropSmaRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SSmaObj *pSma) {
|
|
||||||
SSdb *pSdb = pMnode->pSdb;
|
|
||||||
SVgObj *pVgroup = NULL;
|
|
||||||
void *pIter = NULL;
|
|
||||||
int32_t contLen;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
|
||||||
if (pIter == NULL) break;
|
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t contLen = 0;
|
|
||||||
void *pReq = mndBuildVDropSmaReq(pMnode, pVgroup, pSma, &contLen);
|
|
||||||
if (pReq == NULL) {
|
|
||||||
sdbCancelFetch(pSdb, pIter);
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
STransAction action = {0};
|
|
||||||
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
|
||||||
action.pCont = pReq;
|
|
||||||
action.contLen = contLen;
|
|
||||||
action.msgType = TDMT_VND_DROP_SMA;
|
|
||||||
action.acceptableCode = TSDB_CODE_VND_SMA_NOT_EXIST;
|
|
||||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
|
||||||
taosMemoryFree(pReq);
|
|
||||||
sdbCancelFetch(pSdb, pIter);
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int32_t mndSetDropSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
|
static int32_t mndSetDropSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
|
||||||
SVnodeGid *pVgid = pVgroup->vnodeGid + 0;
|
SVnodeGid *pVgid = pVgroup->vnodeGid + 0;
|
||||||
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
|
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
|
||||||
|
@ -879,7 +796,6 @@ static int32_t mndDropSma(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SSmaObj *p
|
||||||
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
||||||
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
||||||
if (mndSetUpdateSmaStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
if (mndSetUpdateSmaStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
||||||
// if (mndSetDropSmaRedoActions(pMnode, pTrans, pDb, pSma) != 0) goto _OVER;
|
|
||||||
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
|
@ -906,10 +822,20 @@ int32_t mndDropSmasByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *p
|
||||||
if (pSma->stbUid == pStb->uid) {
|
if (pSma->stbUid == pStb->uid) {
|
||||||
pVgroup = mndAcquireVgroup(pMnode, pSma->dstVgId);
|
pVgroup = mndAcquireVgroup(pMnode, pSma->dstVgId);
|
||||||
if (pVgroup == NULL) goto _OVER;
|
if (pVgroup == NULL) goto _OVER;
|
||||||
|
|
||||||
|
SStreamObj *pStream = mndAcquireStream(pMnode, pSma->name);
|
||||||
|
if (pStream != NULL && pStream->smaId == pSma->uid) {
|
||||||
|
if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) {
|
||||||
|
mError("stream:%s, failed to drop task since %s", pStream->name, terrstr());
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) {
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupCommitLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
||||||
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
if (mndSetDropSmaVgroupRedoActions(pMnode, pTrans, pDb, pVgroup) != 0) goto _OVER;
|
||||||
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
||||||
// if (mndSetDropSmaRedoActions(pMnode, pTrans, pDb, pSma) != 0) goto _OVER;
|
|
||||||
mndReleaseVgroup(pMnode, pVgroup);
|
mndReleaseVgroup(pMnode, pVgroup);
|
||||||
pVgroup = NULL;
|
pVgroup = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ void mndCleanupStb(SMnode *pMnode) {}
|
||||||
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + +pStb->commentLen +
|
int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + pStb->commentLen +
|
||||||
pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE + taosArrayGetSize(pStb->pFuncs) * TSDB_FUNC_NAME_LEN;
|
pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE + taosArrayGetSize(pStb->pFuncs) * TSDB_FUNC_NAME_LEN;
|
||||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size);
|
SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size);
|
||||||
if (pRaw == NULL) goto _OVER;
|
if (pRaw == NULL) goto _OVER;
|
||||||
|
@ -92,6 +92,7 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
||||||
SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, _OVER)
|
SDB_SET_INT64(pRaw, dataPos, pStb->dbUid, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pStb->smaVer, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
|
||||||
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[0], _OVER)
|
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[0], _OVER)
|
||||||
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[1], _OVER)
|
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[1], _OVER)
|
||||||
|
@ -100,17 +101,11 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pStb->numOfFuncs, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->commentLen, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER)
|
||||||
|
|
||||||
int32_t funcNum = taosArrayGetSize(pStb->pFuncs);
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, funcNum, _OVER)
|
|
||||||
for (int32_t i = 0; i < funcNum; ++i) {
|
|
||||||
char *func = taosArrayGet(pStb->pFuncs, i);
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, func, TSDB_FUNC_NAME_LEN, _OVER)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||||
SSchema *pSchema = &pStb->pColumns[i];
|
SSchema *pSchema = &pStb->pColumns[i];
|
||||||
SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
|
SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER)
|
||||||
|
@ -129,15 +124,23 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
|
SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
|
||||||
|
char *func = taosArrayGet(pStb->pFuncs, i);
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, func, TSDB_FUNC_NAME_LEN, _OVER)
|
||||||
|
}
|
||||||
|
|
||||||
if (pStb->commentLen > 0) {
|
if (pStb->commentLen > 0) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
|
SDB_SET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pStb->ast1Len > 0) {
|
if (pStb->ast1Len > 0) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
|
SDB_SET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pStb->ast2Len > 0) {
|
if (pStb->ast2Len > 0) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
|
SDB_SET_BINARY(pRaw, dataPos, pStb->pAst2, pStb->ast2Len, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
|
SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
|
||||||
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
||||||
|
|
||||||
|
@ -180,6 +183,7 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, _OVER)
|
SDB_GET_INT64(pRaw, dataPos, &pStb->dbUid, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pStb->smaVer, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
|
||||||
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[0], _OVER)
|
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[0], _OVER)
|
||||||
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[1], _OVER)
|
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[1], _OVER)
|
||||||
|
@ -188,27 +192,15 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfFuncs, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->commentLen, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER)
|
||||||
|
|
||||||
int32_t funcNum = 0;
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &funcNum, _OVER)
|
|
||||||
if (funcNum > 0) {
|
|
||||||
pStb->pFuncs = taosArrayInit(funcNum, TSDB_FUNC_NAME_LEN);
|
|
||||||
if (NULL == pStb->pFuncs) {
|
|
||||||
goto _OVER;
|
|
||||||
}
|
|
||||||
char funcName[TSDB_FUNC_NAME_LEN];
|
|
||||||
for (int32_t i = 0; i < funcNum; ++i) {
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, funcName, TSDB_FUNC_NAME_LEN, _OVER)
|
|
||||||
taosArrayPush(pStb->pFuncs, funcName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema));
|
pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema));
|
||||||
pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema));
|
pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema));
|
||||||
if (pStb->pColumns == NULL || pStb->pTags == NULL) {
|
pStb->pFuncs = taosArrayInit(pStb->numOfFuncs, TSDB_FUNC_NAME_LEN);
|
||||||
|
if (pStb->pColumns == NULL || pStb->pTags == NULL || pStb->pFuncs == NULL) {
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,16 +222,24 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
|
SDB_GET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pStb->numOfFuncs; ++i) {
|
||||||
|
char funcName[TSDB_FUNC_NAME_LEN] = {0};
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, funcName, TSDB_FUNC_NAME_LEN, _OVER)
|
||||||
|
taosArrayPush(pStb->pFuncs, funcName);
|
||||||
|
}
|
||||||
|
|
||||||
if (pStb->commentLen > 0) {
|
if (pStb->commentLen > 0) {
|
||||||
pStb->comment = taosMemoryCalloc(pStb->commentLen + 1, 1);
|
pStb->comment = taosMemoryCalloc(pStb->commentLen + 1, 1);
|
||||||
if (pStb->comment == NULL) goto _OVER;
|
if (pStb->comment == NULL) goto _OVER;
|
||||||
SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
|
SDB_GET_BINARY(pRaw, dataPos, pStb->comment, pStb->commentLen + 1, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pStb->ast1Len > 0) {
|
if (pStb->ast1Len > 0) {
|
||||||
pStb->pAst1 = taosMemoryCalloc(pStb->ast1Len, 1);
|
pStb->pAst1 = taosMemoryCalloc(pStb->ast1Len, 1);
|
||||||
if (pStb->pAst1 == NULL) goto _OVER;
|
if (pStb->pAst1 == NULL) goto _OVER;
|
||||||
SDB_GET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
|
SDB_GET_BINARY(pRaw, dataPos, pStb->pAst1, pStb->ast1Len, _OVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pStb->ast2Len > 0) {
|
if (pStb->ast2Len > 0) {
|
||||||
pStb->pAst2 = taosMemoryCalloc(pStb->ast2Len, 1);
|
pStb->pAst2 = taosMemoryCalloc(pStb->ast2Len, 1);
|
||||||
if (pStb->pAst2 == NULL) goto _OVER;
|
if (pStb->pAst2 == NULL) goto _OVER;
|
||||||
|
@ -273,6 +273,7 @@ static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
|
||||||
taosMemoryFreeClear(pStb->pColumns);
|
taosMemoryFreeClear(pStb->pColumns);
|
||||||
taosMemoryFreeClear(pStb->pTags);
|
taosMemoryFreeClear(pStb->pTags);
|
||||||
taosMemoryFreeClear(pStb->comment);
|
taosMemoryFreeClear(pStb->comment);
|
||||||
|
taosMemoryFreeClear(pStb->pFuncs);
|
||||||
taosMemoryFreeClear(pStb->pAst1);
|
taosMemoryFreeClear(pStb->pAst1);
|
||||||
taosMemoryFreeClear(pStb->pAst2);
|
taosMemoryFreeClear(pStb->pAst2);
|
||||||
taosArrayDestroy(pStb->pFuncs);
|
taosArrayDestroy(pStb->pFuncs);
|
||||||
|
@ -322,7 +323,7 @@ static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
|
||||||
pOld->commentLen = pNew->commentLen;
|
pOld->commentLen = pNew->commentLen;
|
||||||
|
|
||||||
if (pOld->ast1Len < pNew->ast1Len) {
|
if (pOld->ast1Len < pNew->ast1Len) {
|
||||||
void *pAst1 = taosMemoryMalloc(pNew->ast1Len);
|
void *pAst1 = taosMemoryMalloc(pNew->ast1Len + 1);
|
||||||
if (pAst1 != NULL) {
|
if (pAst1 != NULL) {
|
||||||
taosMemoryFree(pOld->pAst1);
|
taosMemoryFree(pOld->pAst1);
|
||||||
pOld->pAst1 = pAst1;
|
pOld->pAst1 = pAst1;
|
||||||
|
@ -334,7 +335,7 @@ static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOld->ast2Len < pNew->ast2Len) {
|
if (pOld->ast2Len < pNew->ast2Len) {
|
||||||
void *pAst2 = taosMemoryMalloc(pNew->ast2Len);
|
void *pAst2 = taosMemoryMalloc(pNew->ast2Len + 1);
|
||||||
if (pAst2 != NULL) {
|
if (pAst2 != NULL) {
|
||||||
taosMemoryFree(pOld->pAst2);
|
taosMemoryFree(pOld->pAst2);
|
||||||
pOld->pAst2 = pAst2;
|
pOld->pAst2 = pAst2;
|
||||||
|
@ -361,12 +362,15 @@ static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOld, SStbObj *pNew) {
|
||||||
}
|
}
|
||||||
if (pNew->commentLen > 0) {
|
if (pNew->commentLen > 0) {
|
||||||
memcpy(pOld->comment, pNew->comment, pNew->commentLen + 1);
|
memcpy(pOld->comment, pNew->comment, pNew->commentLen + 1);
|
||||||
|
pOld->commentLen = pNew->commentLen;
|
||||||
}
|
}
|
||||||
if (pNew->ast1Len != 0) {
|
if (pNew->ast1Len != 0) {
|
||||||
memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
|
memcpy(pOld->pAst1, pNew->pAst1, pNew->ast1Len);
|
||||||
|
pOld->ast1Len = pNew->ast1Len;
|
||||||
}
|
}
|
||||||
if (pNew->ast2Len != 0) {
|
if (pNew->ast2Len != 0) {
|
||||||
memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
|
memcpy(pOld->pAst2, pNew->pAst2, pNew->ast2Len);
|
||||||
|
pOld->ast2Len = pNew->ast2Len;
|
||||||
}
|
}
|
||||||
taosWUnLockLatch(&pOld->lock);
|
taosWUnLockLatch(&pOld->lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -575,7 +579,10 @@ int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
|
||||||
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
||||||
if (pRedoRaw == NULL) return -1;
|
if (pRedoRaw == NULL) return -1;
|
||||||
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
|
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||||
|
sdbFreeRaw(pRedoRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;
|
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -584,7 +591,10 @@ static int32_t mndSetCreateStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *p
|
||||||
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
|
||||||
if (pUndoRaw == NULL) return -1;
|
if (pUndoRaw == NULL) return -1;
|
||||||
if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1;
|
if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
|
||||||
|
sdbFreeRaw(pUndoRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;
|
if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -593,7 +603,10 @@ static int32_t mndSetCreateStbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *p
|
||||||
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndSetCreateStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
||||||
if (pCommitRaw == NULL) return -1;
|
if (pCommitRaw == NULL) return -1;
|
||||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
|
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||||
|
sdbFreeRaw(pCommitRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
|
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -608,7 +621,7 @@ static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
if (!mndVgroupInDb(pVgroup, pDb->uid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -646,7 +659,7 @@ static int32_t mndSetCreateStbUndoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
if (!mndVgroupInDb(pVgroup, pDb->uid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -697,6 +710,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
||||||
pDst->dbUid = pDb->uid;
|
pDst->dbUid = pDb->uid;
|
||||||
pDst->tagVer = 1;
|
pDst->tagVer = 1;
|
||||||
pDst->colVer = 1;
|
pDst->colVer = 1;
|
||||||
|
pDst->smaVer = 1;
|
||||||
pDst->nextColId = 1;
|
pDst->nextColId = 1;
|
||||||
pDst->maxdelay[0] = pCreate->delay1;
|
pDst->maxdelay[0] = pCreate->delay1;
|
||||||
pDst->maxdelay[1] = pCreate->delay2;
|
pDst->maxdelay[1] = pCreate->delay2;
|
||||||
|
@ -705,6 +719,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
||||||
pDst->ttl = pCreate->ttl;
|
pDst->ttl = pCreate->ttl;
|
||||||
pDst->numOfColumns = pCreate->numOfColumns;
|
pDst->numOfColumns = pCreate->numOfColumns;
|
||||||
pDst->numOfTags = pCreate->numOfTags;
|
pDst->numOfTags = pCreate->numOfTags;
|
||||||
|
pDst->numOfFuncs = pCreate->numOfFuncs;
|
||||||
pDst->commentLen = pCreate->commentLen;
|
pDst->commentLen = pCreate->commentLen;
|
||||||
pDst->pFuncs = pCreate->pFuncs;
|
pDst->pFuncs = pCreate->pFuncs;
|
||||||
pCreate->pFuncs = NULL;
|
pCreate->pFuncs = NULL;
|
||||||
|
@ -715,7 +730,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(pDst->comment, pCreate->comment, pDst->commentLen + 1);
|
memcpy(pDst->comment, pCreate->pComment, pDst->commentLen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pDst->ast1Len = pCreate->ast1Len;
|
pDst->ast1Len = pCreate->ast1Len;
|
||||||
|
@ -770,20 +785,15 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
||||||
|
|
||||||
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
|
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
|
||||||
SStbObj stbObj = {0};
|
SStbObj stbObj = {0};
|
||||||
|
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
|
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
|
|
||||||
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
|
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
|
||||||
|
|
||||||
if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
|
if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
|
if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER;
|
||||||
|
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
code = 0;
|
code = 0;
|
||||||
|
|
||||||
_OVER:
|
_OVER:
|
||||||
|
@ -906,7 +916,8 @@ _OVER:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
|
static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) {
|
||||||
if (pAlter->commentLen >= 0 || pAlter->ttl != 0) return 0;
|
if (pAlter->commentLen >= 0) return 0;
|
||||||
|
if (pAlter->ttl != 0) return 0;
|
||||||
|
|
||||||
if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
|
if (pAlter->numOfFields < 1 || pAlter->numOfFields != (int32_t)taosArrayGetSize(pAlter->pFields)) {
|
||||||
terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
|
terrno = TSDB_CODE_MND_INVALID_STB_OPTION;
|
||||||
|
@ -969,6 +980,7 @@ static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, cha
|
||||||
memcpy(pNew->comment, pComment, commentLen + 1);
|
memcpy(pNew->comment, pComment, commentLen + 1);
|
||||||
} else if (commentLen == 0) {
|
} else if (commentLen == 0) {
|
||||||
pNew->commentLen = 0;
|
pNew->commentLen = 0;
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ttl >= 0) {
|
if (ttl >= 0) {
|
||||||
|
@ -1245,7 +1257,10 @@ static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbO
|
||||||
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
||||||
if (pRedoRaw == NULL) return -1;
|
if (pRedoRaw == NULL) return -1;
|
||||||
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
|
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||||
|
sdbFreeRaw(pRedoRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
|
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1254,7 +1269,10 @@ static int32_t mndSetAlterStbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pD
|
||||||
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
||||||
if (pCommitRaw == NULL) return -1;
|
if (pCommitRaw == NULL) return -1;
|
||||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
|
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||||
|
sdbFreeRaw(pCommitRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
|
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1269,7 +1287,7 @@ static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
if (!mndVgroupInDb(pVgroup, pDb->uid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1388,7 +1406,7 @@ static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName,
|
||||||
pSchema->bytes = pSrcSchema->bytes;
|
pSchema->bytes = pSrcSchema->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pStb->pFuncs) {
|
if (pStb->numOfFuncs > 0) {
|
||||||
pRsp->pFuncs = taosArrayDup(pStb->pFuncs);
|
pRsp->pFuncs = taosArrayDup(pStb->pFuncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,7 +1644,10 @@ _OVER:
|
||||||
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
|
static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
|
||||||
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
||||||
if (pRedoRaw == NULL) return -1;
|
if (pRedoRaw == NULL) return -1;
|
||||||
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
|
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||||
|
sdbFreeRaw(pRedoRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING) != 0) return -1;
|
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1635,7 +1656,10 @@ static int32_t mndSetDropStbRedoLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pS
|
||||||
static int32_t mndSetDropStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
|
static int32_t mndSetDropStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStbObj *pStb) {
|
||||||
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
||||||
if (pCommitRaw == NULL) return -1;
|
if (pCommitRaw == NULL) return -1;
|
||||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
|
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||||
|
sdbFreeRaw(pCommitRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;
|
if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1649,7 +1673,7 @@ static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
if (pVgroup->dbUid != pDb->uid) {
|
if (!mndVgroupInDb(pVgroup, pDb->uid)) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1683,7 +1707,7 @@ static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *
|
||||||
|
|
||||||
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
|
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq);
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
|
|
||||||
mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
||||||
|
|
|
@ -117,7 +117,7 @@ void mndReConfig(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SReConfigCbMeta cbM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndSnapshotStartRead(struct SSyncFSM *pFsm, void **ppReader) {
|
int32_t mndSnapshotStartRead(struct SSyncFSM *pFsm, void *pParam, void **ppReader) {
|
||||||
mDebug("start to read snapshot from sdb");
|
mDebug("start to read snapshot from sdb");
|
||||||
SMnode *pMnode = pFsm->data;
|
SMnode *pMnode = pFsm->data;
|
||||||
return sdbStartRead(pMnode->pSdb, (SSdbIter **)ppReader, NULL, NULL, NULL);
|
return sdbStartRead(pMnode->pSdb, (SSdbIter **)ppReader, NULL, NULL, NULL);
|
||||||
|
|
|
@ -1146,13 +1146,13 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
||||||
} else {
|
} else {
|
||||||
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
} else if (pAction->rawWritten) {
|
||||||
if (pAction->rawWritten) {
|
|
||||||
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
|
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
|
||||||
code = pAction->errCode;
|
code = pAction->errCode;
|
||||||
} else {
|
} else {
|
||||||
mDebug("trans:%d, %s:%d write successfully", pTrans->id, mndTransStr(pAction->stage), action);
|
mDebug("trans:%d, %s:%d write successfully", pTrans->id, mndTransStr(pAction->stage), action);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -426,7 +426,15 @@ static int32_t mndCompareDnodeId(int32_t *dnode1Id, int32_t *dnode2Id) { return
|
||||||
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
|
static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) {
|
||||||
float d1Score = (float)pDnode1->numOfVnodes / pDnode1->numOfSupportVnodes;
|
float d1Score = (float)pDnode1->numOfVnodes / pDnode1->numOfSupportVnodes;
|
||||||
float d2Score = (float)pDnode2->numOfVnodes / pDnode2->numOfSupportVnodes;
|
float d2Score = (float)pDnode2->numOfVnodes / pDnode2->numOfSupportVnodes;
|
||||||
|
#if 0
|
||||||
|
if (d1Score == d2Score) {
|
||||||
|
return pDnode2->id - pDnode1->id;
|
||||||
|
} else {
|
||||||
|
return d1Score >= d2Score ? 1 : 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
return d1Score >= d2Score ? 1 : 0;
|
return d1Score >= d2Score ? 1 : 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void mndSortVnodeGid(SVgObj *pVgroup) {
|
void mndSortVnodeGid(SVgObj *pVgroup) {
|
||||||
|
@ -1751,4 +1759,6 @@ _OVER:
|
||||||
|
|
||||||
taosArrayDestroy(pArray);
|
taosArrayDestroy(pArray);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; }
|
|
@ -157,7 +157,7 @@ typedef struct {
|
||||||
static STqMgmt tqMgmt = {0};
|
static STqMgmt tqMgmt = {0};
|
||||||
|
|
||||||
// tqRead
|
// tqRead
|
||||||
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead** pHeadWithCkSum);
|
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHead** pHeadWithCkSum);
|
||||||
|
|
||||||
// tqExec
|
// tqExec
|
||||||
int32_t tqLogScanExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataRsp* pRsp, int32_t workerId);
|
int32_t tqLogScanExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataRsp* pRsp, int32_t workerId);
|
||||||
|
@ -178,6 +178,7 @@ STqOffsetStore* tqOffsetOpen();
|
||||||
void tqOffsetClose(STqOffsetStore*);
|
void tqOffsetClose(STqOffsetStore*);
|
||||||
STqOffset* tqOffsetRead(STqOffsetStore* pStore, const char* subscribeKey);
|
STqOffset* tqOffsetRead(STqOffsetStore* pStore, const char* subscribeKey);
|
||||||
int32_t tqOffsetWrite(STqOffsetStore* pStore, const STqOffset* pOffset);
|
int32_t tqOffsetWrite(STqOffsetStore* pStore, const STqOffset* pOffset);
|
||||||
|
int32_t tqOffsetDelete(STqOffsetStore* pStore, const char* subscribeKey);
|
||||||
int32_t tqOffsetSnapshot(STqOffsetStore* pStore);
|
int32_t tqOffsetSnapshot(STqOffsetStore* pStore);
|
||||||
|
|
||||||
// tqSink
|
// tqSink
|
||||||
|
|
|
@ -271,12 +271,12 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, pReq->subKey);
|
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, pReq->subKey);
|
||||||
if (pOffset != NULL) {
|
if (pOffset != NULL) {
|
||||||
fetchOffsetNew = pOffset->val;
|
fetchOffsetNew = pOffset->val;
|
||||||
char formatBuf[50];
|
char formatBuf[80];
|
||||||
tFormatOffset(formatBuf, 50, &fetchOffsetNew);
|
tFormatOffset(formatBuf, 80, &fetchOffsetNew);
|
||||||
tqDebug("tmq poll: consumer %ld, offset reset to %s", consumerId, formatBuf);
|
tqDebug("tmq poll: consumer %ld, offset reset to %s", consumerId, formatBuf);
|
||||||
} else {
|
} else {
|
||||||
if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) {
|
if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) {
|
||||||
if (pReq->useSnapshot) {
|
if (pReq->useSnapshot && pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||||
if (!pHandle->fetchMeta) {
|
if (!pHandle->fetchMeta) {
|
||||||
tqOffsetResetToData(&fetchOffsetNew, 0, 0);
|
tqOffsetResetToData(&fetchOffsetNew, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -302,9 +302,9 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
tqInitDataRsp(&dataRsp, pReq, pHandle->execHandle.subType);
|
tqInitDataRsp(&dataRsp, pReq, pHandle->execHandle.subType);
|
||||||
|
|
||||||
if (fetchOffsetNew.type == TMQ_OFFSET__LOG) {
|
if (fetchOffsetNew.type == TMQ_OFFSET__LOG) {
|
||||||
int64_t fetchVer = fetchOffsetNew.version + 1;
|
int64_t fetchVer = fetchOffsetNew.version + 1;
|
||||||
SWalHead* pHeadWithCkSum = taosMemoryMalloc(sizeof(SWalHead) + 2048);
|
SWalCkHead* pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048);
|
||||||
if (pHeadWithCkSum == NULL) {
|
if (pCkHead == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tqFetchLog(pTq, pHandle, &fetchVer, &pHeadWithCkSum) < 0) {
|
if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead) < 0) {
|
||||||
// TODO add push mgr
|
// TODO add push mgr
|
||||||
|
|
||||||
tqOffsetResetToLog(&dataRsp.rspOffset, fetchVer);
|
tqOffsetResetToLog(&dataRsp.rspOffset, fetchVer);
|
||||||
|
@ -329,7 +329,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
goto OVER;
|
goto OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWalReadHead* pHead = &pHeadWithCkSum->head;
|
SWalCont* pHead = &pCkHead->head;
|
||||||
|
|
||||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||||
TD_VID(pTq->pVnode), fetchVer, pHead->msgType);
|
TD_VID(pTq->pVnode), fetchVer, pHead->msgType);
|
||||||
|
@ -373,13 +373,10 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(pHeadWithCkSum);
|
taosMemoryFree(pCkHead);
|
||||||
} else if (fetchOffsetNew.type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
} else if (fetchOffsetNew.type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
||||||
// 1. set uid and ts
|
tqInfo("retrieve using snapshot req offset: uid %ld ts %ld, actual offset: uid %ld ts %ld", dataRsp.reqOffset.uid,
|
||||||
// 2. get data (rebuild reader if needed)
|
dataRsp.reqOffset.ts, fetchOffsetNew.uid, fetchOffsetNew.ts);
|
||||||
// 3. get new uid and ts
|
|
||||||
|
|
||||||
tqInfo("retrieve using snapshot req offset: uid %ld ts %ld", dataRsp.reqOffset.uid, dataRsp.reqOffset.ts);
|
|
||||||
if (tqScanSnapshot(pTq, &pHandle->execHandle, &dataRsp, fetchOffsetNew, workerId) < 0) {
|
if (tqScanSnapshot(pTq, &pHandle->execHandle, &dataRsp, fetchOffsetNew, workerId) < 0) {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
@ -526,7 +523,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWalReadHead* pHead = &pHeadWithCkSum->head;
|
SWalCont* pHead = &pHeadWithCkSum->head;
|
||||||
|
|
||||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||||
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
|
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
|
||||||
|
@ -601,6 +598,8 @@ int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen) {
|
||||||
int32_t code = taosHashRemove(pTq->handles, pReq->subKey, strlen(pReq->subKey));
|
int32_t code = taosHashRemove(pTq->handles, pReq->subKey, strlen(pReq->subKey));
|
||||||
ASSERT(code == 0);
|
ASSERT(code == 0);
|
||||||
|
|
||||||
|
tqOffsetDelete(pTq->pOffsetStore, pReq->subKey);
|
||||||
|
|
||||||
if (tqMetaDeleteHandle(pTq, pReq->subKey) < 0) {
|
if (tqMetaDeleteHandle(pTq, pReq->subKey) < 0) {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,10 @@ int32_t tqOffsetWrite(STqOffsetStore* pStore, const STqOffset* pOffset) {
|
||||||
return taosHashPut(pStore->pHash, pOffset->subKey, strlen(pOffset->subKey), pOffset, sizeof(STqOffset));
|
return taosHashPut(pStore->pHash, pOffset->subKey, strlen(pOffset->subKey), pOffset, sizeof(STqOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tqOffsetDelete(STqOffsetStore* pStore, const char* subscribeKey) {
|
||||||
|
return taosHashRemove(pStore->pHash, subscribeKey, strlen(subscribeKey));
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tqOffsetSnapshot(STqOffsetStore* pStore) {
|
int32_t tqOffsetSnapshot(STqOffsetStore* pStore) {
|
||||||
// open file
|
// open file
|
||||||
// TODO file name should be with a version
|
// TODO file name should be with a version
|
||||||
|
|
|
@ -15,13 +15,13 @@
|
||||||
|
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
|
|
||||||
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead** ppHeadWithCkSum) {
|
int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHead** ppCkHead) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
taosThreadMutexLock(&pHandle->pWalReader->mutex);
|
taosThreadMutexLock(&pHandle->pWalReader->mutex);
|
||||||
int64_t offset = *fetchOffset;
|
int64_t offset = *fetchOffset;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (walFetchHead(pHandle->pWalReader, offset, *ppHeadWithCkSum) < 0) {
|
if (walFetchHead(pHandle->pWalReader, offset, *ppCkHead) < 0) {
|
||||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", pHandle->consumerId,
|
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", pHandle->consumerId,
|
||||||
pHandle->epoch, TD_VID(pTq->pVnode), offset);
|
pHandle->epoch, TD_VID(pTq->pVnode), offset);
|
||||||
*fetchOffset = offset - 1;
|
*fetchOffset = offset - 1;
|
||||||
|
@ -29,8 +29,8 @@ int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead*
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*ppHeadWithCkSum)->head.msgType == TDMT_VND_SUBMIT) {
|
if ((*ppCkHead)->head.msgType == TDMT_VND_SUBMIT) {
|
||||||
code = walFetchBody(pHandle->pWalReader, ppHeadWithCkSum);
|
code = walFetchBody(pHandle->pWalReader, ppCkHead);
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
@ -43,9 +43,9 @@ int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead*
|
||||||
goto END;
|
goto END;
|
||||||
} else {
|
} else {
|
||||||
if (pHandle->fetchMeta) {
|
if (pHandle->fetchMeta) {
|
||||||
SWalReadHead* pHead = &((*ppHeadWithCkSum)->head);
|
SWalCont* pHead = &((*ppCkHead)->head);
|
||||||
if (IS_META_MSG(pHead->msgType)) {
|
if (IS_META_MSG(pHead->msgType)) {
|
||||||
code = walFetchBody(pHandle->pWalReader, ppHeadWithCkSum);
|
code = walFetchBody(pHandle->pWalReader, ppCkHead);
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
@ -58,7 +58,7 @@ int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead*
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code = walSkipFetchBody(pHandle->pWalReader, *ppHeadWithCkSum);
|
code = walSkipFetchBody(pHandle->pWalReader, *ppCkHead);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
*fetchOffset = offset;
|
*fetchOffset = offset;
|
||||||
|
|
|
@ -119,7 +119,7 @@ static int32_t vnodeProcessAlterReplicaReq(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||||
SVnode * pVnode = pInfo->ahandle;
|
SVnode *pVnode = pInfo->ahandle;
|
||||||
int32_t vgId = pVnode->config.vgId;
|
int32_t vgId = pVnode->config.vgId;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SRpcMsg *pMsg = NULL;
|
SRpcMsg *pMsg = NULL;
|
||||||
|
@ -199,7 +199,7 @@ void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeApplyMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
void vnodeApplyMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||||
SVnode * pVnode = pInfo->ahandle;
|
SVnode *pVnode = pInfo->ahandle;
|
||||||
int32_t vgId = pVnode->config.vgId;
|
int32_t vgId = pVnode->config.vgId;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SRpcMsg *pMsg = NULL;
|
SRpcMsg *pMsg = NULL;
|
||||||
|
@ -240,7 +240,7 @@ int32_t vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||||
STraceId *trace = &pMsg->info.traceId;
|
STraceId *trace = &pMsg->info.traceId;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char * syncNodeStr = sync2SimpleStr(pVnode->sync);
|
char *syncNodeStr = sync2SimpleStr(pVnode->sync);
|
||||||
static int64_t vndTick = 0;
|
static int64_t vndTick = 0;
|
||||||
if (++vndTick % 10 == 1) {
|
if (++vndTick % 10 == 1) {
|
||||||
vGTrace("vgId:%d, sync trace msg:%s, %s", syncGetVgId(pVnode->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
vGTrace("vgId:%d, sync trace msg:%s, %s", syncGetVgId(pVnode->sync), TMSG_INFO(pMsg->msgType), syncNodeStr);
|
||||||
|
@ -375,7 +375,7 @@ static void vnodeSyncReconfig(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SReCon
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
static void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||||
SVnode * pVnode = pFsm->data;
|
SVnode *pVnode = pFsm->data;
|
||||||
SSnapshot snapshot = {0};
|
SSnapshot snapshot = {0};
|
||||||
SyncIndex beginIndex = SYNC_INDEX_INVALID;
|
SyncIndex beginIndex = SYNC_INDEX_INVALID;
|
||||||
char logBuf[256] = {0};
|
char logBuf[256] = {0};
|
||||||
|
@ -409,7 +409,7 @@ static void vnodeSyncRollBackMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta
|
||||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeSnapshotStartRead(struct SSyncFSM *pFsm, void **ppReader) { return 0; }
|
static int32_t vnodeSnapshotStartRead(struct SSyncFSM *pFsm, void *pParam, void **ppReader) { return 0; }
|
||||||
|
|
||||||
static int32_t vnodeSnapshotStopRead(struct SSyncFSM *pFsm, void *pReader) { return 0; }
|
static int32_t vnodeSnapshotStopRead(struct SSyncFSM *pFsm, void *pReader) { return 0; }
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,7 @@ int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) {
|
||||||
SArray* pTagVals = NULL;
|
SArray* pTagVals = NULL;
|
||||||
STag* pTag = (STag*)pCfg->pTags;
|
STag* pTag = (STag*)pCfg->pTags;
|
||||||
|
|
||||||
if (pCfg->pTags && pTag->flags & TD_TAG_JSON) {
|
if (pCfg->pTags && tTagIsJson(pTag)) {
|
||||||
char* pJson = parseTagDatatoJson(pTag);
|
char* pJson = parseTagDatatoJson(pTag);
|
||||||
if (pJson) {
|
if (pJson) {
|
||||||
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s", pJson);
|
*len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s", pJson);
|
||||||
|
|
|
@ -287,6 +287,7 @@ typedef struct STableScanInfo {
|
||||||
} lastStatus;
|
} lastStatus;
|
||||||
|
|
||||||
int8_t scanMode;
|
int8_t scanMode;
|
||||||
|
int8_t noTable;
|
||||||
} STableScanInfo;
|
} STableScanInfo;
|
||||||
|
|
||||||
typedef struct STagScanInfo {
|
typedef struct STagScanInfo {
|
||||||
|
|
|
@ -63,6 +63,7 @@ size_t getResultRowSize(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||||
rowSize += pCtx[i].resDataInfo.interBufSize;
|
rowSize += pCtx[i].resDataInfo.interBufSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rowSize += (numOfOutput * sizeof(bool)); // expand rowSize to mark if col is null for top/bottom result(saveTupleData)
|
||||||
return rowSize;
|
return rowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +113,15 @@ void initGroupedResultInfo(SGroupResInfo* pGroupResInfo, SHashObj* pHashmap, int
|
||||||
p->groupId = *(uint64_t*)key;
|
p->groupId = *(uint64_t*)key;
|
||||||
p->pos = *(SResultRowPosition*)pData;
|
p->pos = *(SResultRowPosition*)pData;
|
||||||
memcpy(p->key, (char*)key + sizeof(uint64_t), keyLen - sizeof(uint64_t));
|
memcpy(p->key, (char*)key + sizeof(uint64_t), keyLen - sizeof(uint64_t));
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_groupRes, groupId:%"PRIu64",pageId:%d,offset:%d\n", p->groupId, p->pos.pageId, p->pos.offset);
|
||||||
|
#endif
|
||||||
taosArrayPush(pGroupResInfo->pRows, &p);
|
taosArrayPush(pGroupResInfo->pRows, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC) {
|
if (order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC) {
|
||||||
__compar_fn_t fn = (order == TSDB_ORDER_ASC) ? resultrowComparAsc : resultrowComparDesc;
|
__compar_fn_t fn = (order == TSDB_ORDER_ASC) ? resultrowComparAsc : resultrowComparDesc;
|
||||||
qsort(pGroupResInfo->pRows->pData, taosArrayGetSize(pGroupResInfo->pRows), POINTER_BYTES, fn);
|
taosSort(pGroupResInfo->pRows->pData, taosArrayGetSize(pGroupResInfo->pRows), POINTER_BYTES, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
pGroupResInfo->index = 0;
|
pGroupResInfo->index = 0;
|
||||||
|
@ -271,6 +274,7 @@ static bool isTableOk(STableKeyInfo* info, SNode* pTagCond, SMeta* metaHandle) {
|
||||||
SNode* pNew = NULL;
|
SNode* pNew = NULL;
|
||||||
int32_t code = scalarCalculateConstants(pTagCondTmp, &pNew);
|
int32_t code = scalarCalculateConstants(pTagCondTmp, &pNew);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
terrno = code;
|
||||||
nodesDestroyNode(pTagCondTmp);
|
nodesDestroyNode(pTagCondTmp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -323,12 +327,19 @@ int32_t getTableList(void* metaHandle, SScanPhysiNode* pScanNode, STableListInfo
|
||||||
code = tsdbGetAllTableList(metaHandle, tableUid, pListInfo->pTableList);
|
code = tsdbGetAllTableList(metaHandle, tableUid, pListInfo->pTableList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTagCond) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("failed to get tableIds, reason: %s, suid: %" PRIu64 "", tstrerror(code), tableUid);
|
||||||
|
terrno = code;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pTagCond){
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
while (i < taosArrayGetSize(pListInfo->pTableList)) {
|
while (i < taosArrayGetSize(pListInfo->pTableList)) {
|
||||||
STableKeyInfo* info = taosArrayGet(pListInfo->pTableList, i);
|
STableKeyInfo* info = taosArrayGet(pListInfo->pTableList, i);
|
||||||
bool isOk = isTableOk(info, pTagCond, metaHandle);
|
bool isOk = isTableOk(info, pTagCond, metaHandle);
|
||||||
if (!isOk) {
|
if(terrno) return terrno;
|
||||||
|
if(!isOk){
|
||||||
taosArrayRemove(pListInfo->pTableList, i);
|
taosArrayRemove(pListInfo->pTableList, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -586,13 +597,16 @@ static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutpu
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0) {
|
if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0 ||
|
||||||
|
strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_group_key") == 0) {
|
||||||
pValCtx[num++] = &pCtx[i];
|
pValCtx[num++] = &pCtx[i];
|
||||||
} else if (fmIsSelectFunc(pCtx[i].functionId)) {
|
} else if (fmIsSelectFunc(pCtx[i].functionId)) {
|
||||||
p = &pCtx[i];
|
p = &pCtx[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_setSelect num:%d", num);
|
||||||
|
#endif
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
p->subsidiaries.pCtx = pValCtx;
|
p->subsidiaries.pCtx = pValCtx;
|
||||||
p->subsidiaries.num = num;
|
p->subsidiaries.num = num;
|
||||||
|
|
|
@ -235,9 +235,11 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, uint64_t uid, int64_t ts) {
|
||||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||||
|
|
||||||
if (uid == 0) {
|
if (uid == 0) {
|
||||||
STableKeyInfo* pTableInfo = taosArrayGet(pTaskInfo->tableqinfoList.pTableList, 0);
|
if (taosArrayGetSize(pTaskInfo->tableqinfoList.pTableList) != 0) {
|
||||||
uid = pTableInfo->uid;
|
STableKeyInfo* pTableInfo = taosArrayGet(pTaskInfo->tableqinfoList.pTableList, 0);
|
||||||
ts = INT64_MIN;
|
uid = pTableInfo->uid;
|
||||||
|
ts = INT64_MIN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return doPrepareScan(pTaskInfo->pRoot, uid, ts);
|
return doPrepareScan(pTaskInfo->pRoot, uid, ts);
|
||||||
|
|
|
@ -274,6 +274,9 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
||||||
|
|
||||||
// 1. close current opened time window
|
// 1. close current opened time window
|
||||||
if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId))) {
|
if (pResultRowInfo->cur.pageId != -1 && ((pResult == NULL) || (pResult->pageId != pResultRowInfo->cur.pageId))) {
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_1");
|
||||||
|
#endif
|
||||||
SResultRowPosition pos = pResultRowInfo->cur;
|
SResultRowPosition pos = pResultRowInfo->cur;
|
||||||
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
SFilePage* pPage = getBufPage(pResultBuf, pos.pageId);
|
||||||
releaseBufPage(pResultBuf, pPage);
|
releaseBufPage(pResultBuf, pPage);
|
||||||
|
@ -281,6 +284,9 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
||||||
|
|
||||||
// allocate a new buffer page
|
// allocate a new buffer page
|
||||||
if (pResult == NULL) {
|
if (pResult == NULL) {
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_2");
|
||||||
|
#endif
|
||||||
ASSERT(pSup->resultRowSize > 0);
|
ASSERT(pSup->resultRowSize > 0);
|
||||||
pResult = getNewResultRow(pResultBuf, groupId, pSup->resultRowSize);
|
pResult = getNewResultRow(pResultBuf, groupId, pSup->resultRowSize);
|
||||||
|
|
||||||
|
@ -538,7 +544,9 @@ static int32_t doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunct
|
||||||
if (pCtx[k].fpSet.process == NULL) {
|
if (pCtx[k].fpSet.process == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_process");
|
||||||
|
#endif
|
||||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||||
|
@ -1413,7 +1421,9 @@ void setExecutionContext(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t
|
||||||
if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
|
if (pAggInfo->groupId != INT32_MIN && pAggInfo->groupId == groupId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_setbuf, groupId:%"PRIu64, groupId);
|
||||||
|
#endif
|
||||||
doSetTableGroupOutputBuf(pOperator, pAggInfo, numOfOutput, groupId);
|
doSetTableGroupOutputBuf(pOperator, pAggInfo, numOfOutput, groupId);
|
||||||
|
|
||||||
// record the current active group id
|
// record the current active group id
|
||||||
|
@ -1489,11 +1499,15 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
||||||
int32_t numOfExprs) {
|
int32_t numOfExprs) {
|
||||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||||
int32_t start = pGroupResInfo->index;
|
int32_t start = pGroupResInfo->index;
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("\npage_copytoblock rows:%d", numOfRows);
|
||||||
|
#endif
|
||||||
for (int32_t i = start; i < numOfRows; i += 1) {
|
for (int32_t i = start; i < numOfRows; i += 1) {
|
||||||
SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
|
SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
|
||||||
SFilePage* page = getBufPage(pBuf, pPos->pos.pageId);
|
SFilePage* page = getBufPage(pBuf, pPos->pos.pageId);
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_copytoblock pos pageId:%d, offset:%d", pPos->pos.pageId, pPos->pos.offset);
|
||||||
|
#endif
|
||||||
SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
|
SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
|
||||||
|
|
||||||
doUpdateNumOfRows(pRow, numOfExprs, rowCellOffset);
|
doUpdateNumOfRows(pRow, numOfExprs, rowCellOffset);
|
||||||
|
@ -1525,6 +1539,9 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
||||||
|
|
||||||
pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowCellOffset);
|
pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowCellOffset);
|
||||||
if (pCtx[j].fpSet.finalize) {
|
if (pCtx[j].fpSet.finalize) {
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("\npage_finalize %d", numOfExprs);
|
||||||
|
#endif
|
||||||
int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock);
|
||||||
if (TAOS_FAILED(code)) {
|
if (TAOS_FAILED(code)) {
|
||||||
qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code));
|
||||||
|
@ -1553,9 +1570,9 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
||||||
|
|
||||||
releaseBufPage(pBuf, page);
|
releaseBufPage(pBuf, page);
|
||||||
pBlock->info.rows += pRow->numOfRows;
|
pBlock->info.rows += pRow->numOfRows;
|
||||||
if (pBlock->info.rows >= pBlock->info.capacity) { // output buffer is full
|
// if (pBlock->info.rows >= pBlock->info.capacity) { // output buffer is full
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("%s result generated, rows:%d, groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
qDebug("%s result generated, rows:%d, groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
||||||
|
@ -2373,8 +2390,7 @@ static int32_t initExchangeOperator(SExchangePhysiNode* pExNode, SExchangeInfo*
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
|
pInfo->pSources = taosArrayInit(numOfSources, sizeof(SDownstreamSourceNode));
|
||||||
pInfo->pSourceDataInfo = taosArrayInit(numOfSources, sizeof(SSourceDataInfo));
|
if (pInfo->pSources == NULL) {
|
||||||
if (pInfo->pSourceDataInfo == NULL || pInfo->pSources == NULL) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2829,21 +2845,28 @@ int32_t doPrepareScan(SOperatorInfo* pOperator, uint64_t uid, int64_t ts) {
|
||||||
pScanInfo->blockType = STREAM_INPUT__DATA_SCAN;
|
pScanInfo->blockType = STREAM_INPUT__DATA_SCAN;
|
||||||
|
|
||||||
STableScanInfo* pInfo = pScanInfo->pSnapshotReadOp->info;
|
STableScanInfo* pInfo = pScanInfo->pSnapshotReadOp->info;
|
||||||
|
if (uid == 0) {
|
||||||
|
pInfo->noTable = 1;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*if (pSnapShotScanInfo->dataReader == NULL) {*/
|
/*if (pSnapShotScanInfo->dataReader == NULL) {*/
|
||||||
/*pSnapShotScanInfo->dataReader = tsdbReaderOpen(pHandle->vnode, &pSTInfo->cond, tableList, 0, 0);*/
|
/*pSnapShotScanInfo->dataReader = tsdbReaderOpen(pHandle->vnode, &pSTInfo->cond, tableList, 0, 0);*/
|
||||||
/*pSnapShotScanInfo->scanMode = TABLE_SCAN__TABLE_ORDER;*/
|
/*pSnapShotScanInfo->scanMode = TABLE_SCAN__TABLE_ORDER;*/
|
||||||
/*}*/
|
/*}*/
|
||||||
|
|
||||||
|
pInfo->noTable = 0;
|
||||||
|
|
||||||
if (pInfo->lastStatus.uid != uid || pInfo->lastStatus.ts != ts) {
|
if (pInfo->lastStatus.uid != uid || pInfo->lastStatus.ts != ts) {
|
||||||
tsdbSetTableId(pInfo->dataReader, uid);
|
tsdbSetTableId(pInfo->dataReader, uid);
|
||||||
int64_t oldSkey = pInfo->cond.twindows[0].skey;
|
int64_t oldSkey = pInfo->cond.twindows[0].skey;
|
||||||
pInfo->cond.twindows[0].skey = ts;
|
pInfo->cond.twindows[0].skey = ts + 1;
|
||||||
tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0);
|
tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0);
|
||||||
pInfo->cond.twindows[0].skey = oldSkey;
|
pInfo->cond.twindows[0].skey = oldSkey;
|
||||||
pInfo->scanTimes = 0;
|
pInfo->scanTimes = 0;
|
||||||
pInfo->curTWinIdx = 0;
|
pInfo->curTWinIdx = 0;
|
||||||
}
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (pOperator->numOfDownstream == 1) {
|
if (pOperator->numOfDownstream == 1) {
|
||||||
|
@ -2856,8 +2879,6 @@ int32_t doPrepareScan(SOperatorInfo* pOperator, uint64_t uid, int64_t ts) {
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doGetScanStatus(SOperatorInfo* pOperator, uint64_t* uid, int64_t* ts) {
|
int32_t doGetScanStatus(SOperatorInfo* pOperator, uint64_t* uid, int64_t* ts) {
|
||||||
|
@ -3160,8 +3181,9 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for the limitation in each group
|
// check for the limitation in each group
|
||||||
if (pProjectInfo->limit.limit > 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) {
|
if (pProjectInfo->limit.limit >= 0 && pProjectInfo->curOutput + pRes->info.rows >= pProjectInfo->limit.limit) {
|
||||||
pRes->info.rows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput);
|
int32_t keepRows = (int32_t)(pProjectInfo->limit.limit - pProjectInfo->curOutput);
|
||||||
|
blockDataKeepFirstNRows(pRes, keepRows);
|
||||||
if (pProjectInfo->slimit.limit > 0 && pProjectInfo->slimit.limit <= pProjectInfo->curGroupOutput) {
|
if (pProjectInfo->slimit.limit > 0 && pProjectInfo->slimit.limit <= pProjectInfo->curGroupOutput) {
|
||||||
pOperator->status = OP_EXEC_DONE;
|
pOperator->status = OP_EXEC_DONE;
|
||||||
}
|
}
|
||||||
|
@ -3235,8 +3257,6 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
longjmp(pTaskInfo->env, code);
|
longjmp(pTaskInfo->env, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
doFilter(pProjectInfo->pFilterNode, pBlock);
|
|
||||||
|
|
||||||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, scanFlag, false);
|
setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, scanFlag, false);
|
||||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
||||||
|
|
||||||
|
@ -3247,6 +3267,10 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t status = handleLimitOffset(pOperator, pBlock);
|
int32_t status = handleLimitOffset(pOperator, pBlock);
|
||||||
|
|
||||||
|
// filter shall be applied after apply functions and limit/offset on the result
|
||||||
|
doFilter(pProjectInfo->pFilterNode, pInfo->pRes);
|
||||||
|
|
||||||
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
||||||
continue;
|
continue;
|
||||||
} else if (status == PROJECT_RETRIEVE_DONE) {
|
} else if (status == PROJECT_RETRIEVE_DONE) {
|
||||||
|
@ -3473,11 +3497,12 @@ int32_t initAggInfo(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInf
|
||||||
}
|
}
|
||||||
|
|
||||||
void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows) {
|
void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows) {
|
||||||
|
ASSERT(numOfRows != 0);
|
||||||
pOperator->resultInfo.capacity = numOfRows;
|
pOperator->resultInfo.capacity = numOfRows;
|
||||||
pOperator->resultInfo.threshold = numOfRows * 0.75;
|
pOperator->resultInfo.threshold = numOfRows * 0.75;
|
||||||
|
|
||||||
if (pOperator->resultInfo.threshold == 0) {
|
if (pOperator->resultInfo.threshold == 0) {
|
||||||
pOperator->resultInfo.capacity = numOfRows;
|
pOperator->resultInfo.threshold = numOfRows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3977,12 +4002,12 @@ static int32_t sortTableGroup(STableListInfo* pTableListInfo, int32_t groupNum)
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
}
|
}
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
if (taosArrayPush(sortSupport, groupId) != NULL) {
|
if (taosArrayPush(sortSupport, groupId) == NULL) {
|
||||||
qError("taos push support array error");
|
qError("taos push support array error");
|
||||||
taosArrayDestroy(sortSupport);
|
taosArrayDestroy(sortSupport);
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
}
|
}
|
||||||
if (taosArrayPush(pTableListInfo->pGroupList, &tGroup) != NULL) {
|
if (taosArrayPush(pTableListInfo->pGroupList, &tGroup) == NULL) {
|
||||||
qError("taos push group array error");
|
qError("taos push group array error");
|
||||||
taosArrayDestroy(sortSupport);
|
taosArrayDestroy(sortSupport);
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
|
@ -4062,6 +4087,7 @@ int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle,
|
||||||
} else {
|
} else {
|
||||||
taosMemoryFree(keyBuf);
|
taosMemoryFree(keyBuf);
|
||||||
nodesClearList(groupNew);
|
nodesClearList(groupNew);
|
||||||
|
metaReaderClear(&mr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4074,7 +4100,14 @@ int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle,
|
||||||
} else {
|
} else {
|
||||||
isNull[index++] = 0;
|
isNull[index++] = 0;
|
||||||
char* data = nodesGetValueFromNode(pValue);
|
char* data = nodesGetValueFromNode(pValue);
|
||||||
if (pValue->node.resType.type == TSDB_DATA_TYPE_JSON) {
|
if (pValue->node.resType.type == TSDB_DATA_TYPE_JSON){
|
||||||
|
if(tTagIsJson(data)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
|
||||||
|
taosMemoryFree(keyBuf);
|
||||||
|
nodesClearList(groupNew);
|
||||||
|
metaReaderClear(&mr);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
int32_t len = getJsonValueLen(data);
|
int32_t len = getJsonValueLen(data);
|
||||||
memcpy(pStart, data, len);
|
memcpy(pStart, data, len);
|
||||||
pStart += len;
|
pStart += len;
|
||||||
|
@ -4133,7 +4166,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == type) {
|
||||||
STableMergeScanPhysiNode* pTableScanNode = (STableMergeScanPhysiNode*)pPhyNode;
|
STableMergeScanPhysiNode* pTableScanNode = (STableMergeScanPhysiNode*)pPhyNode;
|
||||||
int32_t code = createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
int32_t code = createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||||
if (code) {
|
if(code){
|
||||||
|
pTaskInfo->code = code;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
code = extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
code = extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||||
|
@ -4160,7 +4194,11 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
||||||
.maxTs = INT64_MIN,
|
.maxTs = INT64_MIN,
|
||||||
};
|
};
|
||||||
if (pHandle) {
|
if (pHandle) {
|
||||||
createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
int32_t code = createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||||
|
if(code){
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SOperatorInfo* pOperator =
|
SOperatorInfo* pOperator =
|
||||||
|
|
|
@ -141,6 +141,10 @@ static void recordNewGroupKeys(SArray* pGroupCols, SArray* pGroupColVals, SSData
|
||||||
pkey->isNull = false;
|
pkey->isNull = false;
|
||||||
char* val = colDataGetData(pColInfoData, rowIndex);
|
char* val = colDataGetData(pColInfoData, rowIndex);
|
||||||
if (pkey->type == TSDB_DATA_TYPE_JSON) {
|
if (pkey->type == TSDB_DATA_TYPE_JSON) {
|
||||||
|
if(tTagIsJson(val)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
int32_t dataLen = getJsonValueLen(val);
|
int32_t dataLen = getJsonValueLen(val);
|
||||||
memcpy(pkey->pData, val, dataLen);
|
memcpy(pkey->pData, val, dataLen);
|
||||||
} else if (IS_VAR_DATA_TYPE(pkey->type)) {
|
} else if (IS_VAR_DATA_TYPE(pkey->type)) {
|
||||||
|
@ -227,11 +231,15 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
STimeWindow w = TSWINDOW_INITIALIZER;
|
STimeWindow w = TSWINDOW_INITIALIZER;
|
||||||
|
|
||||||
|
terrno = TSDB_CODE_SUCCESS;
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||||
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
|
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
|
||||||
if (!pInfo->isInit) {
|
if (!pInfo->isInit) {
|
||||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||||
|
if (terrno != TSDB_CODE_SUCCESS) { // group by json error
|
||||||
|
longjmp(pTaskInfo->env, terrno);
|
||||||
|
}
|
||||||
pInfo->isInit = true;
|
pInfo->isInit = true;
|
||||||
num++;
|
num++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -247,6 +255,9 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
num++;
|
num++;
|
||||||
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
recordNewGroupKeys(pInfo->pGroupCols, pInfo->pGroupColVals, pBlock, j);
|
||||||
|
if (terrno != TSDB_CODE_SUCCESS) { // group by json error
|
||||||
|
longjmp(pTaskInfo->env, terrno);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,7 +672,11 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terrno = TSDB_CODE_SUCCESS;
|
||||||
doHashPartition(pOperator, pBlock);
|
doHashPartition(pOperator, pBlock);
|
||||||
|
if (terrno != TSDB_CODE_SUCCESS) { // group by json error
|
||||||
|
longjmp(pTaskInfo->env, terrno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SArray* groupArray = taosArrayInit(taosHashGetSize(pInfo->pGroupSet), sizeof(SDataGroupInfo));
|
SArray* groupArray = taosArrayInit(taosHashGetSize(pInfo->pGroupSet), sizeof(SDataGroupInfo));
|
||||||
|
|
|
@ -518,6 +518,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
// if scan table by table
|
// if scan table by table
|
||||||
if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
|
if (pInfo->scanMode == TABLE_SCAN__TABLE_ORDER) {
|
||||||
|
if (pInfo->noTable) return NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
SSDataBlock* result = doTableScanGroup(pOperator);
|
SSDataBlock* result = doTableScanGroup(pOperator);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
@ -2089,6 +2090,7 @@ int32_t createScanTableListInfo(STableScanPhysiNode* pTableScanNode, SReadHandle
|
||||||
qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
|
qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
pTableListInfo->needSortTableByGroupId = pTableScanNode->groupSort;
|
||||||
code = generateGroupIdMap(pTableListInfo, pHandle, pTableScanNode->pGroupTags);
|
code = generateGroupIdMap(pTableListInfo, pHandle, pTableScanNode->pGroupTags);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
|
|
@ -593,7 +593,10 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
if (size > sortBufSize) {
|
if (size > sortBufSize) {
|
||||||
// Perform the in-memory sort and then flush data in the buffer into disk.
|
// Perform the in-memory sort and then flush data in the buffer into disk.
|
||||||
int64_t p = taosGetTimestampUs();
|
int64_t p = taosGetTimestampUs();
|
||||||
blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
||||||
|
if (code != 0) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t el = taosGetTimestampUs() - p;
|
int64_t el = taosGetTimestampUs() - p;
|
||||||
pHandle->sortElapsed += el;
|
pHandle->sortElapsed += el;
|
||||||
|
@ -608,7 +611,10 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
||||||
// Perform the in-memory sort and then flush data in the buffer into disk.
|
// Perform the in-memory sort and then flush data in the buffer into disk.
|
||||||
int64_t p = taosGetTimestampUs();
|
int64_t p = taosGetTimestampUs();
|
||||||
|
|
||||||
blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
int32_t code = blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
||||||
|
if (code != 0) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t el = taosGetTimestampUs() - p;
|
int64_t el = taosGetTimestampUs() - p;
|
||||||
pHandle->sortElapsed += el;
|
pHandle->sortElapsed += el;
|
||||||
|
|
|
@ -117,6 +117,9 @@ int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||||
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||||
int32_t getFirstLastInfoSize(int32_t resBytes);
|
int32_t getFirstLastInfoSize(int32_t resBytes);
|
||||||
|
|
||||||
|
int32_t lastRowFunction(SqlFunctionCtx *pCtx);
|
||||||
|
int32_t lastRowFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
|
|
||||||
bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
||||||
bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
||||||
bool topBotFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool topBotFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
|
|
|
@ -32,7 +32,7 @@ extern "C" {
|
||||||
#define FUNC_MGT_STRING_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(3)
|
#define FUNC_MGT_STRING_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(3)
|
||||||
#define FUNC_MGT_DATETIME_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(4)
|
#define FUNC_MGT_DATETIME_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(4)
|
||||||
#define FUNC_MGT_TIMELINE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(5)
|
#define FUNC_MGT_TIMELINE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(5)
|
||||||
#define FUNC_MGT_TIMEORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(6)
|
#define FUNC_MGT_IMPLICIT_TS_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(6)
|
||||||
#define FUNC_MGT_PSEUDO_COLUMN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(7)
|
#define FUNC_MGT_PSEUDO_COLUMN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(7)
|
||||||
#define FUNC_MGT_WINDOW_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(8)
|
#define FUNC_MGT_WINDOW_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(8)
|
||||||
#define FUNC_MGT_SPECIAL_DATA_REQUIRED FUNC_MGT_FUNC_CLASSIFICATION_MASK(9)
|
#define FUNC_MGT_SPECIAL_DATA_REQUIRED FUNC_MGT_FUNC_CLASSIFICATION_MASK(9)
|
||||||
|
|
|
@ -238,7 +238,7 @@ static int32_t translateWduration(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
static int32_t translateNowToday(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateNowToday(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
// pseudo column do not need to check parameters
|
// pseudo column do not need to check parameters
|
||||||
|
|
||||||
//add database precision as param
|
// add database precision as param
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
|
|
||||||
|
@ -634,6 +634,12 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
}
|
}
|
||||||
|
|
||||||
// param1 ~ param3
|
// 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 ||
|
||||||
|
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 1; i < numOfParams; ++i) {
|
for (int32_t i = 1; i < numOfParams; ++i) {
|
||||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i);
|
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i);
|
||||||
if (QUERY_NODE_VALUE != nodeType(pParamNode)) {
|
if (QUERY_NODE_VALUE != nodeType(pParamNode)) {
|
||||||
|
@ -643,12 +649,11 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||||
|
|
||||||
pValue->notReserved = true;
|
pValue->notReserved = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) {
|
||||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
"HISTOGRAM function normalized parameter should be 0/1");
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType){.bytes = 512, .type = TSDB_DATA_TYPE_BINARY};
|
pFunc->node.resType = (SDataType){.bytes = 512, .type = TSDB_DATA_TYPE_BINARY};
|
||||||
|
@ -668,6 +673,12 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
||||||
}
|
}
|
||||||
|
|
||||||
// param1 ~ param3
|
// 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 ||
|
||||||
|
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 1; i < numOfParams; ++i) {
|
for (int32_t i = 1; i < numOfParams; ++i) {
|
||||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i);
|
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i);
|
||||||
if (QUERY_NODE_VALUE != nodeType(pParamNode)) {
|
if (QUERY_NODE_VALUE != nodeType(pParamNode)) {
|
||||||
|
@ -677,12 +688,11 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
||||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||||
|
|
||||||
pValue->notReserved = true;
|
pValue->notReserved = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) {
|
||||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
"HISTOGRAM function normalized parameter should be 0/1");
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType =
|
pFunc->node.resType =
|
||||||
|
@ -1017,7 +1027,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add database precision as param
|
// add database precision as param
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
|
|
||||||
|
@ -1031,13 +1041,7 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
pFunc->node.resType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
|
||||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
|
||||||
"The parameters of first/last can only be columns");
|
|
||||||
}
|
|
||||||
|
|
||||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,11 +1055,6 @@ static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
||||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||||
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
||||||
if (isPartial) {
|
if (isPartial) {
|
||||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
|
||||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
|
||||||
"The parameters of first/last can only be columns");
|
|
||||||
}
|
|
||||||
|
|
||||||
pFunc->node.resType =
|
pFunc->node.resType =
|
||||||
(SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
(SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||||
} else {
|
} else {
|
||||||
|
@ -1477,7 +1476,7 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add database precision as param
|
// add database precision as param
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
|
|
||||||
|
@ -1497,7 +1496,7 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add database precision as param
|
// add database precision as param
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
|
|
||||||
|
@ -1525,7 +1524,7 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//add database precision as param
|
// add database precision as param
|
||||||
uint8_t dbPrec = pFunc->node.resType.precision;
|
uint8_t dbPrec = pFunc->node.resType.precision;
|
||||||
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
addDbPrecisonParam(&pFunc->pParameterList, dbPrec);
|
||||||
|
|
||||||
|
@ -1543,7 +1542,7 @@ static int32_t translateToJson(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BINARY].bytes, .type = TSDB_DATA_TYPE_BINARY};
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_JSON].bytes, .type = TSDB_DATA_TYPE_JSON};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1924,7 +1923,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "interp",
|
.name = "interp",
|
||||||
.type = FUNCTION_TYPE_INTERP,
|
.type = FUNCTION_TYPE_INTERP,
|
||||||
.classification = FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC,
|
.classification = FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getSelectivityFuncEnv,
|
.getEnvFunc = getSelectivityFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -1934,7 +1933,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "derivative",
|
.name = "derivative",
|
||||||
.type = FUNCTION_TYPE_DERIVATIVE,
|
.type = FUNCTION_TYPE_DERIVATIVE,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateDerivative,
|
.translateFunc = translateDerivative,
|
||||||
.getEnvFunc = getDerivativeFuncEnv,
|
.getEnvFunc = getDerivativeFuncEnv,
|
||||||
.initFunc = derivativeFuncSetup,
|
.initFunc = derivativeFuncSetup,
|
||||||
|
@ -1944,7 +1943,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "irate",
|
.name = "irate",
|
||||||
.type = FUNCTION_TYPE_IRATE,
|
.type = FUNCTION_TYPE_IRATE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateIrate,
|
.translateFunc = translateIrate,
|
||||||
.getEnvFunc = getIrateFuncEnv,
|
.getEnvFunc = getIrateFuncEnv,
|
||||||
.initFunc = irateFuncSetup,
|
.initFunc = irateFuncSetup,
|
||||||
|
@ -1954,20 +1953,17 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "last_row",
|
.name = "last_row",
|
||||||
.type = FUNCTION_TYPE_LAST_ROW,
|
.type = FUNCTION_TYPE_LAST_ROW,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
.processFunc = lastFunction,
|
.processFunc = lastRowFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = lastRowFinalize,
|
||||||
.pPartialFunc = "_last_partial",
|
|
||||||
.pMergeFunc = "_last_merge",
|
|
||||||
.combineFunc = lastCombine,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "_cache_last_row",
|
.name = "_cache_last_row",
|
||||||
.type = FUNCTION_TYPE_CACHE_LAST_ROW,
|
.type = FUNCTION_TYPE_CACHE_LAST_ROW,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateLastRow,
|
.translateFunc = translateLastRow,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = minmaxFunctionSetup,
|
.initFunc = minmaxFunctionSetup,
|
||||||
|
@ -1977,7 +1973,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "first",
|
.name = "first",
|
||||||
.type = FUNCTION_TYPE_FIRST,
|
.type = FUNCTION_TYPE_FIRST,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -1990,7 +1986,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "_first_partial",
|
.name = "_first_partial",
|
||||||
.type = FUNCTION_TYPE_FIRST_PARTIAL,
|
.type = FUNCTION_TYPE_FIRST_PARTIAL,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLastPartial,
|
.translateFunc = translateFirstLastPartial,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2001,7 +1997,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "_first_merge",
|
.name = "_first_merge",
|
||||||
.type = FUNCTION_TYPE_FIRST_MERGE,
|
.type = FUNCTION_TYPE_FIRST_MERGE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLastMerge,
|
.translateFunc = translateFirstLastMerge,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2012,7 +2008,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "last",
|
.name = "last",
|
||||||
.type = FUNCTION_TYPE_LAST,
|
.type = FUNCTION_TYPE_LAST,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2025,7 +2021,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "_last_partial",
|
.name = "_last_partial",
|
||||||
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLastPartial,
|
.translateFunc = translateFirstLastPartial,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2036,7 +2032,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "_last_merge",
|
.name = "_last_merge",
|
||||||
.type = FUNCTION_TYPE_LAST_MERGE,
|
.type = FUNCTION_TYPE_LAST_MERGE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateFirstLastMerge,
|
.translateFunc = translateFirstLastMerge,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2047,7 +2043,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "twa",
|
.name = "twa",
|
||||||
.type = FUNCTION_TYPE_TWA,
|
.type = FUNCTION_TYPE_TWA,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_INTERVAL_INTERPO_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateInNumOutDou,
|
.translateFunc = translateInNumOutDou,
|
||||||
.dataRequiredFunc = statisDataRequired,
|
.dataRequiredFunc = statisDataRequired,
|
||||||
.getEnvFunc = getTwaFuncEnv,
|
.getEnvFunc = getTwaFuncEnv,
|
||||||
|
@ -2144,7 +2140,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "statecount",
|
.name = "statecount",
|
||||||
.type = FUNCTION_TYPE_STATE_COUNT,
|
.type = FUNCTION_TYPE_STATE_COUNT,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC,
|
||||||
.translateFunc = translateStateCount,
|
.translateFunc = translateStateCount,
|
||||||
.getEnvFunc = getStateFuncEnv,
|
.getEnvFunc = getStateFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2154,7 +2150,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "stateduration",
|
.name = "stateduration",
|
||||||
.type = FUNCTION_TYPE_STATE_DURATION,
|
.type = FUNCTION_TYPE_STATE_DURATION,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC,
|
||||||
.translateFunc = translateStateDuration,
|
.translateFunc = translateStateDuration,
|
||||||
.getEnvFunc = getStateFuncEnv,
|
.getEnvFunc = getStateFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -2194,7 +2190,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "tail",
|
.name = "tail",
|
||||||
.type = FUNCTION_TYPE_TAIL,
|
.type = FUNCTION_TYPE_TAIL,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC,
|
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC |
|
||||||
|
FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateTail,
|
.translateFunc = translateTail,
|
||||||
.getEnvFunc = getTailFuncEnv,
|
.getEnvFunc = getTailFuncEnv,
|
||||||
.initFunc = tailFunctionSetup,
|
.initFunc = tailFunctionSetup,
|
||||||
|
@ -2205,7 +2202,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.name = "unique",
|
.name = "unique",
|
||||||
.type = FUNCTION_TYPE_UNIQUE,
|
.type = FUNCTION_TYPE_UNIQUE,
|
||||||
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC |
|
.classification = FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC |
|
||||||
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC,
|
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_WINDOW_FUNC | FUNC_MGT_FORBID_GROUP_BY_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||||
.translateFunc = translateUnique,
|
.translateFunc = translateUnique,
|
||||||
.getEnvFunc = getUniqueFuncEnv,
|
.getEnvFunc = getUniqueFuncEnv,
|
||||||
.initFunc = uniqueFunctionSetup,
|
.initFunc = uniqueFunctionSetup,
|
||||||
|
@ -2623,7 +2620,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "_group_key",
|
.name = "_group_key",
|
||||||
.type = FUNCTION_TYPE_GROUP_KEY,
|
.type = FUNCTION_TYPE_GROUP_KEY,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC,
|
||||||
.translateFunc = translateGroupKey,
|
.translateFunc = translateGroupKey,
|
||||||
.getEnvFunc = getGroupKeyFuncEnv,
|
.getEnvFunc = getGroupKeyFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "builtinsimpl.h"
|
#include "builtinsimpl.h"
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "query.h"
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "taggfunction.h"
|
#include "taggfunction.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
@ -80,6 +81,7 @@ typedef struct STopBotRes {
|
||||||
|
|
||||||
typedef struct SFirstLastRes {
|
typedef struct SFirstLastRes {
|
||||||
bool hasResult;
|
bool hasResult;
|
||||||
|
bool isNull; // used for last_row function only
|
||||||
int32_t bytes;
|
int32_t bytes;
|
||||||
char buf[];
|
char buf[];
|
||||||
} SFirstLastRes;
|
} SFirstLastRes;
|
||||||
|
@ -208,13 +210,13 @@ typedef struct SMavgInfo {
|
||||||
} SMavgInfo;
|
} SMavgInfo;
|
||||||
|
|
||||||
typedef struct SSampleInfo {
|
typedef struct SSampleInfo {
|
||||||
int32_t samples;
|
int32_t samples;
|
||||||
int32_t totalPoints;
|
int32_t totalPoints;
|
||||||
int32_t numSampled;
|
int32_t numSampled;
|
||||||
uint8_t colType;
|
uint8_t colType;
|
||||||
int16_t colBytes;
|
int16_t colBytes;
|
||||||
char* data;
|
char* data;
|
||||||
STuplePos* tuplePos;
|
STuplePos* tuplePos;
|
||||||
} SSampleInfo;
|
} SSampleInfo;
|
||||||
|
|
||||||
typedef struct STailItem {
|
typedef struct STailItem {
|
||||||
|
@ -269,20 +271,19 @@ typedef struct SDerivInfo {
|
||||||
} SDerivInfo;
|
} SDerivInfo;
|
||||||
|
|
||||||
typedef struct SRateInfo {
|
typedef struct SRateInfo {
|
||||||
double firstValue;
|
double firstValue;
|
||||||
TSKEY firstKey;
|
TSKEY firstKey;
|
||||||
double lastValue;
|
double lastValue;
|
||||||
TSKEY lastKey;
|
TSKEY lastKey;
|
||||||
int8_t hasResult; // flag to denote has value
|
int8_t hasResult; // flag to denote has value
|
||||||
} SRateInfo;
|
} SRateInfo;
|
||||||
|
|
||||||
typedef struct SGroupKeyInfo{
|
typedef struct SGroupKeyInfo {
|
||||||
bool hasResult;
|
bool hasResult;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
char data[];
|
char data[];
|
||||||
} SGroupKeyInfo;
|
} SGroupKeyInfo;
|
||||||
|
|
||||||
|
|
||||||
#define SET_VAL(_info, numOfElem, res) \
|
#define SET_VAL(_info, numOfElem, res) \
|
||||||
do { \
|
do { \
|
||||||
if ((numOfElem) <= 0) { \
|
if ((numOfElem) <= 0) { \
|
||||||
|
@ -1471,8 +1472,8 @@ void setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuple
|
||||||
int32_t pageId = pTuplePos->pageId;
|
int32_t pageId = pTuplePos->pageId;
|
||||||
int32_t offset = pTuplePos->offset;
|
int32_t offset = pTuplePos->offset;
|
||||||
|
|
||||||
if (pTuplePos->pageId != -1) {
|
if (pTuplePos->pageId != -1 && pCtx->subsidiaries.num > 0) {
|
||||||
int32_t numOfCols = taosArrayGetSize(pCtx->pSrcBlock->pDataBlock);
|
int32_t numOfCols = pCtx->subsidiaries.num;
|
||||||
SFilePage* pPage = getBufPage(pCtx->pBuf, pageId);
|
SFilePage* pPage = getBufPage(pCtx->pBuf, pageId);
|
||||||
|
|
||||||
bool* nullList = (bool*)((char*)pPage + offset);
|
bool* nullList = (bool*)((char*)pPage + offset);
|
||||||
|
@ -1483,22 +1484,21 @@ void setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuple
|
||||||
SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j];
|
SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j];
|
||||||
|
|
||||||
SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
|
SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
|
||||||
int32_t srcSlotId = pFuncParam->pCol->slotId;
|
|
||||||
int32_t dstSlotId = pc->pExpr->base.resSchema.slotId;
|
int32_t dstSlotId = pc->pExpr->base.resSchema.slotId;
|
||||||
|
|
||||||
int32_t ps = 0;
|
int32_t ps = 0;
|
||||||
for (int32_t k = 0; k < srcSlotId; ++k) {
|
|
||||||
SColumnInfoData* pSrcCol = taosArrayGet(pCtx->pSrcBlock->pDataBlock, k);
|
|
||||||
ps += pSrcCol->info.bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
SColumnInfoData* pDstCol = taosArrayGet(pBlock->pDataBlock, dstSlotId);
|
SColumnInfoData* pDstCol = taosArrayGet(pBlock->pDataBlock, dstSlotId);
|
||||||
if (nullList[srcSlotId]) {
|
ASSERT(pc->pExpr->base.resSchema.bytes == pDstCol->info.bytes);
|
||||||
|
if (nullList[j]) {
|
||||||
colDataAppendNULL(pDstCol, rowIndex);
|
colDataAppendNULL(pDstCol, rowIndex);
|
||||||
} else {
|
} else {
|
||||||
colDataAppend(pDstCol, rowIndex, (pStart + ps), false);
|
colDataAppend(pDstCol, rowIndex, pStart, false);
|
||||||
}
|
}
|
||||||
|
pStart += pDstCol->info.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
releaseBufPage(pCtx->pBuf, pPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2409,7 +2409,9 @@ int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getFirstLastInfoSize(int32_t resBytes) { return sizeof(SFirstLastRes) + resBytes + sizeof(int64_t) + sizeof(STuplePos); }
|
int32_t getFirstLastInfoSize(int32_t resBytes) {
|
||||||
|
return sizeof(SFirstLastRes) + resBytes + sizeof(int64_t) + sizeof(STuplePos);
|
||||||
|
}
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
@ -2491,7 +2493,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
memcpy(pInfo->buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
if (!pInfo->hasResult) {
|
if (!pInfo->hasResult) {
|
||||||
|
@ -2501,7 +2503,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pInfo->hasResult = true;
|
pInfo->hasResult = true;
|
||||||
//DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2533,7 +2535,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
memcpy(pInfo->buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
if (!pInfo->hasResult) {
|
if (!pInfo->hasResult) {
|
||||||
|
@ -2543,7 +2545,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pInfo->hasResult = true;
|
pInfo->hasResult = true;
|
||||||
//DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2597,7 +2599,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
memcpy(pInfo->buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
if (!pInfo->hasResult) {
|
if (!pInfo->hasResult) {
|
||||||
|
@ -2607,7 +2609,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pInfo->hasResult = true;
|
pInfo->hasResult = true;
|
||||||
//DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2629,7 +2631,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
memcpy(pInfo->buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
if (!pInfo->hasResult) {
|
if (!pInfo->hasResult) {
|
||||||
|
@ -2640,7 +2642,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
pInfo->hasResult = true;
|
pInfo->hasResult = true;
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
//DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2652,7 +2654,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
|
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
|
||||||
SInputColumnInfoData* pColInfo = &pCtx->input;
|
SInputColumnInfoData* pColInfo = &pCtx->input;
|
||||||
int32_t start = pColInfo->startRowIndex;
|
int32_t start = pColInfo->startRowIndex;
|
||||||
|
|
||||||
pOutput->bytes = pInput->bytes;
|
pOutput->bytes = pInput->bytes;
|
||||||
TSKEY* tsIn = (TSKEY*)(pInput->buf + pInput->bytes);
|
TSKEY* tsIn = (TSKEY*)(pInput->buf + pInput->bytes);
|
||||||
|
@ -2670,7 +2672,7 @@ static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, S
|
||||||
}
|
}
|
||||||
*tsOut = *tsIn;
|
*tsOut = *tsIn;
|
||||||
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
|
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pOutput->buf + pOutput->bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pOutput->buf + pOutput->bytes + sizeof(TSKEY));
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
if (!pOutput->hasResult) {
|
if (!pOutput->hasResult) {
|
||||||
|
@ -2717,7 +2719,7 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
|
||||||
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
colDataAppend(pCol, pBlock->info.rows, pRes->buf, pResInfo->isNullRes);
|
colDataAppend(pCol, pBlock->info.rows, pRes->buf, pResInfo->isNullRes);
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY));
|
||||||
setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows);
|
setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows);
|
||||||
|
|
||||||
|
@ -2728,8 +2730,8 @@ int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||||
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||||
|
|
||||||
int32_t resultBytes = getFirstLastInfoSize(pRes->bytes);
|
int32_t resultBytes = getFirstLastInfoSize(pRes->bytes);
|
||||||
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||||
|
|
||||||
memcpy(varDataVal(res), pRes, resultBytes);
|
memcpy(varDataVal(res), pRes, resultBytes);
|
||||||
varDataSetLen(res, resultBytes);
|
varDataSetLen(res, resultBytes);
|
||||||
|
@ -2738,7 +2740,7 @@ int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
|
||||||
colDataAppend(pCol, pBlock->info.rows, res, false);
|
colDataAppend(pCol, pBlock->info.rows, res, false);
|
||||||
//handle selectivity
|
// handle selectivity
|
||||||
STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY));
|
STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY));
|
||||||
setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows);
|
setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows);
|
||||||
|
|
||||||
|
@ -2763,6 +2765,111 @@ int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t lastRowFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
int32_t numOfElems = 0;
|
||||||
|
|
||||||
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
SFirstLastRes* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
|
int32_t type = pInputCol->info.type;
|
||||||
|
int32_t bytes = pInputCol->info.bytes;
|
||||||
|
pInfo->bytes = bytes;
|
||||||
|
|
||||||
|
SColumnDataAgg* pColAgg = (pInput->colDataAggIsSet) ? pInput->pColumnDataAgg[0] : NULL;
|
||||||
|
|
||||||
|
TSKEY startKey = getRowPTs(pInput->pPTS, 0);
|
||||||
|
TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1);
|
||||||
|
|
||||||
|
int32_t blockDataOrder = (startKey <= endKey) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
|
||||||
|
|
||||||
|
if (blockDataOrder == TSDB_ORDER_ASC) {
|
||||||
|
for (int32_t i = pInput->numOfRows + pInput->startRowIndex - 1; i >= pInput->startRowIndex; --i) {
|
||||||
|
char* data = colDataGetData(pInputCol, i);
|
||||||
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf) < cts) {
|
||||||
|
if (pInputCol->hasNull && colDataIsNull(pInputCol, pInput->totalRows, i, pColAgg)) {
|
||||||
|
pInfo->isNull = true;
|
||||||
|
} else {
|
||||||
|
pInfo->isNull = false;
|
||||||
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
|
bytes = varDataTLen(data);
|
||||||
|
pInfo->bytes = bytes;
|
||||||
|
}
|
||||||
|
memcpy(pInfo->buf + sizeof(TSKEY), data, bytes);
|
||||||
|
}
|
||||||
|
*(TSKEY*)(pInfo->buf) = cts;
|
||||||
|
numOfElems++;
|
||||||
|
// handle selectivity
|
||||||
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
|
if (!pInfo->hasResult) {
|
||||||
|
saveTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos);
|
||||||
|
} else {
|
||||||
|
copyTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pInfo->hasResult = true;
|
||||||
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
|
pResInfo->numOfRes = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else { // descending order
|
||||||
|
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) {
|
||||||
|
char* data = colDataGetData(pInputCol, i);
|
||||||
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf) < cts) {
|
||||||
|
if (pInputCol->hasNull && colDataIsNull(pInputCol, pInput->totalRows, i, pColAgg)) {
|
||||||
|
pInfo->isNull = true;
|
||||||
|
} else {
|
||||||
|
pInfo->isNull = false;
|
||||||
|
if (IS_VAR_DATA_TYPE(type)) {
|
||||||
|
bytes = varDataTLen(data);
|
||||||
|
pInfo->bytes = bytes;
|
||||||
|
}
|
||||||
|
memcpy(pInfo->buf + sizeof(TSKEY), data, bytes);
|
||||||
|
}
|
||||||
|
*(TSKEY*)(pInfo->buf) = cts;
|
||||||
|
numOfElems++;
|
||||||
|
// handle selectivity
|
||||||
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
|
STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY));
|
||||||
|
if (!pInfo->hasResult) {
|
||||||
|
saveTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos);
|
||||||
|
} else {
|
||||||
|
copyTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pInfo->hasResult = true;
|
||||||
|
pResInfo->numOfRes = 1;
|
||||||
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_VAL(pResInfo, numOfElems, 1);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t lastRowFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||||
|
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
|
||||||
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
|
||||||
|
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
colDataAppend(pCol, pBlock->info.rows, pRes->buf + sizeof(TSKEY), pRes->isNull);
|
||||||
|
// handle selectivity
|
||||||
|
STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY));
|
||||||
|
setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows);
|
||||||
|
|
||||||
|
return pResInfo->numOfRes;
|
||||||
|
}
|
||||||
|
|
||||||
bool getDiffFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
bool getDiffFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||||
pEnv->calcMemSize = sizeof(SDiffInfo);
|
pEnv->calcMemSize = sizeof(SDiffInfo);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2776,7 +2883,11 @@ bool diffFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
||||||
SDiffInfo* pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SDiffInfo* pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
pDiffInfo->hasPrev = false;
|
pDiffInfo->hasPrev = false;
|
||||||
pDiffInfo->prev.i64 = 0;
|
pDiffInfo->prev.i64 = 0;
|
||||||
pDiffInfo->ignoreNegative = pCtx->param[1].param.i; // TODO set correct param
|
if (pCtx->numOfParams > 1) {
|
||||||
|
pDiffInfo->ignoreNegative = pCtx->param[1].param.i; // TODO set correct param
|
||||||
|
} else {
|
||||||
|
pDiffInfo->ignoreNegative = false;
|
||||||
|
}
|
||||||
pDiffInfo->includeNull = false;
|
pDiffInfo->includeNull = false;
|
||||||
pDiffInfo->firstOutput = false;
|
pDiffInfo->firstOutput = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -2891,10 +3002,8 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
|
||||||
|
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
|
||||||
int32_t startOffset = pCtx->offset;
|
int32_t startOffset = pCtx->offset;
|
||||||
|
|
||||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||||
|
@ -2906,9 +3015,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||||
if (pDiffInfo->includeNull) {
|
if (pDiffInfo->includeNull) {
|
||||||
colDataSetNull_f(pOutput->nullbitmap, pos);
|
colDataSetNull_f(pOutput->nullbitmap, pos);
|
||||||
if (tsList != NULL) {
|
|
||||||
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
numOfElems += 1;
|
numOfElems += 1;
|
||||||
}
|
}
|
||||||
|
@ -2919,9 +3025,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
if (pDiffInfo->hasPrev) {
|
if (pDiffInfo->hasPrev) {
|
||||||
doHandleDiff(pDiffInfo, pInputCol->info.type, pv, pOutput, pos, pCtx->order);
|
doHandleDiff(pDiffInfo, pInputCol->info.type, pv, pOutput, pos, pCtx->order);
|
||||||
if (pTsOutput != NULL) {
|
|
||||||
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
numOfElems++;
|
numOfElems++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2937,9 +3040,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||||
if (pDiffInfo->includeNull) {
|
if (pDiffInfo->includeNull) {
|
||||||
colDataSetNull_f(pOutput->nullbitmap, pos);
|
colDataSetNull_f(pOutput->nullbitmap, pos);
|
||||||
if (tsList != NULL) {
|
|
||||||
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
numOfElems += 1;
|
numOfElems += 1;
|
||||||
}
|
}
|
||||||
|
@ -2951,9 +3051,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
// there is a row of previous data block to be handled in the first place.
|
// there is a row of previous data block to be handled in the first place.
|
||||||
if (pDiffInfo->hasPrev) {
|
if (pDiffInfo->hasPrev) {
|
||||||
doHandleDiff(pDiffInfo, pInputCol->info.type, pv, pOutput, pos, pCtx->order);
|
doHandleDiff(pDiffInfo, pInputCol->info.type, pv, pOutput, pos, pCtx->order);
|
||||||
if (pTsOutput != NULL) {
|
|
||||||
colDataAppendInt64(pTsOutput, pos, &pDiffInfo->prevTs);
|
|
||||||
}
|
|
||||||
|
|
||||||
numOfElems++;
|
numOfElems++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2961,9 +3058,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pDiffInfo->hasPrev = true;
|
pDiffInfo->hasPrev = true;
|
||||||
if (pTsOutput != NULL) {
|
|
||||||
pDiffInfo->prevTs = tsList[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3100,7 +3194,10 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
saveTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
|
saveTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_saveTuple i:%d, item:%p,pageId:%d, offset:%d\n", pEntryInfo->numOfRes, pItem, pItem->tuplePos.pageId,
|
||||||
|
pItem->tuplePos.offset);
|
||||||
|
#endif
|
||||||
// allocate the buffer and keep the data of this row into the new allocated buffer
|
// allocate the buffer and keep the data of this row into the new allocated buffer
|
||||||
pEntryInfo->numOfRes++;
|
pEntryInfo->numOfRes++;
|
||||||
taosheapsort((void*)pItems, sizeof(STopBotResItem), pEntryInfo->numOfRes, (const void*)&type, topBotResComparFn,
|
taosheapsort((void*)pItems, sizeof(STopBotResItem), pEntryInfo->numOfRes, (const void*)&type, topBotResComparFn,
|
||||||
|
@ -3121,7 +3218,9 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData
|
||||||
if (pCtx->subsidiaries.num > 0) {
|
if (pCtx->subsidiaries.num > 0) {
|
||||||
copyTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
|
copyTupleData(pCtx, rowIndex, pSrcBlock, &pItem->tuplePos);
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_copyTuple pageId:%d, offset:%d", pItem->tuplePos.pageId, pItem->tuplePos.offset);
|
||||||
|
#endif
|
||||||
taosheapadjust((void*)pItems, sizeof(STopBotResItem), 0, pEntryInfo->numOfRes - 1, (const void*)&type,
|
taosheapadjust((void*)pItems, sizeof(STopBotResItem), 0, pEntryInfo->numOfRes - 1, (const void*)&type,
|
||||||
topBotResComparFn, NULL, !isTopQuery);
|
topBotResComparFn, NULL, !isTopQuery);
|
||||||
}
|
}
|
||||||
|
@ -3131,7 +3230,11 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData
|
||||||
void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
|
void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
|
||||||
SFilePage* pPage = NULL;
|
SFilePage* pPage = NULL;
|
||||||
|
|
||||||
int32_t completeRowSize = pSrcBlock->info.rowSize + (int32_t) taosArrayGetSize(pSrcBlock->pDataBlock) * sizeof(bool);
|
int32_t completeRowSize = pCtx->subsidiaries.num * sizeof(bool);
|
||||||
|
for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) {
|
||||||
|
SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j];
|
||||||
|
completeRowSize += pc->pExpr->base.resSchema.bytes;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCtx->curBufPage == -1) {
|
if (pCtx->curBufPage == -1) {
|
||||||
pPage = getNewBufPage(pCtx->pBuf, 0, &pCtx->curBufPage);
|
pPage = getNewBufPage(pCtx->pBuf, 0, &pCtx->curBufPage);
|
||||||
|
@ -3149,19 +3252,22 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
|
||||||
// keep the current row data, extract method
|
// keep the current row data, extract method
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
bool* nullList = (bool*)((char*)pPage + pPage->num);
|
bool* nullList = (bool*)((char*)pPage + pPage->num);
|
||||||
char* pStart = (char*)(nullList + sizeof(bool) * (int32_t) taosArrayGetSize(pSrcBlock->pDataBlock));
|
char* pStart = (char*)(nullList + sizeof(bool) * pCtx->subsidiaries.num);
|
||||||
for (int32_t i = 0; i < (int32_t) taosArrayGetSize(pSrcBlock->pDataBlock); ++i) {
|
for (int32_t i = 0; i < pCtx->subsidiaries.num; ++i) {
|
||||||
SColumnInfoData* pCol = taosArrayGet(pSrcBlock->pDataBlock, i);
|
SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[i];
|
||||||
bool isNull = colDataIsNull_s(pCol, rowIndex);
|
|
||||||
if (isNull) {
|
SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
|
||||||
nullList[i] = true;
|
int32_t srcSlotId = pFuncParam->pCol->slotId;
|
||||||
|
|
||||||
|
SColumnInfoData* pCol = taosArrayGet(pSrcBlock->pDataBlock, srcSlotId);
|
||||||
|
if ((nullList[i] = colDataIsNull_s(pCol, rowIndex)) == true) {
|
||||||
offset += pCol->info.bytes;
|
offset += pCol->info.bytes;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* p = colDataGetData(pCol, rowIndex);
|
char* p = colDataGetData(pCol, rowIndex);
|
||||||
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
||||||
memcpy(pStart + offset, p, varDataTLen(p));
|
memcpy(pStart + offset, p, (pCol->info.type == TSDB_DATA_TYPE_JSON) ? getJsonValueLen(p) : varDataTLen(p));
|
||||||
} else {
|
} else {
|
||||||
memcpy(pStart + offset, p, pCol->info.bytes);
|
memcpy(pStart + offset, p, pCol->info.bytes);
|
||||||
}
|
}
|
||||||
|
@ -3179,14 +3285,18 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
|
||||||
void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
|
void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) {
|
||||||
SFilePage* pPage = getBufPage(pCtx->pBuf, pPos->pageId);
|
SFilePage* pPage = getBufPage(pCtx->pBuf, pPos->pageId);
|
||||||
|
|
||||||
int32_t numOfCols = taosArrayGetSize(pSrcBlock->pDataBlock);
|
int32_t numOfCols = pCtx->subsidiaries.num;
|
||||||
|
|
||||||
bool* nullList = (bool*)((char*)pPage + pPos->offset);
|
bool* nullList = (bool*)((char*)pPage + pPos->offset);
|
||||||
char* pStart = (char*)(nullList + numOfCols * sizeof(bool));
|
char* pStart = (char*)(nullList + numOfCols * sizeof(bool));
|
||||||
|
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SColumnInfoData* pCol = taosArrayGet(pSrcBlock->pDataBlock, i);
|
SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[i];
|
||||||
|
SFunctParam* pFuncParam = &pc->pExpr->base.pParam[0];
|
||||||
|
int32_t srcSlotId = pFuncParam->pCol->slotId;
|
||||||
|
|
||||||
|
SColumnInfoData* pCol = taosArrayGet(pSrcBlock->pDataBlock, srcSlotId);
|
||||||
if ((nullList[i] = colDataIsNull_s(pCol, rowIndex)) == true) {
|
if ((nullList[i] = colDataIsNull_s(pCol, rowIndex)) == true) {
|
||||||
offset += pCol->info.bytes;
|
offset += pCol->info.bytes;
|
||||||
continue;
|
continue;
|
||||||
|
@ -3194,7 +3304,7 @@ void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
|
||||||
|
|
||||||
char* p = colDataGetData(pCol, rowIndex);
|
char* p = colDataGetData(pCol, rowIndex);
|
||||||
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
||||||
memcpy(pStart + offset, p, varDataTLen(p));
|
memcpy(pStart + offset, p, (pCol->info.type == TSDB_DATA_TYPE_JSON) ? getJsonValueLen(p) : varDataTLen(p));
|
||||||
} else {
|
} else {
|
||||||
memcpy(pStart + offset, p, pCol->info.bytes);
|
memcpy(pStart + offset, p, pCol->info.bytes);
|
||||||
}
|
}
|
||||||
|
@ -3208,7 +3318,7 @@ void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
|
||||||
|
|
||||||
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||||
STopBotRes* pRes = GET_ROWCELL_INTERBUF(pEntryInfo);
|
STopBotRes* pRes = getTopBotOutputInfo(pCtx);
|
||||||
|
|
||||||
int16_t type = pCtx->input.pData[0]->info.type;
|
int16_t type = pCtx->input.pData[0]->info.type;
|
||||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||||
|
@ -3225,7 +3335,10 @@ int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
} else {
|
} else {
|
||||||
colDataAppend(pCol, currentRow, (const char*)&pItem->v.i, false);
|
colDataAppend(pCol, currentRow, (const char*)&pItem->v.i, false);
|
||||||
}
|
}
|
||||||
|
#ifdef BUF_PAGE_DEBUG
|
||||||
|
qDebug("page_finalize i:%d,item:%p,pageId:%d, offset:%d\n", i, pItem, pItem->tuplePos.pageId,
|
||||||
|
pItem->tuplePos.offset);
|
||||||
|
#endif
|
||||||
setSelectivityValue(pCtx, pBlock, &pRes->pItems[i].tuplePos, currentRow);
|
setSelectivityValue(pCtx, pBlock, &pRes->pItems[i].tuplePos, currentRow);
|
||||||
currentRow += 1;
|
currentRow += 1;
|
||||||
}
|
}
|
||||||
|
@ -3464,7 +3577,7 @@ bool elapsedFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo
|
||||||
pInfo->min = MAX_TS_KEY;
|
pInfo->min = MAX_TS_KEY;
|
||||||
pInfo->max = 0;
|
pInfo->max = 0;
|
||||||
|
|
||||||
if (pCtx->numOfParams > 2) {
|
if (pCtx->numOfParams > 1) {
|
||||||
pInfo->timeUnit = pCtx->param[1].param.i;
|
pInfo->timeUnit = pCtx->param[1].param.i;
|
||||||
} else {
|
} else {
|
||||||
pInfo->timeUnit = 1;
|
pInfo->timeUnit = 1;
|
||||||
|
@ -4405,7 +4518,6 @@ int32_t mavgFunction(SqlFunctionCtx* pCtx) {
|
||||||
SMavgInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SMavgInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
|
||||||
|
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||||
|
@ -4445,10 +4557,6 @@ int32_t mavgFunction(SqlFunctionCtx* pCtx) {
|
||||||
colDataAppend(pOutput, pos, (char*)&result, false);
|
colDataAppend(pOutput, pos, (char*)&result, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this after pTsOutput is handled
|
|
||||||
if (pTsOutput != NULL) {
|
|
||||||
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
|
||||||
}
|
|
||||||
numOfElems++;
|
numOfElems++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4795,11 +4903,11 @@ static void doModeAdd(SModeInfo* pInfo, char* data, bool isNull) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t hashKeyBytes = IS_VAR_DATA_TYPE(pInfo->colType) ? varDataTLen(data) : pInfo->colBytes;
|
int32_t hashKeyBytes = IS_VAR_DATA_TYPE(pInfo->colType) ? varDataTLen(data) : pInfo->colBytes;
|
||||||
SModeItem** pHashItem = taosHashGet(pInfo->pHash, data, hashKeyBytes);
|
SModeItem** pHashItem = taosHashGet(pInfo->pHash, data, hashKeyBytes);
|
||||||
if (pHashItem == NULL) {
|
if (pHashItem == NULL) {
|
||||||
int32_t size = sizeof(SModeItem) + pInfo->colBytes;
|
int32_t size = sizeof(SModeItem) + pInfo->colBytes;
|
||||||
SModeItem* pItem = (SModeItem*)(pInfo->pItems + pInfo->numOfPoints * size);
|
SModeItem* pItem = (SModeItem*)(pInfo->pItems + pInfo->numOfPoints * size);
|
||||||
memcpy(pItem->data, data, pInfo->colBytes);
|
memcpy(pItem->data, data, pInfo->colBytes);
|
||||||
pItem->count += 1;
|
pItem->count += 1;
|
||||||
|
|
||||||
|
@ -4812,7 +4920,7 @@ static void doModeAdd(SModeInfo* pInfo, char* data, bool isNull) {
|
||||||
|
|
||||||
int32_t modeFunction(SqlFunctionCtx* pCtx) {
|
int32_t modeFunction(SqlFunctionCtx* pCtx) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
|
||||||
|
@ -4860,7 +4968,6 @@ int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return pResInfo->numOfRes;
|
return pResInfo->numOfRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
pEnv->calcMemSize = sizeof(STwaInfo);
|
pEnv->calcMemSize = sizeof(STwaInfo);
|
||||||
return true;
|
return true;
|
||||||
|
@ -5112,7 +5219,7 @@ int32_t twaFinalize(struct SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return functionFinalize(pCtx, pBlock);
|
return functionFinalize(pCtx, pBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool blockDistSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
bool blockDistSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||||
if (!functionSetup(pCtx, pResultInfo)) {
|
if (!functionSetup(pCtx, pResultInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5144,7 +5251,7 @@ int32_t blockDistFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
pDistInfo->defMinRows = p1.defMinRows;
|
pDistInfo->defMinRows = p1.defMinRows;
|
||||||
pDistInfo->defMaxRows = p1.defMaxRows;
|
pDistInfo->defMaxRows = p1.defMaxRows;
|
||||||
pDistInfo->rowSize = p1.rowSize;
|
pDistInfo->rowSize = p1.rowSize;
|
||||||
pDistInfo->numOfSmallBlocks = p1.numOfSmallBlocks;
|
pDistInfo->numOfSmallBlocks = p1.numOfSmallBlocks;
|
||||||
|
|
||||||
if (pDistInfo->minRows > p1.minRows) {
|
if (pDistInfo->minRows > p1.minRows) {
|
||||||
|
@ -5230,16 +5337,18 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
int32_t row = 0;
|
int32_t row = 0;
|
||||||
char st[256] = {0};
|
char st[256] = {0};
|
||||||
double totalRawSize = pData->totalRows * pData->rowSize;
|
double totalRawSize = pData->totalRows * pData->rowSize;
|
||||||
int32_t len =
|
int32_t len = sprintf(st + VARSTR_HEADER_SIZE,
|
||||||
sprintf(st + VARSTR_HEADER_SIZE, "Total_Blocks=[%d] Total_Size=[%.2f Kb] Average_size=[%.2f Kb] Compression_Ratio=[%.2f %c]",
|
"Total_Blocks=[%d] Total_Size=[%.2f Kb] Average_size=[%.2f Kb] Compression_Ratio=[%.2f %c]",
|
||||||
pData->numOfBlocks, pData->totalSize / 1024.0, ((double)pData->totalSize) / pData->numOfBlocks,
|
pData->numOfBlocks, pData->totalSize / 1024.0, ((double)pData->totalSize) / pData->numOfBlocks,
|
||||||
pData->totalSize * 100 / totalRawSize, '%');
|
pData->totalSize * 100 / totalRawSize, '%');
|
||||||
|
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
colDataAppend(pColInfo, row++, st, false);
|
colDataAppend(pColInfo, row++, st, false);
|
||||||
|
|
||||||
len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Rows=[%"PRId64"] Inmem_Rows=[%d] MinRows=[%d] MaxRows=[%d] Average_Rows=[%"PRId64"]",
|
len = sprintf(st + VARSTR_HEADER_SIZE,
|
||||||
pData->totalRows, pData->numOfInmemRows, pData->minRows, pData->maxRows, pData->totalRows / pData->numOfBlocks);
|
"Total_Rows=[%" PRId64 "] Inmem_Rows=[%d] MinRows=[%d] MaxRows=[%d] Average_Rows=[%" PRId64 "]",
|
||||||
|
pData->totalRows, pData->numOfInmemRows, pData->minRows, pData->maxRows,
|
||||||
|
pData->totalRows / pData->numOfBlocks);
|
||||||
|
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
colDataAppend(pColInfo, row++, st, false);
|
colDataAppend(pColInfo, row++, st, false);
|
||||||
|
@ -5415,25 +5524,25 @@ bool irateFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
||||||
|
|
||||||
SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
pInfo->firstKey = INT64_MIN;
|
pInfo->firstKey = INT64_MIN;
|
||||||
pInfo->lastKey = INT64_MIN;
|
pInfo->lastKey = INT64_MIN;
|
||||||
pInfo->firstValue = (double)INT64_MIN;
|
pInfo->firstValue = (double)INT64_MIN;
|
||||||
pInfo->lastValue = (double)INT64_MIN;
|
pInfo->lastValue = (double)INT64_MIN;
|
||||||
|
|
||||||
pInfo->hasResult = 0;
|
pInfo->hasResult = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t irateFunction(SqlFunctionCtx* pCtx) {
|
int32_t irateFunction(SqlFunctionCtx* pCtx) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SRateInfo* pRateInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo* pRateInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput;
|
||||||
|
|
||||||
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||||
|
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
int32_t type = pInputCol->info.type;
|
int32_t type = pInputCol->info.type;
|
||||||
|
@ -5445,13 +5554,13 @@ int32_t irateFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
numOfElems++;
|
numOfElems++;
|
||||||
|
|
||||||
char* data = colDataGetData(pInputCol, i);
|
char* data = colDataGetData(pInputCol, i);
|
||||||
double v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, double, type, data);
|
GET_TYPED_DATA(v, double, type, data);
|
||||||
|
|
||||||
if (INT64_MIN == pRateInfo->lastKey) {
|
if (INT64_MIN == pRateInfo->lastKey) {
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = tsList[i];
|
pRateInfo->lastKey = tsList[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5462,7 +5571,7 @@ int32_t irateFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = tsList[i];
|
pRateInfo->lastKey = tsList[i];
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -5471,7 +5580,6 @@ int32_t irateFunction(SqlFunctionCtx* pCtx) {
|
||||||
pRateInfo->firstValue = v;
|
pRateInfo->firstValue = v;
|
||||||
pRateInfo->firstKey = tsList[i];
|
pRateInfo->firstKey = tsList[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_VAL(pResInfo, numOfElems, 1);
|
SET_VAL(pResInfo, numOfElems, 1);
|
||||||
|
@ -5497,7 +5605,7 @@ static double doCalcRate(const SRateInfo* pRateInfo, double tickPerSec) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0;
|
return (duration > 0) ? ((double)diff) / (duration / tickPerSec) : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
@ -5508,7 +5616,7 @@ int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||||
|
|
||||||
SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
double result = doCalcRate(pInfo, (double)TSDB_TICK_PER_SECOND(pCtx->param[1].param.i));
|
double result = doCalcRate(pInfo, (double)TSDB_TICK_PER_SECOND(pCtx->param[1].param.i));
|
||||||
colDataAppend(pCol, pBlock->info.rows, (const char*)&result, pResInfo->isNullRes);
|
colDataAppend(pCol, pBlock->info.rows, (const char*)&result, pResInfo->isNullRes);
|
||||||
|
|
||||||
return pResInfo->numOfRes;
|
return pResInfo->numOfRes;
|
||||||
|
@ -5516,16 +5624,14 @@ int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
|
||||||
int32_t groupKeyFunction(SqlFunctionCtx* pCtx) {
|
int32_t groupKeyFunction(SqlFunctionCtx* pCtx) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SGroupKeyInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SGroupKeyInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
int32_t bytes = pInputCol->info.bytes;
|
|
||||||
|
|
||||||
int32_t startIndex = pInput->startRowIndex;
|
int32_t startIndex = pInput->startRowIndex;
|
||||||
|
|
||||||
//escape rest of data blocks to avoid first entry to be overwritten.
|
// escape rest of data blocks to avoid first entry to be overwritten.
|
||||||
if (pInfo->hasResult) {
|
if (pInfo->hasResult) {
|
||||||
goto _group_key_over;
|
goto _group_key_over;
|
||||||
}
|
}
|
||||||
|
@ -5537,7 +5643,12 @@ int32_t groupKeyFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char* data = colDataGetData(pInputCol, startIndex);
|
char* data = colDataGetData(pInputCol, startIndex);
|
||||||
memcpy(pInfo->data, data, bytes);
|
if (IS_VAR_DATA_TYPE(pInputCol->info.type)) {
|
||||||
|
memcpy(pInfo->data, data,
|
||||||
|
(pInputCol->info.type == TSDB_DATA_TYPE_JSON) ? getJsonValueLen(data) : varDataTLen(data));
|
||||||
|
} else {
|
||||||
|
memcpy(pInfo->data, data, pInputCol->info.bytes);
|
||||||
|
}
|
||||||
pInfo->hasResult = true;
|
pInfo->hasResult = true;
|
||||||
|
|
||||||
_group_key_over:
|
_group_key_over:
|
||||||
|
|
|
@ -181,6 +181,8 @@ bool fmIsForbidGroupByFunc(int32_t funcId) { return isSpecificClassifyFunc(funcI
|
||||||
|
|
||||||
bool fmIsSystemInfoFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SYSTEM_INFO_FUNC); }
|
bool fmIsSystemInfoFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_SYSTEM_INFO_FUNC); }
|
||||||
|
|
||||||
|
bool fmIsImplicitTsFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_IMPLICIT_TS_FUNC); }
|
||||||
|
|
||||||
bool fmIsInterpFunc(int32_t funcId) {
|
bool fmIsInterpFunc(int32_t funcId) {
|
||||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1887,10 +1887,10 @@ static void top_bottom_func_finalizer(SqlFunctionCtx *pCtx) {
|
||||||
// user specify the order of output by sort the result according to timestamp
|
// user specify the order of output by sort the result according to timestamp
|
||||||
if (pCtx->param[1].param.i == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
if (pCtx->param[1].param.i == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
taosSort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
} else /*if (pCtx->param[1].param.i > PRIMARYKEY_TIMESTAMP_COL_ID)*/ {
|
} else /*if (pCtx->param[1].param.i > PRIMARYKEY_TIMESTAMP_COL_ID)*/ {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
taosSort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_TRUE_DATA_TYPE();
|
GET_TRUE_DATA_TYPE();
|
||||||
|
|
|
@ -44,7 +44,7 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx)
|
||||||
offset += (int32_t)(pg->num * pMemBucket->bytes);
|
offset += (int32_t)(pg->num * pMemBucket->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(buffer->data, pMemBucket->pSlots[slotIdx].info.size, pMemBucket->bytes, pMemBucket->comparFn);
|
taosSort(buffer->data, pMemBucket->pSlots[slotIdx].info.size, pMemBucket->bytes, pMemBucket->comparFn);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
|
||||||
#define COPY_SCALAR_FIELD(fldname) \
|
#define COPY_SCALAR_FIELD(fldname) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -164,7 +165,15 @@ static int32_t valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||||
memcpy(pDst->datum.p, pSrc->datum.p, len);
|
memcpy(pDst->datum.p, pSrc->datum.p, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:{
|
||||||
|
int32_t len = getJsonValueLen(pSrc->datum.p);
|
||||||
|
pDst->datum.p = taosMemoryCalloc(1, len);
|
||||||
|
if (NULL == pDst->datum.p) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(pDst->datum.p, pSrc->datum.p, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TSDB_DATA_TYPE_DECIMAL:
|
case TSDB_DATA_TYPE_DECIMAL:
|
||||||
case TSDB_DATA_TYPE_BLOB:
|
case TSDB_DATA_TYPE_BLOB:
|
||||||
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
||||||
|
@ -600,7 +609,7 @@ static int32_t selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
||||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||||
COPY_SCALAR_FIELD(precision);
|
COPY_SCALAR_FIELD(precision);
|
||||||
COPY_SCALAR_FIELD(isEmptyResult);
|
COPY_SCALAR_FIELD(isEmptyResult);
|
||||||
COPY_SCALAR_FIELD(isTimeOrderQuery);
|
COPY_SCALAR_FIELD(isTimeLineResult);
|
||||||
COPY_SCALAR_FIELD(hasAggFuncs);
|
COPY_SCALAR_FIELD(hasAggFuncs);
|
||||||
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "tjson.h"
|
#include "tjson.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
|
||||||
static int32_t nodeToJson(const void* pObj, SJson* pJson);
|
static int32_t nodeToJson(const void* pObj, SJson* pJson);
|
||||||
static int32_t jsonToNode(const SJson* pJson, void* pObj);
|
static int32_t jsonToNode(const SJson* pJson, void* pObj);
|
||||||
|
@ -2629,7 +2630,18 @@ static int32_t datumToJson(const void* pObj, SJson* pJson) {
|
||||||
case TSDB_DATA_TYPE_VARBINARY:
|
case TSDB_DATA_TYPE_VARBINARY:
|
||||||
code = tjsonAddStringToObject(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
code = tjsonAddStringToObject(pJson, jkValueDatum, varDataVal(pNode->datum.p));
|
||||||
break;
|
break;
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:{
|
||||||
|
int32_t len = getJsonValueLen(pNode->datum.p);
|
||||||
|
char* buf = taosMemoryCalloc( len * 2 + 1, sizeof(char));
|
||||||
|
code = taosHexEncode(pNode->datum.p, buf, len);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
code = tjsonAddStringToObject(pJson, jkValueDatum, buf);
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TSDB_DATA_TYPE_DECIMAL:
|
case TSDB_DATA_TYPE_DECIMAL:
|
||||||
case TSDB_DATA_TYPE_BLOB:
|
case TSDB_DATA_TYPE_BLOB:
|
||||||
// todo
|
// todo
|
||||||
|
@ -2752,7 +2764,30 @@ static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:{
|
||||||
|
pNode->datum.p = taosMemoryCalloc(1, pNode->node.resType.bytes);
|
||||||
|
if (NULL == pNode->datum.p) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char* buf = taosMemoryCalloc(1, pNode->node.resType.bytes * 2 + 1);
|
||||||
|
if (NULL == buf) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = tjsonGetStringValue(pJson, jkValueDatum, buf);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = taosHexDecode(buf, pNode->datum.p, pNode->node.resType.bytes);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
taosMemoryFree(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TSDB_DATA_TYPE_DECIMAL:
|
case TSDB_DATA_TYPE_DECIMAL:
|
||||||
case TSDB_DATA_TYPE_BLOB:
|
case TSDB_DATA_TYPE_BLOB:
|
||||||
// todo
|
// todo
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
|
||||||
static SNode* makeNode(ENodeType type, size_t size) {
|
static SNode* makeNode(ENodeType type, size_t size) {
|
||||||
SNode* p = taosMemoryCalloc(1, size);
|
SNode* p = taosMemoryCalloc(1, size);
|
||||||
|
@ -1675,6 +1676,10 @@ void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal) {
|
||||||
pVal->pz[pVal->nLen + VARSTR_HEADER_SIZE] = 0;
|
pVal->pz[pVal->nLen + VARSTR_HEADER_SIZE] = 0;
|
||||||
break;
|
break;
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
pVal->nLen = getJsonValueLen(pNode->datum.p);
|
||||||
|
pVal->pz = taosMemoryMalloc(pVal->nLen);
|
||||||
|
memcpy(pVal->pz, pNode->datum.p, pVal->nLen);
|
||||||
|
break;
|
||||||
case TSDB_DATA_TYPE_DECIMAL:
|
case TSDB_DATA_TYPE_DECIMAL:
|
||||||
case TSDB_DATA_TYPE_BLOB:
|
case TSDB_DATA_TYPE_BLOB:
|
||||||
// todo
|
// todo
|
||||||
|
|
|
@ -62,7 +62,6 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
|
||||||
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
||||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||||
int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, SMsgBuf* pMsgBuf);
|
|
||||||
|
|
||||||
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
||||||
|
|
||||||
|
|
|
@ -717,7 +717,7 @@ SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pPr
|
||||||
select->pProjectionList = pProjectionList;
|
select->pProjectionList = pProjectionList;
|
||||||
select->pFromTable = pTable;
|
select->pFromTable = pTable;
|
||||||
sprintf(select->stmtName, "%p", select);
|
sprintf(select->stmtName, "%p", select);
|
||||||
select->isTimeOrderQuery = true;
|
select->isTimeLineResult = true;
|
||||||
return (SNode*)select;
|
return (SNode*)select;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -790,11 +790,11 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo*
|
||||||
pColIdx[i].schemaColIdx = pColList->boundColumns[i];
|
pColIdx[i].schemaColIdx = pColList->boundColumns[i];
|
||||||
pColIdx[i].boundIdx = i;
|
pColIdx[i].boundIdx = i;
|
||||||
}
|
}
|
||||||
qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
||||||
for (col_id_t i = 0; i < pColList->numOfBound; ++i) {
|
for (col_id_t i = 0; i < pColList->numOfBound; ++i) {
|
||||||
pColIdx[i].finalIdx = i;
|
pColIdx[i].finalIdx = i;
|
||||||
}
|
}
|
||||||
qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pColList->numOfCols > pColList->numOfBound) {
|
if (pColList->numOfCols > pColList->numOfBound) {
|
||||||
|
@ -2232,11 +2232,11 @@ static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SS
|
||||||
pColIdx[i].schemaColIdx = pColList->boundColumns[i];
|
pColIdx[i].schemaColIdx = pColList->boundColumns[i];
|
||||||
pColIdx[i].boundIdx = i;
|
pColIdx[i].boundIdx = i;
|
||||||
}
|
}
|
||||||
qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar);
|
||||||
for (col_id_t i = 0; i < pColList->numOfBound; ++i) {
|
for (col_id_t i = 0; i < pColList->numOfBound; ++i) {
|
||||||
pColIdx[i].finalIdx = i;
|
pColIdx[i].finalIdx = i;
|
||||||
}
|
}
|
||||||
qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pColList->numOfCols > pColList->numOfBound) {
|
if (pColList->numOfCols > pColList->numOfBound) {
|
||||||
|
|
|
@ -295,7 +295,7 @@ void sortRemoveDataBlockDupRowsRaw(STableDataBlocks* dataBuf) {
|
||||||
char* pBlockData = pBlocks->data;
|
char* pBlockData = pBlocks->data;
|
||||||
|
|
||||||
// todo. qsort is unstable, if timestamp is same, should get the last one
|
// todo. qsort is unstable, if timestamp is same, should get the last one
|
||||||
qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
taosSort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
||||||
|
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
int32_t j = 1;
|
int32_t j = 1;
|
||||||
|
@ -365,7 +365,7 @@ int sortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKey
|
||||||
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
|
||||||
// todo. qsort is unstable, if timestamp is same, should get the last one
|
// todo. qsort is unstable, if timestamp is same, should get the last one
|
||||||
qsort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataComparStable);
|
taosSort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataComparStable);
|
||||||
|
|
||||||
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
|
|
|
@ -440,6 +440,10 @@ static bool isTimelineFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isImplicitTsFunc(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsImplicitTsFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
}
|
||||||
|
|
||||||
static bool isScanPseudoColumnFunc(const SNode* pNode) {
|
static bool isScanPseudoColumnFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsScanPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsScanPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
}
|
}
|
||||||
|
@ -479,6 +483,35 @@ static SNodeList* getProjectList(const SNode* pNode) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isTimeLineQuery(SNode* pStmt) {
|
||||||
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
return ((SSelectStmt*)pStmt)->isTimeLineResult;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isPrimaryKeyImpl(SNode* pExpr) {
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
||||||
|
return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId);
|
||||||
|
} else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)pExpr;
|
||||||
|
if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType) {
|
||||||
|
return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0));
|
||||||
|
} else if (FUNCTION_TYPE_WSTARTTS == pFunc->funcType || FUNCTION_TYPE_WENDTS == pFunc->funcType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isPrimaryKey(STempTableNode* pTable, SNode* pExpr) {
|
||||||
|
if (!isTimeLineQuery(pTable->pSubquery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isPrimaryKeyImpl(pExpr);
|
||||||
|
}
|
||||||
|
|
||||||
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, int32_t tagFlag,
|
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, int32_t tagFlag,
|
||||||
SColumnNode* pCol) {
|
SColumnNode* pCol) {
|
||||||
strcpy(pCol->dbName, pTable->table.dbName);
|
strcpy(pCol->dbName, pTable->table.dbName);
|
||||||
|
@ -500,7 +533,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SColumnNode** pColRef) {
|
static void setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SColumnNode** pColRef) {
|
||||||
SColumnNode* pCol = *pColRef;
|
SColumnNode* pCol = *pColRef;
|
||||||
|
|
||||||
// pCol->pProjectRef = (SNode*)pExpr;
|
// pCol->pProjectRef = (SNode*)pExpr;
|
||||||
|
@ -508,15 +541,8 @@ static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SCol
|
||||||
pExpr->pAssociation = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
|
pExpr->pAssociation = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
taosArrayPush(pExpr->pAssociation, &pColRef);
|
taosArrayPush(pExpr->pAssociation, &pColRef);
|
||||||
if (NULL != pTable) {
|
strcpy(pCol->tableAlias, pTable->table.tableAlias);
|
||||||
strcpy(pCol->tableAlias, pTable->tableAlias);
|
pCol->colId = isPrimaryKey(pTable, (SNode*)pExpr) ? PRIMARYKEY_TIMESTAMP_COL_ID : 0;
|
||||||
} else if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
|
||||||
SColumnNode* pProjCol = (SColumnNode*)pExpr;
|
|
||||||
strcpy(pCol->tableAlias, pProjCol->tableAlias);
|
|
||||||
pCol->tableId = pProjCol->tableId;
|
|
||||||
pCol->colId = pProjCol->colId;
|
|
||||||
pCol->colType = pProjCol->colType;
|
|
||||||
}
|
|
||||||
strcpy(pCol->colName, pExpr->aliasName);
|
strcpy(pCol->colName, pExpr->aliasName);
|
||||||
if ('\0' == pCol->node.aliasName[0]) {
|
if ('\0' == pCol->node.aliasName[0]) {
|
||||||
strcpy(pCol->node.aliasName, pCol->colName);
|
strcpy(pCol->node.aliasName, pCol->colName);
|
||||||
|
@ -538,8 +564,9 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
|
||||||
nodesListAppend(pList, (SNode*)pCol);
|
nodesListAppend(pList, (SNode*)pCol);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SNodeList* pProjectList = getProjectList(((STempTableNode*)pTable)->pSubquery);
|
STempTableNode* pTempTable = (STempTableNode*)pTable;
|
||||||
SNode* pNode;
|
SNodeList* pProjectList = getProjectList(pTempTable->pSubquery);
|
||||||
|
SNode* pNode;
|
||||||
FOREACH(pNode, pProjectList) {
|
FOREACH(pNode, pProjectList) {
|
||||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
if (NULL == pCol) {
|
if (NULL == pCol) {
|
||||||
|
@ -547,7 +574,7 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
|
||||||
}
|
}
|
||||||
nodesListAppend(pList, (SNode*)pCol);
|
nodesListAppend(pList, (SNode*)pCol);
|
||||||
SListCell* pCell = nodesListGetCell(pList, LIST_LENGTH(pList) - 1);
|
SListCell* pCell = nodesListGetCell(pList, LIST_LENGTH(pList) - 1);
|
||||||
setColumnInfoByExpr(pTable, (SExprNode*)pNode, (SColumnNode**)&pCell->pNode);
|
setColumnInfoByExpr(pTempTable, (SExprNode*)pNode, (SColumnNode**)&pCell->pNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -557,35 +584,6 @@ static bool isInternalPrimaryKey(const SColumnNode* pCol) {
|
||||||
return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
return PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && 0 == strcmp(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isTimeOrderQuery(SNode* pStmt) {
|
|
||||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
|
||||||
return ((SSelectStmt*)pStmt)->isTimeOrderQuery;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isPrimaryKeyImpl(STempTableNode* pTable, SNode* pExpr) {
|
|
||||||
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
|
||||||
return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId);
|
|
||||||
} else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
|
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)pExpr;
|
|
||||||
if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType) {
|
|
||||||
return isPrimaryKeyImpl(pTable, nodesListGetNode(pFunc->pParameterList, 0));
|
|
||||||
} else if (FUNCTION_TYPE_WSTARTTS == pFunc->funcType || FUNCTION_TYPE_WENDTS == pFunc->funcType) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isPrimaryKey(STempTableNode* pTable, SNode* pExpr) {
|
|
||||||
if (!isTimeOrderQuery(pTable->pSubquery)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isPrimaryKeyImpl(pTable, pExpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, const STableNode* pTable,
|
static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, const STableNode* pTable,
|
||||||
bool* pFound) {
|
bool* pFound) {
|
||||||
SColumnNode* pCol = *pColRef;
|
SColumnNode* pCol = *pColRef;
|
||||||
|
@ -606,18 +604,19 @@ static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SNodeList* pProjectList = getProjectList(((STempTableNode*)pTable)->pSubquery);
|
STempTableNode* pTempTable = (STempTableNode*)pTable;
|
||||||
SNode* pNode;
|
SNodeList* pProjectList = getProjectList(pTempTable->pSubquery);
|
||||||
|
SNode* pNode;
|
||||||
FOREACH(pNode, pProjectList) {
|
FOREACH(pNode, pProjectList) {
|
||||||
SExprNode* pExpr = (SExprNode*)pNode;
|
SExprNode* pExpr = (SExprNode*)pNode;
|
||||||
if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
|
if (0 == strcmp(pCol->colName, pExpr->aliasName)) {
|
||||||
if (*pFound) {
|
if (*pFound) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pCol->colName);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pCol->colName);
|
||||||
}
|
}
|
||||||
setColumnInfoByExpr(pTable, pExpr, pColRef);
|
setColumnInfoByExpr(pTempTable, pExpr, pColRef);
|
||||||
*pFound = true;
|
*pFound = true;
|
||||||
} else if (isPrimaryKey((STempTableNode*)pTable, pNode) && isInternalPrimaryKey(pCol)) {
|
} else if (isPrimaryKey(pTempTable, pNode) && isInternalPrimaryKey(pCol)) {
|
||||||
setColumnInfoByExpr(pTable, pExpr, pColRef);
|
setColumnInfoByExpr(pTempTable, pExpr, pColRef);
|
||||||
*pFound = true;
|
*pFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,12 +783,12 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) {
|
if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) {
|
||||||
// TODO
|
// TODO
|
||||||
//pVal->node.resType = targetDt;
|
// pVal->node.resType = targetDt;
|
||||||
pVal->translate = true;
|
pVal->translate = true;
|
||||||
pVal->isNull = true;
|
pVal->isNull = true;
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
if (pVal->isDuration) {
|
if (pVal->isDuration) {
|
||||||
if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, precision) !=
|
if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, precision) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
|
@ -1259,6 +1258,7 @@ static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
||||||
pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType);
|
pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType);
|
||||||
pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType);
|
pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType);
|
||||||
pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
|
pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
|
||||||
|
pSelect->hasTimeLineFunc = pSelect->hasLastRowFunc ? true : fmIsTimelineFunc(pFunc->funcId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1477,7 +1477,7 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
|
||||||
strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
|
strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
|
||||||
pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
|
pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||||
pCxt->errCode == getFuncInfo(pCxt, pFunc);
|
pCxt->errCode = getFuncInfo(pCxt, pFunc);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||||
*pNode = (SNode*)pFunc;
|
*pNode = (SNode*)pFunc;
|
||||||
|
@ -1633,6 +1633,16 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t checkWindowFuncCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
if (NULL == pSelect->pWindow) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
if (NULL != pSelect->pWindow && !pSelect->hasAggFuncs) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t toVgroupsInfo(SArray* pVgs, SVgroupsInfo** pVgsInfo) {
|
static int32_t toVgroupsInfo(SArray* pVgs, SVgroupsInfo** pVgsInfo) {
|
||||||
size_t vgroupNum = taosArrayGetSize(pVgs);
|
size_t vgroupNum = taosArrayGetSize(pVgs);
|
||||||
*pVgsInfo = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * vgroupNum);
|
*pVgsInfo = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * vgroupNum);
|
||||||
|
@ -2137,7 +2147,7 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
}
|
}
|
||||||
if (NULL != pSelect->pGroupByList) {
|
if (NULL != pSelect->pGroupByList) {
|
||||||
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
||||||
pSelect->isTimeOrderQuery = false;
|
pSelect->isTimeLineResult = false;
|
||||||
return translateExprList(pCxt, pSelect->pGroupByList);
|
return translateExprList(pCxt, pSelect->pGroupByList);
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2471,9 +2481,9 @@ static int32_t createPrimaryKeyCol(STranslateContext* pCxt, SNode** pPrimaryKey)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes rewriteTimelineFuncImpl(SNode* pNode, void* pContext) {
|
static EDealRes appendTsForImplicitTsFuncImpl(SNode* pNode, void* pContext) {
|
||||||
STranslateContext* pCxt = pContext;
|
STranslateContext* pCxt = pContext;
|
||||||
if (isTimelineFunc(pNode)) {
|
if (isImplicitTsFunc(pNode)) {
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||||
SNode* pPrimaryKey = NULL;
|
SNode* pPrimaryKey = NULL;
|
||||||
pCxt->errCode = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
pCxt->errCode = createPrimaryKeyCol(pCxt, &pPrimaryKey);
|
||||||
|
@ -2485,8 +2495,8 @@ static EDealRes rewriteTimelineFuncImpl(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t appendTsForImplicitTsFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, rewriteTimelineFuncImpl, pCxt);
|
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_FROM, appendTsForImplicitTsFuncImpl, pCxt);
|
||||||
return pCxt->errCode;
|
return pCxt->errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2579,6 +2589,9 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkAggColCoexist(pCxt, pSelect);
|
code = checkAggColCoexist(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = checkWindowFuncCoexist(pCxt, pSelect);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkLimit(pCxt, pSelect);
|
code = checkLimit(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
@ -2586,7 +2599,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
code = translateInterp(pCxt, pSelect);
|
code = translateInterp(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteTimelineFunc(pCxt, pSelect);
|
code = appendTsForImplicitTsFunc(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = replaceOrderByAlias(pCxt, pSelect->pProjectionList, pSelect->pOrderByList);
|
code = replaceOrderByAlias(pCxt, pSelect->pProjectionList, pSelect->pOrderByList);
|
||||||
|
@ -3208,7 +3221,7 @@ static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SN
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
|
if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
|
||||||
(TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
|
(TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
|
||||||
code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -3621,8 +3634,8 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm
|
||||||
pReq->numOfColumns = LIST_LENGTH(pStmt->pCols);
|
pReq->numOfColumns = LIST_LENGTH(pStmt->pCols);
|
||||||
pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
|
pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
|
||||||
if (pStmt->pOptions->commentNull == false) {
|
if (pStmt->pOptions->commentNull == false) {
|
||||||
pReq->comment = strdup(pStmt->pOptions->comment);
|
pReq->pComment = strdup(pStmt->pOptions->comment);
|
||||||
if (NULL == pReq->comment) {
|
if (NULL == pReq->pComment) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
pReq->commentLen = strlen(pStmt->pOptions->comment);
|
pReq->commentLen = strlen(pStmt->pOptions->comment);
|
||||||
|
@ -3630,6 +3643,7 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm
|
||||||
pReq->commentLen = -1;
|
pReq->commentLen = -1;
|
||||||
}
|
}
|
||||||
buildRollupFuncs(pStmt->pOptions->pRollupFuncs, &pReq->pFuncs);
|
buildRollupFuncs(pStmt->pOptions->pRollupFuncs, &pReq->pFuncs);
|
||||||
|
pReq->numOfFuncs = taosArrayGetSize(pReq->pFuncs);
|
||||||
|
|
||||||
SName tableName;
|
SName tableName;
|
||||||
tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), pReq->name);
|
tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), pReq->name);
|
||||||
|
|
|
@ -185,19 +185,21 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
case TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG:
|
case TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG:
|
||||||
return "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes";
|
return "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes";
|
||||||
case TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC:
|
case TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC:
|
||||||
return "%s function does not supportted in fill query";
|
return "%s function is not supported in fill query";
|
||||||
case TSDB_CODE_PAR_INVALID_WINDOW_PC:
|
case TSDB_CODE_PAR_INVALID_WINDOW_PC:
|
||||||
return "_WSTARTTS, _WENDTS and _WDURATION can only be used in window query";
|
return "_WSTARTTS, _WENDTS and _WDURATION can only be used in window query";
|
||||||
case TSDB_CODE_PAR_WINDOW_NOT_ALLOWED_FUNC:
|
case TSDB_CODE_PAR_WINDOW_NOT_ALLOWED_FUNC:
|
||||||
return "%s function does not supportted in time window query";
|
return "%s function is not supported in time window query";
|
||||||
case TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC:
|
case TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC:
|
||||||
return "%s function does not supportted in stream query";
|
return "%s function is not supported in stream query";
|
||||||
case TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC:
|
case TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC:
|
||||||
return "%s function does not supportted in group query";
|
return "%s function is not supported in group query";
|
||||||
case TSDB_CODE_PAR_INVALID_TABLE_OPTION:
|
case TSDB_CODE_PAR_INVALID_TABLE_OPTION:
|
||||||
return "Invalid option %s";
|
return "Invalid option %s";
|
||||||
case TSDB_CODE_PAR_INVALID_INTERP_CLAUSE:
|
case TSDB_CODE_PAR_INVALID_INTERP_CLAUSE:
|
||||||
return "Invalid usage of RANGE clause, EVERY clause or FILL clause";
|
return "Invalid usage of RANGE clause, EVERY clause or FILL clause";
|
||||||
|
case TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN:
|
||||||
|
return "No valid function in window query";
|
||||||
case TSDB_CODE_OUT_OF_MEMORY:
|
case TSDB_CODE_OUT_OF_MEMORY:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
default:
|
default:
|
||||||
|
@ -219,6 +221,7 @@ int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) {
|
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) {
|
||||||
|
if(pBuf == NULL) return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
const char* msgFormat1 = "syntax error near \'%s\'";
|
const char* msgFormat1 = "syntax error near \'%s\'";
|
||||||
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
||||||
const char* msgFormat3 = "%s";
|
const char* msgFormat3 = "%s";
|
||||||
|
@ -337,16 +340,16 @@ int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen) {
|
||||||
static bool isValidateTag(char* input) {
|
static bool isValidateTag(char* input) {
|
||||||
if (!input) return false;
|
if (!input) return false;
|
||||||
for (size_t i = 0; i < strlen(input); ++i) {
|
for (size_t i = 0; i < strlen(input); ++i) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (input[i] < 0x20 || input[i] > 0x7E) return false;
|
if (input[i] < 0x20 || input[i] > 0x7E) return false;
|
||||||
#else
|
#else
|
||||||
if (isprint(input[i]) == 0) return false;
|
if (isprint(input[i]) == 0) return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, SMsgBuf* pMsgBuf) {
|
int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf) {
|
||||||
int32_t retCode = TSDB_CODE_SUCCESS;
|
int32_t retCode = TSDB_CODE_SUCCESS;
|
||||||
cJSON* root = NULL;
|
cJSON* root = NULL;
|
||||||
SHashObj* keyHash = NULL;
|
SHashObj* keyHash = NULL;
|
||||||
|
@ -381,7 +384,8 @@ int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, SMs
|
||||||
|
|
||||||
char* jsonKey = item->string;
|
char* jsonKey = item->string;
|
||||||
if (!isValidateTag(jsonKey)) {
|
if (!isValidateTag(jsonKey)) {
|
||||||
fprintf(stdout,"%s(%d) %s %08" PRId64 "\n", __FILE__, __LINE__,__func__,taosGetSelfPthreadId());fflush(stdout);
|
fprintf(stdout, "%s(%d) %s %08" PRId64 "\n", __FILE__, __LINE__, __func__, taosGetSelfPthreadId());
|
||||||
|
fflush(stdout);
|
||||||
retCode = buildSyntaxErrMsg(pMsgBuf, "json key not validate", jsonKey);
|
retCode = buildSyntaxErrMsg(pMsgBuf, "json key not validate", jsonKey);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,7 +372,7 @@ TEST_F(ParserInitialCTest, createStable) {
|
||||||
expect.watermark2 = watermark2;
|
expect.watermark2 = watermark2;
|
||||||
// expect.ttl = ttl;
|
// expect.ttl = ttl;
|
||||||
if (nullptr != pComment) {
|
if (nullptr != pComment) {
|
||||||
expect.comment = strdup(pComment);
|
expect.pComment = strdup(pComment);
|
||||||
expect.commentLen = strlen(pComment);
|
expect.commentLen = strlen(pComment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -443,7 +443,7 @@ TEST_F(ParserInitialCTest, createStable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expect.commentLen > 0) {
|
if (expect.commentLen > 0) {
|
||||||
ASSERT_EQ(std::string(req.comment), std::string(expect.comment));
|
ASSERT_EQ(std::string(req.pComment), std::string(expect.pComment));
|
||||||
}
|
}
|
||||||
if (expect.ast1Len > 0) {
|
if (expect.ast1Len > 0) {
|
||||||
ASSERT_EQ(std::string(req.pAst1), std::string(expect.pAst1));
|
ASSERT_EQ(std::string(req.pAst1), std::string(expect.pAst1));
|
||||||
|
|
|
@ -542,6 +542,7 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
|
||||||
|
|
||||||
pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
|
pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
|
||||||
pIdfRowsFunc->isUniqueFunc = pSelect->hasUniqueFunc;
|
pIdfRowsFunc->isUniqueFunc = pSelect->hasUniqueFunc;
|
||||||
|
pIdfRowsFunc->isTimeLineFunc = pSelect->hasTimeLineFunc;
|
||||||
|
|
||||||
// indefinite rows functions and _select_values functions
|
// indefinite rows functions and _select_values functions
|
||||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
|
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsVectorFunc, &pIdfRowsFunc->pFuncs);
|
||||||
|
@ -727,6 +728,9 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
}
|
}
|
||||||
|
|
||||||
SFillNode* pFillNode = (SFillNode*)(((SIntervalWindowNode*)pSelect->pWindow)->pFill);
|
SFillNode* pFillNode = (SFillNode*)(((SIntervalWindowNode*)pSelect->pWindow)->pFill);
|
||||||
|
if (FILL_MODE_NONE == pFillNode->mode) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SFillLogicNode* pFill = (SFillLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILL);
|
SFillLogicNode* pFill = (SFillLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILL);
|
||||||
if (NULL == pFill) {
|
if (NULL == pFill) {
|
||||||
|
|
|
@ -476,10 +476,16 @@ static int32_t pushDownCondOptPushCondToScan(SOptimizeContext* pCxt, SScanLogicN
|
||||||
return pushDownCondOptAppendCond(&pScan->node.pConditions, pCond);
|
return pushDownCondOptAppendCond(&pScan->node.pConditions, pCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t pushDownCondOptPushCondToProject(SOptimizeContext* pCxt, SProjectLogicNode* pProject, SNode** pCond) {
|
||||||
|
return pushDownCondOptAppendCond(&pProject->node.pConditions, pCond);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPushCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) {
|
static int32_t pushDownCondOptPushCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) {
|
||||||
switch (nodeType(pChild)) {
|
switch (nodeType(pChild)) {
|
||||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||||
return pushDownCondOptPushCondToScan(pCxt, (SScanLogicNode*)pChild, pCond);
|
return pushDownCondOptPushCondToScan(pCxt, (SScanLogicNode*)pChild, pCond);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
|
return pushDownCondOptPushCondToProject(pCxt, (SProjectLogicNode*)pChild, pCond);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -588,7 +594,7 @@ static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* p
|
||||||
|
|
||||||
typedef struct SPartAggCondContext {
|
typedef struct SPartAggCondContext {
|
||||||
SAggLogicNode* pAgg;
|
SAggLogicNode* pAgg;
|
||||||
bool hasAggFunc;
|
bool hasAggFunc;
|
||||||
} SPartAggCondContext;
|
} SPartAggCondContext;
|
||||||
|
|
||||||
static EDealRes partAggCondHasAggFuncImpl(SNode* pNode, void* pContext) {
|
static EDealRes partAggCondHasAggFuncImpl(SNode* pNode, void* pContext) {
|
||||||
|
@ -613,11 +619,11 @@ static int32_t partitionAggCondHasAggFunc(SAggLogicNode* pAgg, SNode* pCond) {
|
||||||
|
|
||||||
static int32_t partitionAggCondConj(SAggLogicNode* pAgg, SNode** ppAggFuncCond, SNode** ppGroupKeyCond) {
|
static int32_t partitionAggCondConj(SAggLogicNode* pAgg, SNode** ppAggFuncCond, SNode** ppGroupKeyCond) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pAgg->node.pConditions;
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pAgg->node.pConditions;
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
SNodeList* pAggFuncConds = NULL;
|
SNodeList* pAggFuncConds = NULL;
|
||||||
SNodeList* pGroupKeyConds = NULL;
|
SNodeList* pGroupKeyConds = NULL;
|
||||||
SNode* pCond = NULL;
|
SNode* pCond = NULL;
|
||||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||||
if (partitionAggCondHasAggFunc(pAgg, pCond)) {
|
if (partitionAggCondHasAggFunc(pAgg, pCond)) {
|
||||||
code = nodesListMakeAppend(&pAggFuncConds, nodesCloneNode(pCond));
|
code = nodesListMakeAppend(&pAggFuncConds, nodesCloneNode(pCond));
|
||||||
|
@ -671,14 +677,14 @@ static int32_t pushCondToAggCond(SOptimizeContext* pCxt, SAggLogicNode* pAgg, SN
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SRewriteAggGroupKeyCondContext{
|
typedef struct SRewriteAggGroupKeyCondContext {
|
||||||
SAggLogicNode *pAgg;
|
SAggLogicNode* pAgg;
|
||||||
int32_t errCode;
|
int32_t errCode;
|
||||||
} SRewriteAggGroupKeyCondContext;
|
} SRewriteAggGroupKeyCondContext;
|
||||||
|
|
||||||
static EDealRes rewriteAggGroupKeyCondForPushDownImpl(SNode** pNode, void* pContext) {
|
static EDealRes rewriteAggGroupKeyCondForPushDownImpl(SNode** pNode, void* pContext) {
|
||||||
SRewriteAggGroupKeyCondContext* pCxt = pContext;
|
SRewriteAggGroupKeyCondContext* pCxt = pContext;
|
||||||
SAggLogicNode* pAgg = pCxt->pAgg;
|
SAggLogicNode* pAgg = pCxt->pAgg;
|
||||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||||
SNode* pGroupKey = NULL;
|
SNode* pGroupKey = NULL;
|
||||||
FOREACH(pGroupKey, pAgg->pGroupKeys) {
|
FOREACH(pGroupKey, pAgg->pGroupKeys) {
|
||||||
|
@ -711,14 +717,15 @@ static int32_t pushDownCondOptDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAg
|
||||||
OPTIMIZE_FLAG_TEST_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
OPTIMIZE_FLAG_TEST_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
//TODO: remove it after full implementation of pushing down to child
|
// TODO: remove it after full implementation of pushing down to child
|
||||||
if (1 != LIST_LENGTH(pAgg->node.pChildren) ||
|
if (1 != LIST_LENGTH(pAgg->node.pChildren) ||
|
||||||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) {
|
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pAgg->node.pChildren, 0)) &&
|
||||||
|
QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* pAggFuncCond = NULL;
|
SNode* pAggFuncCond = NULL;
|
||||||
SNode* pGroupKeyCond = NULL;
|
SNode* pGroupKeyCond = NULL;
|
||||||
int32_t code = partitionAggCond(pAgg, &pAggFuncCond, &pGroupKeyCond);
|
int32_t code = partitionAggCond(pAgg, &pAggFuncCond, &pGroupKeyCond);
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pAggFuncCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pAggFuncCond) {
|
||||||
code = pushCondToAggCond(pCxt, pAgg, &pAggFuncCond);
|
code = pushCondToAggCond(pCxt, pAgg, &pAggFuncCond);
|
||||||
|
@ -1455,9 +1462,17 @@ static int32_t rewriteTailOptCreateSort(SIndefRowsFuncLogicNode* pIndef, SLogicN
|
||||||
TSWAP(pSort->node.pChildren, pIndef->node.pChildren);
|
TSWAP(pSort->node.pChildren, pIndef->node.pChildren);
|
||||||
pSort->node.precision = pIndef->node.precision;
|
pSort->node.precision = pIndef->node.precision;
|
||||||
|
|
||||||
|
SFunctionNode* pTail = NULL;
|
||||||
|
SNode* pFunc = NULL;
|
||||||
|
FOREACH(pFunc, pIndef->pFuncs) {
|
||||||
|
if (FUNCTION_TYPE_TAIL == ((SFunctionNode*)pFunc)->funcType) {
|
||||||
|
pTail = (SFunctionNode*)pFunc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// tail(expr, [limit, offset,] _rowts)
|
// tail(expr, [limit, offset,] _rowts)
|
||||||
SFunctionNode* pTail = (SFunctionNode*)nodesListGetNode(pIndef->pFuncs, 0);
|
int32_t rowtsIndex = LIST_LENGTH(pTail->pParameterList) - 1;
|
||||||
int32_t rowtsIndex = LIST_LENGTH(pTail->pParameterList) - 1;
|
|
||||||
|
|
||||||
int32_t code = nodesListMakeStrictAppend(
|
int32_t code = nodesListMakeStrictAppend(
|
||||||
&pSort->pSortKeys, rewriteTailOptCreateOrderByExpr(nodesListGetNode(pTail->pParameterList, rowtsIndex)));
|
&pSort->pSortKeys, rewriteTailOptCreateOrderByExpr(nodesListGetNode(pTail->pParameterList, rowtsIndex)));
|
||||||
|
@ -1477,12 +1492,12 @@ static int32_t rewriteTailOptCreateSort(SIndefRowsFuncLogicNode* pIndef, SLogicN
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SNode* rewriteTailOptCreateProjectExpr(SFunctionNode* pTail) {
|
static SNode* rewriteTailOptCreateProjectExpr(SFunctionNode* pFunc) {
|
||||||
SNode* pExpr = nodesCloneNode(nodesListGetNode(pTail->pParameterList, 0));
|
SNode* pExpr = nodesCloneNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||||
if (NULL == pExpr) {
|
if (NULL == pExpr) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(((SExprNode*)pExpr)->aliasName, pTail->node.aliasName);
|
strcpy(((SExprNode*)pExpr)->aliasName, pFunc->node.aliasName);
|
||||||
return pExpr;
|
return pExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1495,12 +1510,22 @@ static int32_t rewriteTailOptCreateProject(SIndefRowsFuncLogicNode* pIndef, SLog
|
||||||
TSWAP(pProject->node.pTargets, pIndef->node.pTargets);
|
TSWAP(pProject->node.pTargets, pIndef->node.pTargets);
|
||||||
pProject->node.precision = pIndef->node.precision;
|
pProject->node.precision = pIndef->node.precision;
|
||||||
|
|
||||||
// tail(expr, [limit, offset,] _rowts)
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SFunctionNode* pTail = (SFunctionNode*)nodesListGetNode(pIndef->pFuncs, 0);
|
SFunctionNode* pTail = NULL;
|
||||||
int32_t limitIndex = LIST_LENGTH(pTail->pParameterList) > 2 ? 1 : -1;
|
SNode* pFunc = NULL;
|
||||||
int32_t offsetIndex = LIST_LENGTH(pTail->pParameterList) > 3 ? 2 : -1;
|
FOREACH(pFunc, pIndef->pFuncs) {
|
||||||
|
code = nodesListMakeStrictAppend(&pProject->pProjections, rewriteTailOptCreateProjectExpr((SFunctionNode*)pFunc));
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FUNCTION_TYPE_TAIL == ((SFunctionNode*)pFunc)->funcType) {
|
||||||
|
pTail = (SFunctionNode*)pFunc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t code = nodesListMakeStrictAppend(&pProject->pProjections, rewriteTailOptCreateProjectExpr(pTail));
|
// tail(expr, [limit, offset,] _rowts)
|
||||||
|
int32_t limitIndex = LIST_LENGTH(pTail->pParameterList) > 2 ? 1 : -1;
|
||||||
|
int32_t offsetIndex = LIST_LENGTH(pTail->pParameterList) > 3 ? 2 : -1;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewriteTailOptCreateLimit(limitIndex < 0 ? NULL : nodesListGetNode(pTail->pParameterList, limitIndex),
|
code = rewriteTailOptCreateLimit(limitIndex < 0 ? NULL : nodesListGetNode(pTail->pParameterList, limitIndex),
|
||||||
offsetIndex < 0 ? NULL : nodesListGetNode(pTail->pParameterList, offsetIndex),
|
offsetIndex < 0 ? NULL : nodesListGetNode(pTail->pParameterList, offsetIndex),
|
||||||
|
@ -1855,7 +1880,7 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pSelfNode) {
|
static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pSelfNode) {
|
||||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSelfNode->pChildren, 0);
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSelfNode->pChildren, 0);
|
||||||
|
|
||||||
SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS};
|
SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS};
|
||||||
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt);
|
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt);
|
||||||
|
|
|
@ -35,6 +35,8 @@ TEST_F(PlanBasicTest, whereClause) {
|
||||||
run("SELECT * FROM t1 WHERE c1 > 10");
|
run("SELECT * FROM t1 WHERE c1 > 10");
|
||||||
|
|
||||||
run("SELECT * FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59'");
|
run("SELECT * FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59'");
|
||||||
|
|
||||||
|
run("SELECT ts, c1 FROM t1 WHERE ts > NOW AND ts IS NULL AND (c1 > 0 OR c3 < 20)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PlanBasicTest, func) {
|
TEST_F(PlanBasicTest, func) {
|
||||||
|
@ -103,6 +105,22 @@ TEST_F(PlanBasicTest, lastRowFunc) {
|
||||||
run("SELECT LAST_ROW(c1), SUM(c3) FROM t1");
|
run("SELECT LAST_ROW(c1), SUM(c3) FROM t1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlanBasicTest, timeLineFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT CSUM(c1) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT CSUM(c1) FROM st1");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PlanBasicTest, multiResFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT LAST(*) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT LAST(c1 + 10, c2) FROM st1");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlanBasicTest, sampleFunc) {
|
TEST_F(PlanBasicTest, sampleFunc) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
|
|
@ -305,18 +305,21 @@ int32_t dataConverToStr(char* str, int type, void* buf, int32_t bufSize, int32_t
|
||||||
|
|
||||||
char* parseTagDatatoJson(void* p) {
|
char* parseTagDatatoJson(void* p) {
|
||||||
char* string = NULL;
|
char* string = NULL;
|
||||||
cJSON* json = cJSON_CreateObject();
|
|
||||||
if (json == NULL) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
SArray* pTagVals = NULL;
|
SArray* pTagVals = NULL;
|
||||||
|
cJSON* json = NULL;
|
||||||
if (tTagToValArray((const STag*)p, &pTagVals) != 0) {
|
if (tTagToValArray((const STag*)p, &pTagVals) != 0) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t nCols = taosArrayGetSize(pTagVals);
|
int16_t nCols = taosArrayGetSize(pTagVals);
|
||||||
|
if (nCols == 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
char tagJsonKey[256] = {0};
|
char tagJsonKey[256] = {0};
|
||||||
|
json = cJSON_CreateObject();
|
||||||
|
if (json == NULL) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
for (int j = 0; j < nCols; ++j) {
|
for (int j = 0; j < nCols; ++j) {
|
||||||
STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j);
|
STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j);
|
||||||
// json key encode by binary
|
// json key encode by binary
|
||||||
|
@ -374,6 +377,10 @@ char* parseTagDatatoJson(void* p) {
|
||||||
string = cJSON_PrintUnformatted(json);
|
string = cJSON_PrintUnformatted(json);
|
||||||
end:
|
end:
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
|
taosArrayDestroy(pTagVals);
|
||||||
|
if(string == NULL){
|
||||||
|
string = strdup(TSDB_DATA_NULL_STR_L);
|
||||||
|
}
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,9 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
return 18;
|
return 18;
|
||||||
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_IN_ERROR;
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -215,6 +218,9 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
return 24;
|
return 24;
|
||||||
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_IN_ERROR;
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -2059,7 +2065,7 @@ int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colIdxi > 1) {
|
if (colIdxi > 1) {
|
||||||
qsort(colIdx, colIdxi, sizeof(uint32_t), getComparFunc(TSDB_DATA_TYPE_USMALLINT, 0));
|
taosSort(colIdx, colIdxi, sizeof(uint32_t), getComparFunc(TSDB_DATA_TYPE_USMALLINT, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t l = 0; l < colIdxi; ++l) {
|
for (uint32_t l = 0; l < colIdxi; ++l) {
|
||||||
|
@ -2294,7 +2300,7 @@ int32_t filterMergeGroups(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t *gR
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(gRes, *gResNum, POINTER_BYTES, filterCompareGroupCtx);
|
taosSort(gRes, *gResNum, POINTER_BYTES, filterCompareGroupCtx);
|
||||||
|
|
||||||
int32_t pEnd = 0, cStart = 0, cEnd = 0;
|
int32_t pEnd = 0, cStart = 0, cEnd = 0;
|
||||||
uint32_t pColNum = 0, cColNum = 0;
|
uint32_t pColNum = 0, cColNum = 0;
|
||||||
|
|
|
@ -287,7 +287,7 @@ int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarC
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
if (NULL == pParamList) {
|
if (NULL == pParamList) {
|
||||||
if (ctx->pBlockList) {
|
if (ctx->pBlockList) {
|
||||||
SSDataBlock *pBlock = taosArrayGet(ctx->pBlockList, 0);
|
SSDataBlock *pBlock = taosArrayGetP(ctx->pBlockList, 0);
|
||||||
*rowNum = pBlock->info.rows;
|
*rowNum = pBlock->info.rows;
|
||||||
} else {
|
} else {
|
||||||
*rowNum = 1;
|
*rowNum = 1;
|
||||||
|
@ -551,7 +551,9 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
|
||||||
SScalarParam* pLeft = ¶ms[0];
|
SScalarParam* pLeft = ¶ms[0];
|
||||||
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
||||||
|
|
||||||
|
terrno = TSDB_CODE_SUCCESS;
|
||||||
OperatorFn(pLeft, pRight, output, TSDB_ORDER_ASC);
|
OperatorFn(pLeft, pRight, output, TSDB_ORDER_ASC);
|
||||||
|
code = terrno;
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
for (int32_t i = 0; i < paramNum; ++i) {
|
for (int32_t i = 0; i < paramNum; ++i) {
|
||||||
|
@ -693,7 +695,11 @@ EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) {
|
||||||
res->node.resType.scale = output.columnData->info.scale;
|
res->node.resType.scale = output.columnData->info.scale;
|
||||||
res->node.resType.precision = output.columnData->info.precision;
|
res->node.resType.precision = output.columnData->info.precision;
|
||||||
int32_t type = output.columnData->info.type;
|
int32_t type = output.columnData->info.type;
|
||||||
if (IS_VAR_DATA_TYPE(type)) {
|
if (type == TSDB_DATA_TYPE_JSON){
|
||||||
|
int32_t len = getJsonValueLen(output.columnData->pData);
|
||||||
|
res->datum.p = taosMemoryCalloc(len, 1);
|
||||||
|
memcpy(res->datum.p, output.columnData->pData, len);
|
||||||
|
} else if (IS_VAR_DATA_TYPE(type)) {
|
||||||
res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1);
|
res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1);
|
||||||
memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
|
memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1152,42 +1152,30 @@ int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
|
||||||
|
|
||||||
char tmp[TSDB_MAX_JSON_TAG_LEN] = {0};
|
char tmp[TSDB_MAX_JSON_TAG_LEN] = {0};
|
||||||
for (int32_t i = 0; i < pInput[0].numOfRows; ++i) {
|
for (int32_t i = 0; i < pInput[0].numOfRows; ++i) {
|
||||||
if (colDataIsNull_s(pInput[0].columnData, i)) {
|
SArray* pTagVals = taosArrayInit(8, sizeof(STagVal));
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
STag* pTag = NULL;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
char *input = pInput[0].columnData->pData + pInput[0].columnData->varmeta.offset[i];
|
|
||||||
|
|
||||||
if(type == TSDB_DATA_TYPE_NCHAR){
|
if (colDataIsNull_s(pInput[0].columnData, i)) {
|
||||||
if (varDataTLen(input) > TSDB_MAX_JSON_TAG_LEN){
|
tTagNew(pTagVals, 1, true, &pTag);
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), tmp);
|
|
||||||
if (len < 0) {
|
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tmp[len] = 0;
|
|
||||||
}else{
|
}else{
|
||||||
|
char *input = pInput[0].columnData->pData + pInput[0].columnData->varmeta.offset[i];
|
||||||
if (varDataLen(input) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE){
|
if (varDataLen(input) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE){
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
taosArrayDestroy(pTagVals);
|
||||||
continue;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||||
tmp[varDataLen(input)] = 0;
|
tmp[varDataLen(input)] = 0;
|
||||||
|
if(parseJsontoTagData(tmp, pTagVals, &pTag, NULL)){
|
||||||
|
tTagNew(pTagVals, 1, true, &pTag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tjsonValidateJson(tmp)){
|
colDataAppend(pOutput->columnData, i, (const char*)pTag, false);
|
||||||
colDataAppendNULL(pOutput->columnData, i);
|
tTagFree(pTag);
|
||||||
continue;
|
taosArrayDestroy(pTagVals);
|
||||||
}
|
|
||||||
|
|
||||||
colDataAppend(pOutput->columnData, i, input, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pOutput->numOfRows = pInput->numOfRows;
|
pOutput->numOfRows = pInput->numOfRows;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,9 @@ int64_t getVectorBigintValue_JSON(void *src, int32_t index){
|
||||||
return 0;
|
return 0;
|
||||||
} else if(*data == TSDB_DATA_TYPE_NCHAR) { // json inner type can not be BINARY
|
} else if(*data == TSDB_DATA_TYPE_NCHAR) { // json inner type can not be BINARY
|
||||||
convertNcharToDouble(data+CHAR_BYTES, &out);
|
convertNcharToDouble(data+CHAR_BYTES, &out);
|
||||||
|
} else if(tTagIsJson(data)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
convertNumberToNumber(data+CHAR_BYTES, &out, *data, TSDB_DATA_TYPE_DOUBLE);
|
convertNumberToNumber(data+CHAR_BYTES, &out, *data, TSDB_DATA_TYPE_DOUBLE);
|
||||||
}
|
}
|
||||||
|
@ -416,6 +419,9 @@ int32_t vectorConvertFromVarData(const SScalarParam* pIn, SScalarParam* pOut, in
|
||||||
else if(*data == TSDB_DATA_TYPE_NCHAR) {
|
else if(*data == TSDB_DATA_TYPE_NCHAR) {
|
||||||
data += CHAR_BYTES;
|
data += CHAR_BYTES;
|
||||||
convertType = TSDB_DATA_TYPE_NCHAR;
|
convertType = TSDB_DATA_TYPE_NCHAR;
|
||||||
|
} else if(tTagIsJson(data)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return terrno;
|
||||||
} else {
|
} else {
|
||||||
convertNumberToNumber(data+CHAR_BYTES, colDataGetNumData(pOut->columnData, i), *data, outType);
|
convertNumberToNumber(data+CHAR_BYTES, colDataGetNumData(pOut->columnData, i), *data, outType);
|
||||||
continue;
|
continue;
|
||||||
|
@ -461,7 +467,10 @@ double getVectorDoubleValue_JSON(void *src, int32_t index){
|
||||||
return out;
|
return out;
|
||||||
} else if(*data == TSDB_DATA_TYPE_NCHAR) { // json inner type can not be BINARY
|
} else if(*data == TSDB_DATA_TYPE_NCHAR) { // json inner type can not be BINARY
|
||||||
convertNcharToDouble(data+CHAR_BYTES, &out);
|
convertNcharToDouble(data+CHAR_BYTES, &out);
|
||||||
} else {
|
} else if(tTagIsJson(data)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return 0;
|
||||||
|
} else{
|
||||||
convertNumberToNumber(data+CHAR_BYTES, &out, *data, TSDB_DATA_TYPE_DOUBLE);
|
convertNumberToNumber(data+CHAR_BYTES, &out, *data, TSDB_DATA_TYPE_DOUBLE);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -493,10 +502,18 @@ bool convertJsonValue(__compar_fn_t *fp, int32_t optr, int8_t typeLeft, int8_t t
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeLeft == TSDB_DATA_TYPE_JSON){
|
if(typeLeft == TSDB_DATA_TYPE_JSON){
|
||||||
|
if(tTagIsJson(*pLeftData)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
typeLeft = **pLeftData;
|
typeLeft = **pLeftData;
|
||||||
(*pLeftData) ++;
|
(*pLeftData) ++;
|
||||||
}
|
}
|
||||||
if(typeRight == TSDB_DATA_TYPE_JSON){
|
if(typeRight == TSDB_DATA_TYPE_JSON){
|
||||||
|
if(tTagIsJson(*pLeftData)){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
typeRight = **pRightData;
|
typeRight = **pRightData;
|
||||||
(*pRightData) ++;
|
(*pRightData) ++;
|
||||||
}
|
}
|
||||||
|
@ -1576,7 +1593,11 @@ void vectorBitOr(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut,
|
||||||
void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr) {
|
void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
__compar_fn_t fp = filterGetCompFunc(GET_PARAM_TYPE(pLeft), optr);
|
__compar_fn_t fp = filterGetCompFunc(GET_PARAM_TYPE(pLeft), optr);
|
||||||
|
if(terrno != TSDB_CODE_SUCCESS){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
|
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
|
||||||
|
|
||||||
|
@ -1709,6 +1730,7 @@ void vectorIsTrue(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut,
|
||||||
STagVal getJsonValue(char *json, char *key, bool *isExist) {
|
STagVal getJsonValue(char *json, char *key, bool *isExist) {
|
||||||
STagVal val = {.pKey = key};
|
STagVal val = {.pKey = key};
|
||||||
if (tTagIsJson((const STag *)json) == false){
|
if (tTagIsJson((const STag *)json) == false){
|
||||||
|
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
|
||||||
if(isExist){
|
if(isExist){
|
||||||
*isExist = false;
|
*isExist = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,8 +276,6 @@ extern SSchedulerMgmt schMgmt;
|
||||||
|
|
||||||
#define SCH_TASK_ID(_task) ((_task) ? (_task)->taskId : -1)
|
#define SCH_TASK_ID(_task) ((_task) ? (_task)->taskId : -1)
|
||||||
#define SCH_TASK_EID(_task) ((_task) ? (_task)->execId : -1)
|
#define SCH_TASK_EID(_task) ((_task) ? (_task)->execId : -1)
|
||||||
#define SCH_SET_TASK_LASTMSG_TYPE(_task, _type) do { if(_task) { atomic_store_32(&(_task)->lastMsgType, _type); } } while (0)
|
|
||||||
#define SCH_GET_TASK_LASTMSG_TYPE(_task) ((_task) ? atomic_load_32(&(_task)->lastMsgType) : -1)
|
|
||||||
|
|
||||||
#define SCH_IS_DATA_SRC_QRY_TASK(task) ((task)->plan->subplanType == SUBPLAN_TYPE_SCAN)
|
#define SCH_IS_DATA_SRC_QRY_TASK(task) ((task)->plan->subplanType == SUBPLAN_TYPE_SCAN)
|
||||||
#define SCH_IS_DATA_SRC_TASK(task) (((task)->plan->subplanType == SUBPLAN_TYPE_SCAN) || ((task)->plan->subplanType == SUBPLAN_TYPE_MODIFY))
|
#define SCH_IS_DATA_SRC_TASK(task) (((task)->plan->subplanType == SUBPLAN_TYPE_SCAN) || ((task)->plan->subplanType == SUBPLAN_TYPE_MODIFY))
|
||||||
|
@ -309,7 +307,10 @@ extern SSchedulerMgmt schMgmt;
|
||||||
#define SCH_IS_NEED_DROP_JOB(_job) (SCH_IS_QUERY_JOB(_job))
|
#define SCH_IS_NEED_DROP_JOB(_job) (SCH_IS_QUERY_JOB(_job))
|
||||||
#define SCH_IS_EXPLAIN_JOB(_job) (EXPLAIN_MODE_ANALYZE == (_job)->attr.explainMode)
|
#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)
|
#define SCH_NETWORK_ERR(_code) ((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL)
|
||||||
#define SCH_SUB_TASK_NETWORK_ERR(_code, _len) (((_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_RPC_BROKEN_LINK) && ((_len) > 0))
|
#define SCH_SUB_TASK_NETWORK_ERR(_code, _len) (SCH_NETWORK_ERR(_code) && ((_len) > 0))
|
||||||
|
#define SCH_NEED_REDIRECT_MSGTYPE(_msgType) ((_msgType) == TDMT_SCH_QUERY || (_msgType) == TDMT_SCH_MERGE_QUERY || (_msgType) == TDMT_SCH_FETCH)
|
||||||
|
#define SCH_NEED_REDIRECT(_msgType, _code, _rspLen) (SCH_NEED_REDIRECT_MSGTYPE(_msgType) && (NEED_SCHEDULER_REDIRECT_ERROR(_code) || SCH_SUB_TASK_NETWORK_ERR(_code, _rspLen)))
|
||||||
|
#define SCH_NEED_RETRY(_msgType, _code) ((SCH_NETWORK_ERR(_code) && SCH_NEED_REDIRECT_MSGTYPE(_msgType)) || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||||
|
|
||||||
#define SCH_IS_LEVEL_UNFINISHED(_level) ((_level)->taskLaunchedNum < (_level)->taskNum)
|
#define SCH_IS_LEVEL_UNFINISHED(_level) ((_level)->taskLaunchedNum < (_level)->taskNum)
|
||||||
#define SCH_GET_CUR_EP(_addr) (&(_addr)->epSet.eps[(_addr)->epSet.inUse])
|
#define SCH_GET_CUR_EP(_addr) (&(_addr)->epSet.eps[(_addr)->epSet.inUse])
|
||||||
|
|
|
@ -825,7 +825,7 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NEED_SCHEDULER_RETRY_ERROR(errCode)) {
|
if (!SCH_NEED_RETRY(pTask->lastMsgType, errCode)) {
|
||||||
*needRetry = false;
|
*needRetry = false;
|
||||||
SCH_TASK_DLOG("task no more retry cause of errCode, errCode:%x - %s", errCode, tstrerror(errCode));
|
SCH_TASK_DLOG("task no more retry cause of errCode, errCode:%x - %s", errCode, tstrerror(errCode));
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
|
|
||||||
int32_t schValidateReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) {
|
int32_t schValidateReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) {
|
||||||
int32_t lastMsgType = SCH_GET_TASK_LASTMSG_TYPE(pTask);
|
int32_t lastMsgType = pTask->lastMsgType;
|
||||||
int32_t taskStatus = SCH_GET_TASK_STATUS(pTask);
|
int32_t taskStatus = SCH_GET_TASK_STATUS(pTask);
|
||||||
int32_t reqMsgType = msgType - 1;
|
int32_t reqMsgType = msgType - 1;
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
|
@ -42,7 +42,7 @@ int32_t schValidateReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgTy
|
||||||
TMSG_INFO(msgType));
|
TMSG_INFO(msgType));
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
//SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
case TDMT_SCH_FETCH_RSP:
|
case TDMT_SCH_FETCH_RSP:
|
||||||
if (lastMsgType != reqMsgType && -1 != lastMsgType) {
|
if (lastMsgType != reqMsgType && -1 != lastMsgType) {
|
||||||
|
@ -57,7 +57,7 @@ int32_t schValidateReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgTy
|
||||||
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
//SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
case TDMT_VND_CREATE_TABLE_RSP:
|
case TDMT_VND_CREATE_TABLE_RSP:
|
||||||
case TDMT_VND_DROP_TABLE_RSP:
|
case TDMT_VND_DROP_TABLE_RSP:
|
||||||
|
@ -82,7 +82,7 @@ int32_t schValidateReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgTy
|
||||||
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
//SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,8 @@ int32_t schHandleCallback(void *param, SDataBuf *pMsg, int32_t rspCode) {
|
||||||
|
|
||||||
SCH_ERR_JRET(schValidateReceivedMsgType(pJob, pTask, msgType));
|
SCH_ERR_JRET(schValidateReceivedMsgType(pJob, pTask, msgType));
|
||||||
|
|
||||||
if (NEED_SCHEDULER_REDIRECT_ERROR(rspCode) || SCH_SUB_TASK_NETWORK_ERR(rspCode, pMsg->len > 0)) {
|
int32_t reqType = IsReq(pMsg) ? pMsg->msgType : (pMsg->msgType - 1);
|
||||||
|
if (SCH_NEED_REDIRECT(reqType, rspCode, pMsg->len)) {
|
||||||
code = schHandleRedirect(pJob, pTask, (SDataBuf *)pMsg, rspCode);
|
code = schHandleRedirect(pJob, pTask, (SDataBuf *)pMsg, rspCode);
|
||||||
goto _return;
|
goto _return;
|
||||||
}
|
}
|
||||||
|
@ -859,6 +860,9 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, SSchTrans *trans, SQuery
|
||||||
addr->nodeId, epSet->eps[epSet->inUse].fqdn, epSet->eps[epSet->inUse].port,
|
addr->nodeId, epSet->eps[epSet->inUse].fqdn, epSet->eps[epSet->inUse].port,
|
||||||
trans->pTrans, trans->pHandle);
|
trans->pTrans, trans->pHandle);
|
||||||
|
|
||||||
|
if (pTask) {
|
||||||
|
pTask->lastMsgType = msgType;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
code = asyncSendMsgToServerExt(trans->pTrans, epSet, &transporterId, pMsgSendInfo, persistHandle, ctx);
|
code = asyncSendMsgToServerExt(trans->pTrans, epSet, &transporterId, pMsgSendInfo, persistHandle, ctx);
|
||||||
|
@ -1102,8 +1106,6 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_SET_TASK_LASTMSG_TYPE(pTask, msgType);
|
|
||||||
|
|
||||||
SSchTrans trans = {.pTrans = pJob->conn.pTrans, .pHandle = SCH_GET_TASK_HANDLE(pTask)};
|
SSchTrans trans = {.pTrans = pJob->conn.pTrans, .pHandle = SCH_GET_TASK_HANDLE(pTask)};
|
||||||
SCH_ERR_JRET(schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle,
|
SCH_ERR_JRET(schAsyncSendMsg(pJob, pTask, &trans, addr, msgType, msg, msgSize, persistHandle,
|
||||||
(rpcCtx.args ? &rpcCtx : NULL)));
|
(rpcCtx.args ? &rpcCtx : NULL)));
|
||||||
|
@ -1116,7 +1118,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
pTask->lastMsgType = -1;
|
||||||
schFreeRpcCtx(&rpcCtx);
|
schFreeRpcCtx(&rpcCtx);
|
||||||
|
|
||||||
taosMemoryFreeClear(msg);
|
taosMemoryFreeClear(msg);
|
||||||
|
|
|
@ -88,3 +88,12 @@ SStreamDataSubmit* streamSubmitRefClone(SStreamDataSubmit* pSubmit) {
|
||||||
memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit));
|
memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit));
|
||||||
return pSubmitClone;
|
return pSubmitClone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) {
|
||||||
|
int32_t ref = atomic_sub_fetch_32(pDataSubmit->dataRef, 1);
|
||||||
|
ASSERT(ref >= 0);
|
||||||
|
if (ref == 0) {
|
||||||
|
taosMemoryFree(pDataSubmit->data);
|
||||||
|
taosMemoryFree(pDataSubmit->dataRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -63,7 +63,6 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do we need free memory?
|
|
||||||
SSDataBlock block = {0};
|
SSDataBlock block = {0};
|
||||||
assignOneDataBlock(&block, output);
|
assignOneDataBlock(&block, output);
|
||||||
block.info.childId = pTask->selfChildId;
|
block.info.childId = pTask->selfChildId;
|
||||||
|
|
|
@ -41,12 +41,3 @@ void streamQueueClose(SStreamQueue* queue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) {
|
|
||||||
int32_t ref = atomic_sub_fetch_32(pDataSubmit->dataRef, 1);
|
|
||||||
ASSERT(ref >= 0);
|
|
||||||
if (ref == 0) {
|
|
||||||
taosMemoryFree(pDataSubmit->data);
|
|
||||||
taosMemoryFree(pDataSubmit->dataRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ extern "C" {
|
||||||
//
|
//
|
||||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
||||||
int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg);
|
||||||
|
int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatch* pMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,12 @@ extern "C" {
|
||||||
//
|
//
|
||||||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
||||||
int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
||||||
|
int32_t syncNodeOnAppendEntriesReplySnapshot2Cb(SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
||||||
|
|
||||||
|
typedef struct SReaderParam {
|
||||||
|
SyncIndex start;
|
||||||
|
SyncIndex end;
|
||||||
|
} SReaderParam;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ typedef struct SSyncNode {
|
||||||
char path[TSDB_FILENAME_LEN];
|
char path[TSDB_FILENAME_LEN];
|
||||||
char raftStorePath[TSDB_FILENAME_LEN * 2];
|
char raftStorePath[TSDB_FILENAME_LEN * 2];
|
||||||
char configPath[TSDB_FILENAME_LEN * 2];
|
char configPath[TSDB_FILENAME_LEN * 2];
|
||||||
|
int32_t batchSize;
|
||||||
|
|
||||||
// sync io
|
// sync io
|
||||||
SWal* pWal;
|
SWal* pWal;
|
||||||
|
@ -170,6 +171,7 @@ void syncNodeStart(SSyncNode* pSyncNode);
|
||||||
void syncNodeStartStandBy(SSyncNode* pSyncNode);
|
void syncNodeStartStandBy(SSyncNode* pSyncNode);
|
||||||
void syncNodeClose(SSyncNode* pSyncNode);
|
void syncNodeClose(SSyncNode* pSyncNode);
|
||||||
int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak);
|
int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak);
|
||||||
|
int32_t syncNodeProposeBatch(SSyncNode* pSyncNode, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize);
|
||||||
|
|
||||||
// option
|
// option
|
||||||
bool syncNodeSnapshotEnable(SSyncNode* pSyncNode);
|
bool syncNodeSnapshotEnable(SSyncNode* pSyncNode);
|
||||||
|
|
|
@ -53,8 +53,10 @@ extern "C" {
|
||||||
//
|
//
|
||||||
int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode);
|
int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode);
|
||||||
int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode);
|
int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode);
|
||||||
|
int32_t syncNodeAppendEntriesPeersSnapshot2(SSyncNode* pSyncNode);
|
||||||
int32_t syncNodeReplicate(SSyncNode* pSyncNode);
|
int32_t syncNodeReplicate(SSyncNode* pSyncNode);
|
||||||
int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntries* pMsg);
|
int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntries* pMsg);
|
||||||
|
int32_t syncNodeAppendEntriesBatch(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntriesBatch* pMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@ typedef struct SSyncSnapshotSender {
|
||||||
SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex);
|
SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex);
|
||||||
void snapshotSenderDestroy(SSyncSnapshotSender *pSender);
|
void snapshotSenderDestroy(SSyncSnapshotSender *pSender);
|
||||||
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender);
|
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender);
|
||||||
void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader);
|
int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader);
|
||||||
void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish);
|
int32_t snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish);
|
||||||
int32_t snapshotSend(SSyncSnapshotSender *pSender);
|
int32_t snapshotSend(SSyncSnapshotSender *pSender);
|
||||||
int32_t snapshotReSend(SSyncSnapshotSender *pSender);
|
int32_t snapshotReSend(SSyncSnapshotSender *pSender);
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ typedef struct SSyncSnapshotReceiver {
|
||||||
|
|
||||||
SSyncSnapshotReceiver *snapshotReceiverCreate(SSyncNode *pSyncNode, SRaftId fromId);
|
SSyncSnapshotReceiver *snapshotReceiverCreate(SSyncNode *pSyncNode, SRaftId fromId);
|
||||||
void snapshotReceiverDestroy(SSyncSnapshotReceiver *pReceiver);
|
void snapshotReceiverDestroy(SSyncSnapshotReceiver *pReceiver);
|
||||||
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg);
|
int32_t snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg);
|
||||||
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver);
|
int32_t snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver);
|
||||||
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver);
|
bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver);
|
||||||
|
|
||||||
cJSON *snapshotReceiver2Json(SSyncSnapshotReceiver *pReceiver);
|
cJSON *snapshotReceiver2Json(SSyncSnapshotReceiver *pReceiver);
|
||||||
char *snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver);
|
char *snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver);
|
||||||
|
|
|
@ -628,6 +628,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int32_t syncNodeMakeLogSame2(SSyncNode* ths, SyncAppendEntriesBatch* pMsg) { return 0; }
|
||||||
|
|
||||||
static int32_t syncNodeMakeLogSame(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
static int32_t syncNodeMakeLogSame(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||||
int32_t code;
|
int32_t code;
|
||||||
|
|
||||||
|
@ -719,6 +721,283 @@ static bool syncNodeOnAppendEntriesLogOK(SSyncNode* pSyncNode, SyncAppendEntries
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatch* pMsg) {
|
||||||
|
int32_t ret = 0;
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
// if already drop replica, do not process
|
||||||
|
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||||
|
syncNodeEventLog(ths, "recv sync-append-entries-batch, maybe replica already dropped");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maybe update term
|
||||||
|
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||||
|
syncNodeUpdateTerm(ths, pMsg->term);
|
||||||
|
}
|
||||||
|
ASSERT(pMsg->term <= ths->pRaftStore->currentTerm);
|
||||||
|
|
||||||
|
// reset elect timer
|
||||||
|
if (pMsg->term == ths->pRaftStore->currentTerm) {
|
||||||
|
ths->leaderCache = pMsg->srcId;
|
||||||
|
syncNodeResetElectTimer(ths);
|
||||||
|
}
|
||||||
|
ASSERT(pMsg->dataLen >= 0);
|
||||||
|
|
||||||
|
// candidate to follower
|
||||||
|
//
|
||||||
|
// operation:
|
||||||
|
// to follower
|
||||||
|
do {
|
||||||
|
bool condition = pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_CANDIDATE;
|
||||||
|
if (condition) {
|
||||||
|
syncNodeEventLog(ths, "recv sync-append-entries-batch, candidate to follower");
|
||||||
|
|
||||||
|
syncNodeBecomeFollower(ths, "from candidate by append entries");
|
||||||
|
// do not reply?
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// fake match2
|
||||||
|
//
|
||||||
|
// condition1:
|
||||||
|
// preIndex <= my commit index
|
||||||
|
//
|
||||||
|
// operation:
|
||||||
|
// if hasAppendEntries && pMsg->prevLogIndex == ths->commitIndex, append entry
|
||||||
|
// match my-commit-index or my-commit-index + 1
|
||||||
|
// no operation on log
|
||||||
|
do {
|
||||||
|
bool condition = (pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) &&
|
||||||
|
(pMsg->prevLogIndex <= ths->commitIndex);
|
||||||
|
if (condition) {
|
||||||
|
do {
|
||||||
|
char logBuf[128];
|
||||||
|
snprintf(logBuf, sizeof(logBuf),
|
||||||
|
"recv sync-append-entries-batch, fake match2, pre-index:%ld, pre-term:%lu, datalen:%d",
|
||||||
|
pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->dataLen);
|
||||||
|
syncNodeEventLog(ths, logBuf);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
SyncIndex matchIndex = ths->commitIndex;
|
||||||
|
bool hasAppendEntries = pMsg->dataLen > 0;
|
||||||
|
if (hasAppendEntries && pMsg->prevLogIndex == ths->commitIndex) {
|
||||||
|
SRpcMsg rpcMsgArr[SYNC_MAX_BATCH_SIZE];
|
||||||
|
memset(rpcMsgArr, 0, sizeof(rpcMsgArr));
|
||||||
|
int32_t retArrSize = 0;
|
||||||
|
syncAppendEntriesBatch2RpcMsgArray(pMsg, rpcMsgArr, SYNC_MAX_BATCH_SIZE, &retArrSize);
|
||||||
|
|
||||||
|
// make log same
|
||||||
|
do {
|
||||||
|
SyncIndex logLastIndex = ths->pLogStore->syncLogLastIndex(ths->pLogStore);
|
||||||
|
bool hasExtraEntries = logLastIndex > pMsg->prevLogIndex;
|
||||||
|
|
||||||
|
if (hasExtraEntries) {
|
||||||
|
// make log same, rollback deleted entries
|
||||||
|
code = syncNodeMakeLogSame2(ths, pMsg);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// append entry batch
|
||||||
|
for (int32_t i = 0; i < retArrSize; ++i) {
|
||||||
|
SSyncRaftEntry* pAppendEntry = syncEntryBuild(1234);
|
||||||
|
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry);
|
||||||
|
if (code != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = syncNodePreCommit(ths, pAppendEntry);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
|
||||||
|
syncEntryDestory(pAppendEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fsync once
|
||||||
|
SSyncLogStoreData* pData = ths->pLogStore->data;
|
||||||
|
SWal* pWal = pData->pWal;
|
||||||
|
walFsync(pWal, true);
|
||||||
|
|
||||||
|
// update match index
|
||||||
|
matchIndex = pMsg->prevLogIndex + retArrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare response msg
|
||||||
|
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId);
|
||||||
|
pReply->srcId = ths->myRaftId;
|
||||||
|
pReply->destId = pMsg->srcId;
|
||||||
|
pReply->term = ths->pRaftStore->currentTerm;
|
||||||
|
pReply->privateTerm = ths->pNewNodeReceiver->privateTerm;
|
||||||
|
pReply->success = true;
|
||||||
|
pReply->matchIndex = matchIndex;
|
||||||
|
|
||||||
|
// send response
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||||
|
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||||
|
syncAppendEntriesReplyDestroy(pReply);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// calculate logOK here, before will coredump, due to fake match
|
||||||
|
// bool logOK = syncNodeOnAppendEntriesLogOK(ths, pMsg);
|
||||||
|
bool logOK = true;
|
||||||
|
|
||||||
|
// not match
|
||||||
|
//
|
||||||
|
// condition1:
|
||||||
|
// term < myTerm
|
||||||
|
//
|
||||||
|
// condition2:
|
||||||
|
// !logOK
|
||||||
|
//
|
||||||
|
// operation:
|
||||||
|
// not match
|
||||||
|
// no operation on log
|
||||||
|
do {
|
||||||
|
bool condition1 = pMsg->term < ths->pRaftStore->currentTerm;
|
||||||
|
bool condition2 =
|
||||||
|
(pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) && !logOK;
|
||||||
|
bool condition = condition1 || condition2;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
char logBuf[128];
|
||||||
|
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries, not match, pre-index:%ld, pre-term:%lu, datalen:%d",
|
||||||
|
pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->dataLen);
|
||||||
|
syncNodeEventLog(ths, logBuf);
|
||||||
|
|
||||||
|
// prepare response msg
|
||||||
|
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId);
|
||||||
|
pReply->srcId = ths->myRaftId;
|
||||||
|
pReply->destId = pMsg->srcId;
|
||||||
|
pReply->term = ths->pRaftStore->currentTerm;
|
||||||
|
pReply->privateTerm = ths->pNewNodeReceiver->privateTerm;
|
||||||
|
pReply->success = false;
|
||||||
|
pReply->matchIndex = SYNC_INDEX_INVALID;
|
||||||
|
|
||||||
|
// send response
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||||
|
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||||
|
syncAppendEntriesReplyDestroy(pReply);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
// really match
|
||||||
|
//
|
||||||
|
// condition:
|
||||||
|
// logOK
|
||||||
|
//
|
||||||
|
// operation:
|
||||||
|
// match
|
||||||
|
// make log same
|
||||||
|
do {
|
||||||
|
bool condition = (pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) && logOK;
|
||||||
|
if (condition) {
|
||||||
|
// has extra entries (> preIndex) in local log
|
||||||
|
SyncIndex myLastIndex = syncNodeGetLastIndex(ths);
|
||||||
|
bool hasExtraEntries = myLastIndex > pMsg->prevLogIndex;
|
||||||
|
|
||||||
|
// has entries in SyncAppendEntries msg
|
||||||
|
bool hasAppendEntries = pMsg->dataLen > 0;
|
||||||
|
|
||||||
|
char logBuf[128];
|
||||||
|
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries, match, pre-index:%ld, pre-term:%lu, datalen:%d",
|
||||||
|
pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->dataLen);
|
||||||
|
syncNodeEventLog(ths, logBuf);
|
||||||
|
|
||||||
|
if (hasExtraEntries) {
|
||||||
|
// make log same, rollback deleted entries
|
||||||
|
// code = syncNodeMakeLogSame(ths, pMsg);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t retArrSize = 0;
|
||||||
|
if (hasAppendEntries) {
|
||||||
|
SRpcMsg rpcMsgArr[SYNC_MAX_BATCH_SIZE];
|
||||||
|
memset(rpcMsgArr, 0, sizeof(rpcMsgArr));
|
||||||
|
syncAppendEntriesBatch2RpcMsgArray(pMsg, rpcMsgArr, SYNC_MAX_BATCH_SIZE, &retArrSize);
|
||||||
|
|
||||||
|
// append entry batch
|
||||||
|
for (int32_t i = 0; i < retArrSize; ++i) {
|
||||||
|
SSyncRaftEntry* pAppendEntry = syncEntryBuild(1234);
|
||||||
|
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry);
|
||||||
|
if (code != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = syncNodePreCommit(ths, pAppendEntry);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
|
||||||
|
syncEntryDestory(pAppendEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fsync once
|
||||||
|
SSyncLogStoreData* pData = ths->pLogStore->data;
|
||||||
|
SWal* pWal = pData->pWal;
|
||||||
|
walFsync(pWal, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare response msg
|
||||||
|
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId);
|
||||||
|
pReply->srcId = ths->myRaftId;
|
||||||
|
pReply->destId = pMsg->srcId;
|
||||||
|
pReply->term = ths->pRaftStore->currentTerm;
|
||||||
|
pReply->privateTerm = ths->pNewNodeReceiver->privateTerm;
|
||||||
|
pReply->success = true;
|
||||||
|
pReply->matchIndex = hasAppendEntries ? pMsg->prevLogIndex + retArrSize : pMsg->prevLogIndex;
|
||||||
|
|
||||||
|
// send response
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||||
|
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||||
|
syncAppendEntriesReplyDestroy(pReply);
|
||||||
|
|
||||||
|
// maybe update commit index, leader notice me
|
||||||
|
if (pMsg->commitIndex > ths->commitIndex) {
|
||||||
|
// has commit entry in local
|
||||||
|
if (pMsg->commitIndex <= ths->pLogStore->syncLogLastIndex(ths->pLogStore)) {
|
||||||
|
// advance commit index to sanpshot first
|
||||||
|
SSnapshot snapshot;
|
||||||
|
ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot);
|
||||||
|
if (snapshot.lastApplyIndex >= 0 && snapshot.lastApplyIndex > ths->commitIndex) {
|
||||||
|
SyncIndex commitBegin = ths->commitIndex;
|
||||||
|
SyncIndex commitEnd = snapshot.lastApplyIndex;
|
||||||
|
ths->commitIndex = snapshot.lastApplyIndex;
|
||||||
|
|
||||||
|
char eventLog[128];
|
||||||
|
snprintf(eventLog, sizeof(eventLog), "commit by snapshot from index:%ld to index:%ld", commitBegin,
|
||||||
|
commitEnd);
|
||||||
|
syncNodeEventLog(ths, eventLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncIndex beginIndex = ths->commitIndex + 1;
|
||||||
|
SyncIndex endIndex = pMsg->commitIndex;
|
||||||
|
|
||||||
|
// update commit index
|
||||||
|
ths->commitIndex = pMsg->commitIndex;
|
||||||
|
|
||||||
|
// call back Wal
|
||||||
|
code = ths->pLogStore->updateCommitIndex(ths->pLogStore, ths->commitIndex);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
|
||||||
|
code = syncNodeCommit(ths, beginIndex, endIndex, ths->state);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
|
@ -108,48 +108,82 @@ int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* p
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
// only start once
|
||||||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
static void syncNodeStartSnapshot(SSyncNode* ths, SyncIndex beginIndex, SyncIndex endIndex, SyncTerm lastApplyTerm,
|
||||||
|
SyncAppendEntriesReply* pMsg) {
|
||||||
|
// get sender
|
||||||
|
SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(ths, &(pMsg->srcId));
|
||||||
|
ASSERT(pSender != NULL);
|
||||||
|
|
||||||
|
SSnapshot snapshot = {
|
||||||
|
.data = NULL, .lastApplyIndex = endIndex, .lastApplyTerm = lastApplyTerm, .lastConfigIndex = SYNC_INDEX_INVALID};
|
||||||
|
|
||||||
|
void* pReader = NULL;
|
||||||
|
SReaderParam readerParam = {.start = beginIndex, .end = endIndex};
|
||||||
|
ths->pFsm->FpSnapshotStartRead(ths->pFsm, &readerParam, &pReader);
|
||||||
|
if (!snapshotSenderIsStart(pSender) && pMsg->privateTerm < pSender->privateTerm) {
|
||||||
|
ASSERT(pReader != NULL);
|
||||||
|
snapshotSenderStart(pSender, snapshot, pReader);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (pReader != NULL) {
|
||||||
|
ths->pFsm->FpSnapshotStopRead(ths->pFsm, pReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeOnAppendEntriesReplySnapshot2Cb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
char logBuf[128] = {0};
|
// if already drop replica, do not process
|
||||||
snprintf(logBuf, sizeof(logBuf), "==syncNodeOnAppendEntriesReplyCb== term:%lu", ths->pRaftStore->currentTerm);
|
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||||
syncAppendEntriesReplyLog2(logBuf, pMsg);
|
syncNodeEventLog(ths, "recv sync-append-entries-reply, maybe replica already dropped");
|
||||||
|
return -1;
|
||||||
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
|
||||||
sTrace("DropStaleResponse, receive term:%" PRIu64 ", current term:%" PRIu64 "", pMsg->term,
|
|
||||||
ths->pRaftStore->currentTerm);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== before pNextIndex", ths->pNextIndex);
|
// drop stale response
|
||||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== before pMatchIndex", ths->pMatchIndex);
|
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
||||||
|
char logBuf[128];
|
||||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries-reply, recv-term:%lu, drop stale response", pMsg->term);
|
||||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
syncNodeEventLog(ths, logBuf);
|
||||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
return -1;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// error term
|
||||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||||
char logBuf[128] = {0};
|
char logBuf[128];
|
||||||
snprintf(logBuf, sizeof(logBuf), "syncNodeOnAppendEntriesReplyCb error term, receive:%lu current:%lu", pMsg->term,
|
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries-reply, error term, recv-term:%lu", pMsg->term);
|
||||||
ths->pRaftStore->currentTerm);
|
syncNodeErrorLog(ths, logBuf);
|
||||||
syncNodeLog2(logBuf, ths);
|
return -1;
|
||||||
sError("%s", logBuf);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pMsg->term == ths->pRaftStore->currentTerm);
|
ASSERT(pMsg->term == ths->pRaftStore->currentTerm);
|
||||||
|
|
||||||
if (pMsg->success) {
|
if (pMsg->success) {
|
||||||
// nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1]
|
SyncIndex newNextIndex = pMsg->matchIndex + 1;
|
||||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), pMsg->matchIndex + 1);
|
SyncIndex newMatchIndex = pMsg->matchIndex;
|
||||||
|
|
||||||
// matchIndex' = [matchIndex EXCEPT ![i][j] = m.mmatchIndex]
|
if (ths->pLogStore->syncLogExist(ths->pLogStore, newNextIndex) &&
|
||||||
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), pMsg->matchIndex);
|
ths->pLogStore->syncLogExist(ths->pLogStore, newNextIndex - 1)) {
|
||||||
|
// nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1]
|
||||||
|
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), newNextIndex);
|
||||||
|
|
||||||
// maybe commit
|
// matchIndex' = [matchIndex EXCEPT ![i][j] = m.mmatchIndex]
|
||||||
syncMaybeAdvanceCommitIndex(ths);
|
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), newMatchIndex);
|
||||||
|
|
||||||
|
// maybe commit
|
||||||
|
if (ths->state == TAOS_SYNC_STATE_LEADER) {
|
||||||
|
syncMaybeAdvanceCommitIndex(ths);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// start snapshot <match+1, old snapshot.end>
|
||||||
|
SSnapshot snapshot;
|
||||||
|
ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot);
|
||||||
|
syncNodeStartSnapshot(ths, newMatchIndex + 1, snapshot.lastApplyIndex, snapshot.lastApplyTerm, pMsg);
|
||||||
|
|
||||||
|
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), snapshot.lastApplyIndex + 1);
|
||||||
|
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), newMatchIndex);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId));
|
SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId));
|
||||||
|
@ -157,18 +191,35 @@ int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* p
|
||||||
// notice! int64, uint64
|
// notice! int64, uint64
|
||||||
if (nextIndex > SYNC_INDEX_BEGIN) {
|
if (nextIndex > SYNC_INDEX_BEGIN) {
|
||||||
--nextIndex;
|
--nextIndex;
|
||||||
|
|
||||||
|
if (ths->pLogStore->syncLogExist(ths->pLogStore, nextIndex) &&
|
||||||
|
ths->pLogStore->syncLogExist(ths->pLogStore, nextIndex - 1)) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
SSyncRaftEntry* pEntry;
|
||||||
|
int32_t code = ths->pLogStore->syncLogGetEntry(ths->pLogStore, nextIndex, &pEntry);
|
||||||
|
ASSERT(code == 0);
|
||||||
|
syncNodeStartSnapshot(ths, SYNC_INDEX_BEGIN, nextIndex, pEntry->term, pMsg);
|
||||||
|
|
||||||
|
// get sender
|
||||||
|
SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(ths, &(pMsg->srcId));
|
||||||
|
ASSERT(pSender != NULL);
|
||||||
|
SyncIndex sentryIndex = pSender->snapshot.lastApplyIndex + 1;
|
||||||
|
|
||||||
|
// update nextIndex to sentryIndex
|
||||||
|
if (nextIndex <= sentryIndex) {
|
||||||
|
nextIndex = sentryIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nextIndex = SYNC_INDEX_BEGIN;
|
nextIndex = SYNC_INDEX_BEGIN;
|
||||||
}
|
}
|
||||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex);
|
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== after pNextIndex", ths->pNextIndex);
|
return 0;
|
||||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== after pMatchIndex", ths->pMatchIndex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
|
@ -50,7 +50,6 @@ static int32_t syncNodeAppendNoop(SSyncNode* ths);
|
||||||
// process message ----
|
// process message ----
|
||||||
int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg);
|
int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg);
|
||||||
int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg);
|
int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg);
|
||||||
int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg, SyncIndex* pRetIndex);
|
|
||||||
|
|
||||||
// life cycle
|
// life cycle
|
||||||
static void syncFreeNode(void* param);
|
static void syncFreeNode(void* param);
|
||||||
|
@ -627,6 +626,94 @@ int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t syncProposeBatch(int64_t rid, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize) {
|
||||||
|
if (arrSize < 0) {
|
||||||
|
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret = 0;
|
||||||
|
SSyncNode* pSyncNode = taosAcquireRef(tsNodeRefId, rid);
|
||||||
|
if (pSyncNode == NULL) {
|
||||||
|
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ASSERT(rid == pSyncNode->rid);
|
||||||
|
ret = syncNodeProposeBatch(pSyncNode, pMsgArr, pIsWeakArr, arrSize);
|
||||||
|
|
||||||
|
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool syncNodeBatchOK(SRpcMsg* pMsgArr, int32_t arrSize) {
|
||||||
|
for (int32_t i = 0; i < arrSize; ++i) {
|
||||||
|
if (pMsgArr[i].msgType == TDMT_SYNC_CONFIG_CHANGE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsgArr[i].msgType == TDMT_SYNC_CONFIG_CHANGE_FINISH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeProposeBatch(SSyncNode* pSyncNode, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize) {
|
||||||
|
if (!syncNodeBatchOK(pMsgArr, arrSize)) {
|
||||||
|
syncNodeErrorLog(pSyncNode, "sync propose batch error");
|
||||||
|
terrno = TSDB_CODE_SYN_BATCH_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arrSize > SYNC_MAX_BATCH_SIZE) {
|
||||||
|
syncNodeErrorLog(pSyncNode, "sync propose match batch error");
|
||||||
|
terrno = TSDB_CODE_SYN_BATCH_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||||
|
syncNodeErrorLog(pSyncNode, "sync propose not leader");
|
||||||
|
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSyncNode->changing) {
|
||||||
|
syncNodeErrorLog(pSyncNode, "sync propose not ready");
|
||||||
|
terrno = TSDB_CODE_SYN_PROPOSE_NOT_READY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRaftMeta raftArr[SYNC_MAX_BATCH_SIZE];
|
||||||
|
for (int i = 0; i < arrSize; ++i) {
|
||||||
|
SRespStub stub;
|
||||||
|
stub.createTime = taosGetTimestampMs();
|
||||||
|
stub.rpcMsg = pMsgArr[i];
|
||||||
|
uint64_t seqNum = syncRespMgrAdd(pSyncNode->pSyncRespMgr, &stub);
|
||||||
|
|
||||||
|
raftArr[i].isWeak = pIsWeakArr[i];
|
||||||
|
raftArr[i].seqNum = seqNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncClientRequestBatch* pSyncMsg = syncClientRequestBatchBuild(pMsgArr, raftArr, arrSize, pSyncNode->vgId);
|
||||||
|
ASSERT(pSyncMsg != NULL);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncClientRequestBatch2RpcMsg(pSyncMsg, &rpcMsg);
|
||||||
|
taosMemoryFree(pSyncMsg); // only free msg body, do not free rpc msg content
|
||||||
|
|
||||||
|
if (pSyncNode->FpEqMsg != NULL && (*pSyncNode->FpEqMsg)(pSyncNode->msgcb, &rpcMsg) == 0) {
|
||||||
|
// enqueue msg ok
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sError("enqueue msg error, FpEqMsg is NULL");
|
||||||
|
terrno = TSDB_CODE_SYN_INTERNAL_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak) {
|
int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak) {
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
@ -2362,6 +2449,49 @@ int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg, SyncI
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeOnClientRequestBatchCb(SSyncNode* ths, SyncClientRequestBatch* pMsg) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
if (ths->state != TAOS_SYNC_STATE_LEADER) {
|
||||||
|
// call FpCommitCb, delete resp mgr
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncIndex index = ths->pLogStore->syncLogWriteIndex(ths->pLogStore);
|
||||||
|
SyncTerm term = ths->pRaftStore->currentTerm;
|
||||||
|
|
||||||
|
int32_t raftMetaArrayLen = sizeof(SRaftMeta) * pMsg->dataCount;
|
||||||
|
int32_t rpcArrayLen = sizeof(SRpcMsg) * pMsg->dataCount;
|
||||||
|
SRaftMeta* raftMetaArr = (SRaftMeta*)(pMsg->data);
|
||||||
|
SRpcMsg* msgArr = (SRpcMsg*)((char*)(pMsg->data) + raftMetaArrayLen);
|
||||||
|
for (int32_t i = 0; i < pMsg->dataCount; ++i) {
|
||||||
|
SSyncRaftEntry* pEntry = syncEntryBuild(msgArr[i].contLen);
|
||||||
|
ASSERT(pEntry != NULL);
|
||||||
|
|
||||||
|
pEntry->originalRpcType = msgArr[i].msgType;
|
||||||
|
pEntry->seqNum = raftMetaArr[i].seqNum;
|
||||||
|
pEntry->isWeak = raftMetaArr[i].isWeak;
|
||||||
|
pEntry->term = term;
|
||||||
|
pEntry->index = index;
|
||||||
|
memcpy(pEntry->data, msgArr[i].pCont, msgArr[i].contLen);
|
||||||
|
ASSERT(msgArr[i].contLen == pEntry->dataLen);
|
||||||
|
|
||||||
|
code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pEntry);
|
||||||
|
if (code != 0) {
|
||||||
|
// del resp mgr, call FpCommitCb
|
||||||
|
ASSERT(0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fsync once
|
||||||
|
SSyncLogStoreData* pData = ths->pLogStore->data;
|
||||||
|
SWal* pWal = pData->pWal;
|
||||||
|
walFsync(pWal, true);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void syncFreeNode(void* param) {
|
static void syncFreeNode(void* param) {
|
||||||
SSyncNode* pNode = param;
|
SSyncNode* pNode = param;
|
||||||
// inner object already free
|
// inner object already free
|
||||||
|
|
|
@ -591,7 +591,7 @@ void syncPingReplySerialize(const SyncPingReply* pMsg, char* buf, uint32_t bufLe
|
||||||
void syncPingReplyDeserialize(const char* buf, uint32_t len, SyncPingReply* pMsg) {
|
void syncPingReplyDeserialize(const char* buf, uint32_t len, SyncPingReply* pMsg) {
|
||||||
memcpy(pMsg, buf, len);
|
memcpy(pMsg, buf, len);
|
||||||
ASSERT(len == pMsg->bytes);
|
ASSERT(len == pMsg->bytes);
|
||||||
ASSERT(pMsg->bytes == sizeof(SyncPing) + pMsg->dataLen);
|
ASSERT(pMsg->bytes == sizeof(SyncPingReply) + pMsg->dataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* syncPingReplySerialize2(const SyncPingReply* pMsg, uint32_t* len) {
|
char* syncPingReplySerialize2(const SyncPingReply* pMsg, uint32_t* len) {
|
||||||
|
@ -956,6 +956,48 @@ void syncClientRequestLog2(char* s, const SyncClientRequest* pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- message process SyncClientRequestBatch----
|
||||||
|
|
||||||
|
// block1:
|
||||||
|
// block2: SRaftMeta array
|
||||||
|
// block3: rpc msg array (with pCont)
|
||||||
|
|
||||||
|
SyncClientRequestBatch* syncClientRequestBatchBuild(SRpcMsg* rpcMsgArr, SRaftMeta* raftArr, int32_t arrSize,
|
||||||
|
int32_t vgId) {
|
||||||
|
ASSERT(rpcMsgArr != NULL);
|
||||||
|
ASSERT(arrSize > 0);
|
||||||
|
|
||||||
|
int32_t dataLen = 0;
|
||||||
|
int32_t raftMetaArrayLen = sizeof(SRaftMeta) * arrSize;
|
||||||
|
int32_t rpcArrayLen = sizeof(SRpcMsg) * arrSize;
|
||||||
|
dataLen += (raftMetaArrayLen + rpcArrayLen);
|
||||||
|
|
||||||
|
uint32_t bytes = sizeof(SyncClientRequestBatch) + dataLen;
|
||||||
|
SyncClientRequestBatch* pMsg = taosMemoryMalloc(bytes);
|
||||||
|
memset(pMsg, 0, bytes);
|
||||||
|
pMsg->bytes = bytes;
|
||||||
|
pMsg->vgId = vgId;
|
||||||
|
pMsg->msgType = TDMT_SYNC_CLIENT_REQUEST_BATCH;
|
||||||
|
pMsg->dataCount = arrSize;
|
||||||
|
pMsg->dataLen = dataLen;
|
||||||
|
|
||||||
|
SRaftMeta* raftMetaArr = (SRaftMeta*)(pMsg->data);
|
||||||
|
SRpcMsg* msgArr = (SRpcMsg*)((char*)(pMsg->data) + raftMetaArrayLen);
|
||||||
|
|
||||||
|
for (int i = 0; i < arrSize; ++i) {
|
||||||
|
// init raftMetaArr
|
||||||
|
raftMetaArr[i].isWeak = raftArr[i].isWeak;
|
||||||
|
raftMetaArr[i].seqNum = raftArr[i].seqNum;
|
||||||
|
|
||||||
|
// init msgArr
|
||||||
|
msgArr[i] = rpcMsgArr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncClientRequestBatch2RpcMsg(const SyncClientRequestBatch* pSyncMsg, SRpcMsg* pRpcMsg) {}
|
||||||
|
|
||||||
// ---- message process SyncRequestVote----
|
// ---- message process SyncRequestVote----
|
||||||
SyncRequestVote* syncRequestVoteBuild(int32_t vgId) {
|
SyncRequestVote* syncRequestVoteBuild(int32_t vgId) {
|
||||||
uint32_t bytes = sizeof(SyncRequestVote);
|
uint32_t bytes = sizeof(SyncRequestVote);
|
||||||
|
@ -1426,6 +1468,279 @@ void syncAppendEntriesLog2(char* s, const SyncAppendEntries* pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- message process SyncAppendEntriesBatch----
|
||||||
|
|
||||||
|
// block1: SOffsetAndContLen
|
||||||
|
// block2: SOffsetAndContLen Array
|
||||||
|
// block3: SRpcMsg Array
|
||||||
|
// block4: SRpcMsg pCont Array
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SRpcMsg* rpcMsgArr, int32_t arrSize, int32_t vgId) {
|
||||||
|
ASSERT(rpcMsgArr != NULL);
|
||||||
|
ASSERT(arrSize > 0);
|
||||||
|
|
||||||
|
int32_t dataLen = 0;
|
||||||
|
int32_t metaArrayLen = sizeof(SOffsetAndContLen) * arrSize; // <offset, contLen>
|
||||||
|
int32_t rpcArrayLen = sizeof(SRpcMsg) * arrSize; // SRpcMsg
|
||||||
|
int32_t contArrayLen = 0;
|
||||||
|
for (int i = 0; i < arrSize; ++i) { // SRpcMsg pCont
|
||||||
|
contArrayLen += rpcMsgArr[i].contLen;
|
||||||
|
}
|
||||||
|
dataLen += (metaArrayLen + rpcArrayLen + contArrayLen);
|
||||||
|
|
||||||
|
uint32_t bytes = sizeof(SyncAppendEntriesBatch) + dataLen;
|
||||||
|
SyncAppendEntriesBatch* pMsg = taosMemoryMalloc(bytes);
|
||||||
|
memset(pMsg, 0, bytes);
|
||||||
|
pMsg->bytes = bytes;
|
||||||
|
pMsg->vgId = vgId;
|
||||||
|
pMsg->msgType = TDMT_SYNC_APPEND_ENTRIES_BATCH;
|
||||||
|
pMsg->dataCount = arrSize;
|
||||||
|
pMsg->dataLen = dataLen;
|
||||||
|
|
||||||
|
SOffsetAndContLen* metaArr = (SOffsetAndContLen*)(pMsg->data);
|
||||||
|
SRpcMsg* msgArr = (SRpcMsg*)((char*)(pMsg->data) + metaArrayLen);
|
||||||
|
char* pData = pMsg->data;
|
||||||
|
|
||||||
|
for (int i = 0; i < arrSize; ++i) {
|
||||||
|
// init <offset, contLen>
|
||||||
|
if (i == 0) {
|
||||||
|
metaArr[i].offset = metaArrayLen + rpcArrayLen;
|
||||||
|
metaArr[i].contLen = rpcMsgArr[i].contLen;
|
||||||
|
} else {
|
||||||
|
metaArr[i].offset = metaArr[i - 1].offset + metaArr[i - 1].contLen;
|
||||||
|
metaArr[i].contLen = rpcMsgArr[i].contLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init msgArr
|
||||||
|
msgArr[i] = rpcMsgArr[i];
|
||||||
|
|
||||||
|
// init data
|
||||||
|
ASSERT(rpcMsgArr[i].contLen == metaArr[i].contLen);
|
||||||
|
memcpy(pData + metaArr[i].offset, rpcMsgArr[i].pCont, rpcMsgArr[i].contLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchDestroy(SyncAppendEntriesBatch* pMsg) {
|
||||||
|
if (pMsg != NULL) {
|
||||||
|
taosMemoryFree(pMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchSerialize(const SyncAppendEntriesBatch* pMsg, char* buf, uint32_t bufLen) {
|
||||||
|
ASSERT(pMsg->bytes <= bufLen);
|
||||||
|
memcpy(buf, pMsg, pMsg->bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchDeserialize(const char* buf, uint32_t len, SyncAppendEntriesBatch* pMsg) {
|
||||||
|
memcpy(pMsg, buf, len);
|
||||||
|
ASSERT(len == pMsg->bytes);
|
||||||
|
ASSERT(pMsg->bytes == sizeof(SyncAppendEntriesBatch) + pMsg->dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* syncAppendEntriesBatchSerialize2(const SyncAppendEntriesBatch* pMsg, uint32_t* len) {
|
||||||
|
char* buf = taosMemoryMalloc(pMsg->bytes);
|
||||||
|
ASSERT(buf != NULL);
|
||||||
|
syncAppendEntriesBatchSerialize(pMsg, buf, pMsg->bytes);
|
||||||
|
if (len != NULL) {
|
||||||
|
*len = pMsg->bytes;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchDeserialize2(const char* buf, uint32_t len) {
|
||||||
|
uint32_t bytes = *((uint32_t*)buf);
|
||||||
|
SyncAppendEntriesBatch* pMsg = taosMemoryMalloc(bytes);
|
||||||
|
ASSERT(pMsg != NULL);
|
||||||
|
syncAppendEntriesBatchDeserialize(buf, len, pMsg);
|
||||||
|
ASSERT(len == pMsg->bytes);
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatch2RpcMsg(const SyncAppendEntriesBatch* pMsg, SRpcMsg* pRpcMsg) {
|
||||||
|
memset(pRpcMsg, 0, sizeof(*pRpcMsg));
|
||||||
|
pRpcMsg->msgType = pMsg->msgType;
|
||||||
|
pRpcMsg->contLen = pMsg->bytes;
|
||||||
|
pRpcMsg->pCont = rpcMallocCont(pRpcMsg->contLen);
|
||||||
|
syncAppendEntriesBatchSerialize(pMsg, pRpcMsg->pCont, pRpcMsg->contLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchFromRpcMsg(const SRpcMsg* pRpcMsg, SyncAppendEntriesBatch* pMsg) {
|
||||||
|
syncAppendEntriesBatchDeserialize(pRpcMsg->pCont, pRpcMsg->contLen, pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch* syncAppendEntriesBatchFromRpcMsg2(const SRpcMsg* pRpcMsg) {
|
||||||
|
SyncAppendEntriesBatch* pMsg = syncAppendEntriesBatchDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen);
|
||||||
|
ASSERT(pMsg != NULL);
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* syncAppendEntriesBatch2Json(const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
char u64buf[128] = {0};
|
||||||
|
cJSON* pRoot = cJSON_CreateObject();
|
||||||
|
|
||||||
|
if (pMsg != NULL) {
|
||||||
|
cJSON_AddNumberToObject(pRoot, "bytes", pMsg->bytes);
|
||||||
|
cJSON_AddNumberToObject(pRoot, "vgId", pMsg->vgId);
|
||||||
|
cJSON_AddNumberToObject(pRoot, "msgType", pMsg->msgType);
|
||||||
|
|
||||||
|
cJSON* pSrcId = cJSON_CreateObject();
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->srcId.addr);
|
||||||
|
cJSON_AddStringToObject(pSrcId, "addr", u64buf);
|
||||||
|
{
|
||||||
|
uint64_t u64 = pMsg->srcId.addr;
|
||||||
|
cJSON* pTmp = pSrcId;
|
||||||
|
char host[128] = {0};
|
||||||
|
uint16_t port;
|
||||||
|
syncUtilU642Addr(u64, host, sizeof(host), &port);
|
||||||
|
cJSON_AddStringToObject(pTmp, "addr_host", host);
|
||||||
|
cJSON_AddNumberToObject(pTmp, "addr_port", port);
|
||||||
|
}
|
||||||
|
cJSON_AddNumberToObject(pSrcId, "vgId", pMsg->srcId.vgId);
|
||||||
|
cJSON_AddItemToObject(pRoot, "srcId", pSrcId);
|
||||||
|
|
||||||
|
cJSON* pDestId = cJSON_CreateObject();
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->destId.addr);
|
||||||
|
cJSON_AddStringToObject(pDestId, "addr", u64buf);
|
||||||
|
{
|
||||||
|
uint64_t u64 = pMsg->destId.addr;
|
||||||
|
cJSON* pTmp = pDestId;
|
||||||
|
char host[128] = {0};
|
||||||
|
uint16_t port;
|
||||||
|
syncUtilU642Addr(u64, host, sizeof(host), &port);
|
||||||
|
cJSON_AddStringToObject(pTmp, "addr_host", host);
|
||||||
|
cJSON_AddNumberToObject(pTmp, "addr_port", port);
|
||||||
|
}
|
||||||
|
cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId);
|
||||||
|
cJSON_AddItemToObject(pRoot, "destId", pDestId);
|
||||||
|
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term);
|
||||||
|
cJSON_AddStringToObject(pRoot, "term", u64buf);
|
||||||
|
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%ld", pMsg->prevLogIndex);
|
||||||
|
cJSON_AddStringToObject(pRoot, "prevLogIndex", u64buf);
|
||||||
|
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->prevLogTerm);
|
||||||
|
cJSON_AddStringToObject(pRoot, "prevLogTerm", u64buf);
|
||||||
|
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%ld", pMsg->commitIndex);
|
||||||
|
cJSON_AddStringToObject(pRoot, "commitIndex", u64buf);
|
||||||
|
|
||||||
|
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->privateTerm);
|
||||||
|
cJSON_AddStringToObject(pRoot, "privateTerm", u64buf);
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(pRoot, "dataCount", pMsg->dataCount);
|
||||||
|
cJSON_AddNumberToObject(pRoot, "dataLen", pMsg->dataLen);
|
||||||
|
|
||||||
|
int32_t metaArrayLen = sizeof(SOffsetAndContLen) * pMsg->dataCount; // <offset, contLen>
|
||||||
|
int32_t rpcArrayLen = sizeof(SRpcMsg) * pMsg->dataCount; // SRpcMsg
|
||||||
|
int32_t contArrayLen = pMsg->dataLen - metaArrayLen - rpcArrayLen;
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(pRoot, "metaArrayLen", metaArrayLen);
|
||||||
|
cJSON_AddNumberToObject(pRoot, "rpcArrayLen", rpcArrayLen);
|
||||||
|
cJSON_AddNumberToObject(pRoot, "contArrayLen", contArrayLen);
|
||||||
|
|
||||||
|
SOffsetAndContLen* metaArr = (SOffsetAndContLen*)(pMsg->data);
|
||||||
|
SRpcMsg* msgArr = (SRpcMsg*)(pMsg->data + metaArrayLen);
|
||||||
|
void* pData = (void*)(pMsg->data + metaArrayLen + rpcArrayLen);
|
||||||
|
|
||||||
|
cJSON* pMetaArr = cJSON_CreateArray();
|
||||||
|
cJSON_AddItemToObject(pRoot, "metaArr", pMetaArr);
|
||||||
|
for (int i = 0; i < pMsg->dataCount; ++i) {
|
||||||
|
cJSON* pMeta = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(pMeta, "offset", metaArr[i].offset);
|
||||||
|
cJSON_AddNumberToObject(pMeta, "contLen", metaArr[i].contLen);
|
||||||
|
cJSON_AddItemToArray(pMetaArr, pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* pMsgArr = cJSON_CreateArray();
|
||||||
|
cJSON_AddItemToObject(pRoot, "msgArr", pMsgArr);
|
||||||
|
for (int i = 0; i < pMsg->dataCount; ++i) {
|
||||||
|
cJSON* pRpcMsgJson = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(pRpcMsgJson, "code", msgArr[i].code);
|
||||||
|
cJSON_AddNumberToObject(pRpcMsgJson, "contLen", msgArr[i].contLen);
|
||||||
|
cJSON_AddNumberToObject(pRpcMsgJson, "msgType", msgArr[i].msgType);
|
||||||
|
cJSON_AddItemToArray(pMsgArr, pRpcMsgJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* s;
|
||||||
|
s = syncUtilprintBin((char*)(pMsg->data), pMsg->dataLen);
|
||||||
|
cJSON_AddStringToObject(pRoot, "data", s);
|
||||||
|
taosMemoryFree(s);
|
||||||
|
s = syncUtilprintBin2((char*)(pMsg->data), pMsg->dataLen);
|
||||||
|
cJSON_AddStringToObject(pRoot, "data2", s);
|
||||||
|
taosMemoryFree(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* pJson = cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject(pJson, "SyncAppendEntriesBatch", pRoot);
|
||||||
|
return pJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* syncAppendEntriesBatch2Str(const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
cJSON* pJson = syncAppendEntriesBatch2Json(pMsg);
|
||||||
|
char* serialized = cJSON_Print(pJson);
|
||||||
|
cJSON_Delete(pJson);
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatch2RpcMsgArray(SyncAppendEntriesBatch* pSyncMsg, SRpcMsg* rpcMsgArr, int32_t maxArrSize,
|
||||||
|
int32_t* pRetArrSize) {
|
||||||
|
if (pRetArrSize != NULL) {
|
||||||
|
*pRetArrSize = pSyncMsg->dataCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t arrSize = pSyncMsg->dataCount;
|
||||||
|
if (arrSize > maxArrSize) {
|
||||||
|
arrSize = maxArrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t metaArrayLen = sizeof(SOffsetAndContLen) * pSyncMsg->dataCount; // <offset, contLen>
|
||||||
|
int32_t rpcArrayLen = sizeof(SRpcMsg) * pSyncMsg->dataCount; // SRpcMsg
|
||||||
|
int32_t contArrayLen = pSyncMsg->dataLen - metaArrayLen - rpcArrayLen;
|
||||||
|
|
||||||
|
SOffsetAndContLen* metaArr = (SOffsetAndContLen*)(pSyncMsg->data);
|
||||||
|
SRpcMsg* msgArr = (SRpcMsg*)(pSyncMsg->data + metaArrayLen);
|
||||||
|
void* pData = pSyncMsg->data + metaArrayLen + rpcArrayLen;
|
||||||
|
|
||||||
|
for (int i = 0; i < arrSize; ++i) {
|
||||||
|
rpcMsgArr[i] = msgArr[i];
|
||||||
|
rpcMsgArr[i].pCont = rpcMallocCont(msgArr[i].contLen);
|
||||||
|
void* pRpcCont = pSyncMsg->data + metaArr[i].offset;
|
||||||
|
memcpy(rpcMsgArr[i].pCont, pRpcCont, rpcMsgArr[i].contLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for debug ----------------------
|
||||||
|
void syncAppendEntriesBatchPrint(const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
char* serialized = syncAppendEntriesBatch2Str(pMsg);
|
||||||
|
printf("syncAppendEntriesBatchPrint | len:%lu | %s \n", strlen(serialized), serialized);
|
||||||
|
fflush(NULL);
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchPrint2(char* s, const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
char* serialized = syncAppendEntriesBatch2Str(pMsg);
|
||||||
|
printf("syncAppendEntriesBatchPrint2 | len:%lu | %s | %s \n", strlen(serialized), s, serialized);
|
||||||
|
fflush(NULL);
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchLog(const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
char* serialized = syncAppendEntriesBatch2Str(pMsg);
|
||||||
|
sTrace("syncAppendEntriesBatchLog | len:%lu | %s", strlen(serialized), serialized);
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncAppendEntriesBatchLog2(char* s, const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
if (gRaftDetailLog) {
|
||||||
|
char* serialized = syncAppendEntriesBatch2Str(pMsg);
|
||||||
|
sTraceLong("syncAppendEntriesBatchLog2 | len:%lu | %s | %s", strlen(serialized), s, serialized);
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- message process SyncAppendEntriesReply----
|
// ---- message process SyncAppendEntriesReply----
|
||||||
SyncAppendEntriesReply* syncAppendEntriesReplyBuild(int32_t vgId) {
|
SyncAppendEntriesReply* syncAppendEntriesReplyBuild(int32_t vgId) {
|
||||||
uint32_t bytes = sizeof(SyncAppendEntriesReply);
|
uint32_t bytes = sizeof(SyncAppendEntriesReply);
|
||||||
|
|
|
@ -101,7 +101,7 @@ cJSON *syncCfg2Json(SSyncCfg *pSyncCfg) {
|
||||||
|
|
||||||
char *syncCfg2Str(SSyncCfg *pSyncCfg) {
|
char *syncCfg2Str(SSyncCfg *pSyncCfg) {
|
||||||
cJSON *pJson = syncCfg2Json(pSyncCfg);
|
cJSON *pJson = syncCfg2Json(pSyncCfg);
|
||||||
char *serialized = cJSON_Print(pJson);
|
char * serialized = cJSON_Print(pJson);
|
||||||
cJSON_Delete(pJson);
|
cJSON_Delete(pJson);
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ char *syncCfg2Str(SSyncCfg *pSyncCfg) {
|
||||||
char *syncCfg2SimpleStr(SSyncCfg *pSyncCfg) {
|
char *syncCfg2SimpleStr(SSyncCfg *pSyncCfg) {
|
||||||
if (pSyncCfg != NULL) {
|
if (pSyncCfg != NULL) {
|
||||||
int32_t len = 512;
|
int32_t len = 512;
|
||||||
char *s = taosMemoryMalloc(len);
|
char * s = taosMemoryMalloc(len);
|
||||||
memset(s, 0, len);
|
memset(s, 0, len);
|
||||||
|
|
||||||
snprintf(s, len, "{replica-num:%d, my-index:%d, ", pSyncCfg->replicaNum, pSyncCfg->myIndex);
|
snprintf(s, len, "{replica-num:%d, my-index:%d, ", pSyncCfg->replicaNum, pSyncCfg->myIndex);
|
||||||
|
@ -205,7 +205,7 @@ cJSON *raftCfg2Json(SRaftCfg *pRaftCfg) {
|
||||||
|
|
||||||
char *raftCfg2Str(SRaftCfg *pRaftCfg) {
|
char *raftCfg2Str(SRaftCfg *pRaftCfg) {
|
||||||
cJSON *pJson = raftCfg2Json(pRaftCfg);
|
cJSON *pJson = raftCfg2Json(pRaftCfg);
|
||||||
char *serialized = cJSON_Print(pJson);
|
char * serialized = cJSON_Print(pJson);
|
||||||
cJSON_Delete(pJson);
|
cJSON_Delete(pJson);
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ int32_t raftCfgFromJson(const cJSON *pRoot, SRaftCfg *pRaftCfg) {
|
||||||
(pRaftCfg->configIndexArr)[i] = atoll(pIndex->valuestring);
|
(pRaftCfg->configIndexArr)[i] = atoll(pIndex->valuestring);
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON *pJsonSyncCfg = cJSON_GetObjectItem(pJson, "SSyncCfg");
|
cJSON * pJsonSyncCfg = cJSON_GetObjectItem(pJson, "SSyncCfg");
|
||||||
int32_t code = syncCfgFromJson(pJsonSyncCfg, &(pRaftCfg->cfg));
|
int32_t code = syncCfgFromJson(pJsonSyncCfg, &(pRaftCfg->cfg));
|
||||||
ASSERT(code == 0);
|
ASSERT(code == 0);
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,73 @@ int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeAppendEntriesPeersSnapshot2(SSyncNode* pSyncNode) {
|
||||||
|
if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret = 0;
|
||||||
|
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
||||||
|
SRaftId* pDestId = &(pSyncNode->peersId[i]);
|
||||||
|
|
||||||
|
// next index
|
||||||
|
SyncIndex nextIndex = syncIndexMgrGetIndex(pSyncNode->pNextIndex, pDestId);
|
||||||
|
|
||||||
|
// pre index, pre term
|
||||||
|
SyncIndex preLogIndex = syncNodeGetPreIndex(pSyncNode, nextIndex);
|
||||||
|
SyncTerm preLogTerm = syncNodeGetPreTerm(pSyncNode, nextIndex);
|
||||||
|
if (preLogTerm == SYNC_TERM_INVALID) {
|
||||||
|
SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(pSyncNode, pDestId);
|
||||||
|
ASSERT(pSender != NULL);
|
||||||
|
ASSERT(!snapshotSenderIsStart(pSender));
|
||||||
|
|
||||||
|
SyncIndex newNextIndex = syncNodeGetLastIndex(pSyncNode) + 1;
|
||||||
|
syncIndexMgrSetIndex(pSyncNode->pNextIndex, pDestId, newNextIndex);
|
||||||
|
syncIndexMgrSetIndex(pSyncNode->pMatchIndex, pDestId, SYNC_INDEX_INVALID);
|
||||||
|
sError("vgId:%d sync get pre term error, nextIndex:%ld, update next-index:%ld, match-index:%d, raftid:%ld",
|
||||||
|
pSyncNode->vgId, nextIndex, newNextIndex, SYNC_INDEX_INVALID, pDestId->addr);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcMsg rpcMsgArr[SYNC_MAX_BATCH_SIZE];
|
||||||
|
memset(rpcMsgArr, 0, sizeof(rpcMsgArr));
|
||||||
|
|
||||||
|
int32_t getCount = 0;
|
||||||
|
for (int32_t i = 0; i < pSyncNode->batchSize; ++i) {
|
||||||
|
SSyncRaftEntry* pEntry;
|
||||||
|
int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, nextIndex, &pEntry);
|
||||||
|
if (code == 0) {
|
||||||
|
ASSERT(pEntry != NULL);
|
||||||
|
// get rpc msg [i] from entry
|
||||||
|
syncEntryDestory(pEntry);
|
||||||
|
getCount++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch* pMsg = syncAppendEntriesBatchBuild(rpcMsgArr, getCount, pSyncNode->vgId);
|
||||||
|
ASSERT(pMsg != NULL);
|
||||||
|
|
||||||
|
// prepare msg
|
||||||
|
pMsg->srcId = pSyncNode->myRaftId;
|
||||||
|
pMsg->destId = *pDestId;
|
||||||
|
pMsg->term = pSyncNode->pRaftStore->currentTerm;
|
||||||
|
pMsg->prevLogIndex = preLogIndex;
|
||||||
|
pMsg->prevLogTerm = preLogTerm;
|
||||||
|
pMsg->commitIndex = pSyncNode->commitIndex;
|
||||||
|
pMsg->privateTerm = 0;
|
||||||
|
pMsg->dataCount = getCount;
|
||||||
|
|
||||||
|
// send msg
|
||||||
|
syncNodeAppendEntriesBatch(pSyncNode, pDestId, pMsg);
|
||||||
|
syncAppendEntriesBatchDestroy(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode) {
|
int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode) {
|
||||||
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_LEADER);
|
ASSERT(pSyncNode->state == TAOS_SYNC_STATE_LEADER);
|
||||||
|
|
||||||
|
@ -234,4 +301,24 @@ int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, c
|
||||||
syncAppendEntries2RpcMsg(pMsg, &rpcMsg);
|
syncAppendEntries2RpcMsg(pMsg, &rpcMsg);
|
||||||
syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t syncNodeAppendEntriesBatch(SSyncNode* pSyncNode, const SRaftId* destRaftId,
|
||||||
|
const SyncAppendEntriesBatch* pMsg) {
|
||||||
|
do {
|
||||||
|
char host[128];
|
||||||
|
uint16_t port;
|
||||||
|
syncUtilU642Addr(destRaftId->addr, host, sizeof(host), &port);
|
||||||
|
sDebug(
|
||||||
|
"vgId:%d, send sync-append-entries-batch to %s:%d, {term:%lu, pre-index:%ld, pre-term:%lu, pterm:%lu, "
|
||||||
|
"commit:%ld, "
|
||||||
|
"datalen:%d, dataCount:%d}",
|
||||||
|
pSyncNode->vgId, host, port, pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->privateTerm,
|
||||||
|
pMsg->commitIndex, pMsg->dataLen, pMsg->dataCount);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntriesBatch2RpcMsg(pMsg, &rpcMsg);
|
||||||
|
syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
||||||
|
return 0;
|
||||||
}
|
}
|
|
@ -80,7 +80,7 @@ void snapshotSenderDestroy(SSyncSnapshotSender *pSender) {
|
||||||
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender) { return pSender->start; }
|
bool snapshotSenderIsStart(SSyncSnapshotSender *pSender) { return pSender->start; }
|
||||||
|
|
||||||
// begin send snapshot by snapshot, pReader
|
// begin send snapshot by snapshot, pReader
|
||||||
void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader) {
|
int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader) {
|
||||||
ASSERT(!snapshotSenderIsStart(pSender));
|
ASSERT(!snapshotSenderIsStart(pSender));
|
||||||
|
|
||||||
// init snapshot and reader
|
// init snapshot and reader
|
||||||
|
@ -181,9 +181,11 @@ void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void
|
||||||
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
||||||
taosMemoryFree(eventLog);
|
taosMemoryFree(eventLog);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish) {
|
int32_t snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish) {
|
||||||
// close reader
|
// close reader
|
||||||
if (pSender->pReader != NULL) {
|
if (pSender->pReader != NULL) {
|
||||||
int32_t ret = pSender->pSyncNode->pFsm->FpSnapshotStopRead(pSender->pSyncNode->pFsm, pSender->pReader);
|
int32_t ret = pSender->pSyncNode->pFsm->FpSnapshotStopRead(pSender->pSyncNode->pFsm, pSender->pReader);
|
||||||
|
@ -208,6 +210,8 @@ void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish) {
|
||||||
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
syncNodeEventLog(pSender->pSyncNode, eventLog);
|
||||||
taosMemoryFree(eventLog);
|
taosMemoryFree(eventLog);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// when sender receive ack, call this function to send msg from seq
|
// when sender receive ack, call this function to send msg from seq
|
||||||
|
@ -471,7 +475,7 @@ static void snapshotReceiverForceStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
|
|
||||||
// if receiver receive msg from seq = SYNC_SNAPSHOT_SEQ_BEGIN, start receiver
|
// if receiver receive msg from seq = SYNC_SNAPSHOT_SEQ_BEGIN, start receiver
|
||||||
// if already start, force close, start again
|
// if already start, force close, start again
|
||||||
void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg) {
|
int32_t snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTerm, SyncSnapshotSend *pBeginMsg) {
|
||||||
if (!snapshotReceiverIsStart(pReceiver)) {
|
if (!snapshotReceiverIsStart(pReceiver)) {
|
||||||
// first start
|
// first start
|
||||||
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
||||||
|
@ -486,9 +490,11 @@ void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateTer
|
||||||
// start again
|
// start again
|
||||||
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
snapshotReceiverDoStart(pReceiver, privateTerm, pBeginMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver) {
|
int32_t snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
if (pReceiver->pWriter != NULL) {
|
if (pReceiver->pWriter != NULL) {
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, false);
|
pReceiver->pSyncNode->pFsm->FpSnapshotStopWrite(pReceiver->pSyncNode->pFsm, pReceiver->pWriter, false);
|
||||||
|
@ -506,6 +512,8 @@ void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver) {
|
||||||
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
syncNodeEventLog(pReceiver->pSyncNode, eventLog);
|
||||||
taosMemoryFree(eventLog);
|
taosMemoryFree(eventLog);
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t snapshotReceiverFinish(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *pMsg) {
|
static int32_t snapshotReceiverFinish(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSend *pMsg) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ add_executable(syncEntryCacheTest "")
|
||||||
add_executable(syncRequestVoteTest "")
|
add_executable(syncRequestVoteTest "")
|
||||||
add_executable(syncRequestVoteReplyTest "")
|
add_executable(syncRequestVoteReplyTest "")
|
||||||
add_executable(syncAppendEntriesTest "")
|
add_executable(syncAppendEntriesTest "")
|
||||||
|
add_executable(syncAppendEntriesBatchTest "")
|
||||||
add_executable(syncAppendEntriesReplyTest "")
|
add_executable(syncAppendEntriesReplyTest "")
|
||||||
add_executable(syncClientRequestTest "")
|
add_executable(syncClientRequestTest "")
|
||||||
add_executable(syncTimeoutTest "")
|
add_executable(syncTimeoutTest "")
|
||||||
|
@ -146,6 +147,10 @@ target_sources(syncAppendEntriesTest
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"syncAppendEntriesTest.cpp"
|
"syncAppendEntriesTest.cpp"
|
||||||
)
|
)
|
||||||
|
target_sources(syncAppendEntriesBatchTest
|
||||||
|
PRIVATE
|
||||||
|
"syncAppendEntriesBatchTest.cpp"
|
||||||
|
)
|
||||||
target_sources(syncAppendEntriesReplyTest
|
target_sources(syncAppendEntriesReplyTest
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"syncAppendEntriesReplyTest.cpp"
|
"syncAppendEntriesReplyTest.cpp"
|
||||||
|
@ -387,6 +392,11 @@ target_include_directories(syncAppendEntriesTest
|
||||||
"${TD_SOURCE_DIR}/include/libs/sync"
|
"${TD_SOURCE_DIR}/include/libs/sync"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||||
)
|
)
|
||||||
|
target_include_directories(syncAppendEntriesBatchTest
|
||||||
|
PUBLIC
|
||||||
|
"${TD_SOURCE_DIR}/include/libs/sync"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||||
|
)
|
||||||
target_include_directories(syncAppendEntriesReplyTest
|
target_include_directories(syncAppendEntriesReplyTest
|
||||||
PUBLIC
|
PUBLIC
|
||||||
"${TD_SOURCE_DIR}/include/libs/sync"
|
"${TD_SOURCE_DIR}/include/libs/sync"
|
||||||
|
@ -636,6 +646,10 @@ target_link_libraries(syncAppendEntriesTest
|
||||||
sync
|
sync
|
||||||
gtest_main
|
gtest_main
|
||||||
)
|
)
|
||||||
|
target_link_libraries(syncAppendEntriesBatchTest
|
||||||
|
sync
|
||||||
|
gtest_main
|
||||||
|
)
|
||||||
target_link_libraries(syncAppendEntriesReplyTest
|
target_link_libraries(syncAppendEntriesReplyTest
|
||||||
sync
|
sync
|
||||||
gtest_main
|
gtest_main
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
//#include <gtest/gtest.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "syncIO.h"
|
||||||
|
#include "syncInt.h"
|
||||||
|
#include "syncMessage.h"
|
||||||
|
#include "syncUtil.h"
|
||||||
|
#include "trpc.h"
|
||||||
|
|
||||||
|
void logTest() {
|
||||||
|
sTrace("--- sync log test: trace");
|
||||||
|
sDebug("--- sync log test: debug");
|
||||||
|
sInfo("--- sync log test: info");
|
||||||
|
sWarn("--- sync log test: warn");
|
||||||
|
sError("--- sync log test: error");
|
||||||
|
sFatal("--- sync log test: fatal");
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcMsg *createRpcMsg(int32_t i, int32_t dataLen) {
|
||||||
|
SRpcMsg *pRpcMsg = (SRpcMsg *)taosMemoryMalloc(sizeof(SRpcMsg));
|
||||||
|
memset(pRpcMsg, 0, sizeof(SRpcMsg));
|
||||||
|
|
||||||
|
pRpcMsg->msgType = TDMT_SYNC_PING;
|
||||||
|
pRpcMsg->contLen = dataLen;
|
||||||
|
pRpcMsg->pCont = rpcMallocCont(pRpcMsg->contLen);
|
||||||
|
pRpcMsg->code = 10 * i;
|
||||||
|
snprintf((char *)pRpcMsg->pCont, pRpcMsg->contLen, "value_%d", i);
|
||||||
|
|
||||||
|
return pRpcMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch *createMsg() {
|
||||||
|
SRpcMsg rpcMsgArr[5];
|
||||||
|
memset(rpcMsgArr, 0, sizeof(rpcMsgArr));
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 5; ++i) {
|
||||||
|
SRpcMsg *pRpcMsg = createRpcMsg(i, 20);
|
||||||
|
rpcMsgArr[i] = *pRpcMsg;
|
||||||
|
taosMemoryFree(pRpcMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncAppendEntriesBatch *pMsg = syncAppendEntriesBatchBuild(rpcMsgArr, 5, 1234);
|
||||||
|
pMsg->srcId.addr = syncUtilAddr2U64("127.0.0.1", 1234);
|
||||||
|
pMsg->srcId.vgId = 100;
|
||||||
|
pMsg->destId.addr = syncUtilAddr2U64("127.0.0.1", 5678);
|
||||||
|
pMsg->destId.vgId = 100;
|
||||||
|
pMsg->prevLogIndex = 11;
|
||||||
|
pMsg->prevLogTerm = 22;
|
||||||
|
pMsg->commitIndex = 33;
|
||||||
|
pMsg->privateTerm = 44;
|
||||||
|
return pMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test1() {
|
||||||
|
SyncAppendEntriesBatch *pMsg = createMsg();
|
||||||
|
syncAppendEntriesBatchLog2((char *)"test1:", pMsg);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsgArr[5];
|
||||||
|
int32_t retArrSize;
|
||||||
|
syncAppendEntriesBatch2RpcMsgArray(pMsg, rpcMsgArr, 5, &retArrSize);
|
||||||
|
for (int i = 0; i < retArrSize; ++i) {
|
||||||
|
char logBuf[128];
|
||||||
|
snprintf(logBuf, sizeof(logBuf), "==test1 decode rpc msg %d: msgType:%d, code:%d, contLen:%d, pCont:%s \n", i,
|
||||||
|
rpcMsgArr[i].msgType, rpcMsgArr[i].code, rpcMsgArr[i].contLen, (char *)rpcMsgArr[i].pCont);
|
||||||
|
sTrace("%s", logBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
syncAppendEntriesBatchDestroy(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void test2() {
|
||||||
|
SyncAppendEntries *pMsg = createMsg();
|
||||||
|
uint32_t len = pMsg->bytes;
|
||||||
|
char * serialized = (char *)taosMemoryMalloc(len);
|
||||||
|
syncAppendEntriesSerialize(pMsg, serialized, len);
|
||||||
|
SyncAppendEntries *pMsg2 = syncAppendEntriesBuild(pMsg->dataLen, 1000);
|
||||||
|
syncAppendEntriesDeserialize(serialized, len, pMsg2);
|
||||||
|
syncAppendEntriesLog2((char *)"test2: syncAppendEntriesSerialize -> syncAppendEntriesDeserialize ", pMsg2);
|
||||||
|
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
syncAppendEntriesDestroy(pMsg);
|
||||||
|
syncAppendEntriesDestroy(pMsg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3() {
|
||||||
|
SyncAppendEntries *pMsg = createMsg();
|
||||||
|
uint32_t len;
|
||||||
|
char * serialized = syncAppendEntriesSerialize2(pMsg, &len);
|
||||||
|
SyncAppendEntries *pMsg2 = syncAppendEntriesDeserialize2(serialized, len);
|
||||||
|
syncAppendEntriesLog2((char *)"test3: syncAppendEntriesSerialize3 -> syncAppendEntriesDeserialize2 ", pMsg2);
|
||||||
|
|
||||||
|
taosMemoryFree(serialized);
|
||||||
|
syncAppendEntriesDestroy(pMsg);
|
||||||
|
syncAppendEntriesDestroy(pMsg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test4() {
|
||||||
|
SyncAppendEntries *pMsg = createMsg();
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntries2RpcMsg(pMsg, &rpcMsg);
|
||||||
|
SyncAppendEntries *pMsg2 = (SyncAppendEntries *)taosMemoryMalloc(rpcMsg.contLen);
|
||||||
|
syncAppendEntriesFromRpcMsg(&rpcMsg, pMsg2);
|
||||||
|
syncAppendEntriesLog2((char *)"test4: syncAppendEntries2RpcMsg -> syncAppendEntriesFromRpcMsg ", pMsg2);
|
||||||
|
|
||||||
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
syncAppendEntriesDestroy(pMsg);
|
||||||
|
syncAppendEntriesDestroy(pMsg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test5() {
|
||||||
|
SyncAppendEntries *pMsg = createMsg();
|
||||||
|
SRpcMsg rpcMsg;
|
||||||
|
syncAppendEntries2RpcMsg(pMsg, &rpcMsg);
|
||||||
|
SyncAppendEntries *pMsg2 = syncAppendEntriesFromRpcMsg2(&rpcMsg);
|
||||||
|
syncAppendEntriesLog2((char *)"test5: syncAppendEntries2RpcMsg -> syncAppendEntriesFromRpcMsg2 ", pMsg2);
|
||||||
|
|
||||||
|
rpcFreeCont(rpcMsg.pCont);
|
||||||
|
syncAppendEntriesDestroy(pMsg);
|
||||||
|
syncAppendEntriesDestroy(pMsg2);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
gRaftDetailLog = true;
|
||||||
|
tsAsyncLog = 0;
|
||||||
|
sDebugFlag = DEBUG_DEBUG + DEBUG_TRACE + DEBUG_SCREEN + DEBUG_FILE;
|
||||||
|
logTest();
|
||||||
|
|
||||||
|
test1();
|
||||||
|
|
||||||
|
/*
|
||||||
|
test2();
|
||||||
|
test3();
|
||||||
|
test4();
|
||||||
|
test5();
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ int32_t GetSnapshotCb(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void** ppReader) {
|
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, void** ppReader) {
|
||||||
*ppReader = (void*)0xABCD;
|
*ppReader = (void*)0xABCD;
|
||||||
char logBuf[256] = {0};
|
char logBuf[256] = {0};
|
||||||
snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader);
|
snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader);
|
||||||
|
|
|
@ -25,7 +25,7 @@ void ReConfigCb(struct SSyncFSM* pFsm, SSyncCfg newCfg, SReConfigCbMeta cbMeta)
|
||||||
|
|
||||||
int32_t GetSnapshot(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) { return 0; }
|
int32_t GetSnapshot(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) { return 0; }
|
||||||
|
|
||||||
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void** ppReader) { return 0; }
|
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, void** ppReader) { return 0; }
|
||||||
int32_t SnapshotStopRead(struct SSyncFSM* pFsm, void* pReader) { return 0; }
|
int32_t SnapshotStopRead(struct SSyncFSM* pFsm, void* pReader) { return 0; }
|
||||||
int32_t SnapshotDoRead(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len) { return 0; }
|
int32_t SnapshotDoRead(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len) { return 0; }
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ int32_t GetSnapshotCb(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void** ppReader) {
|
int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, void** ppReader) {
|
||||||
*ppReader = (void*)0xABCD;
|
*ppReader = (void*)0xABCD;
|
||||||
char logBuf[256] = {0};
|
char logBuf[256] = {0};
|
||||||
snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader);
|
snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader);
|
||||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// meta section begin
|
// meta section begin
|
||||||
typedef struct WalFileInfo {
|
typedef struct {
|
||||||
int64_t firstVer;
|
int64_t firstVer;
|
||||||
int64_t lastVer;
|
int64_t lastVer;
|
||||||
int64_t createTs;
|
int64_t createTs;
|
||||||
|
@ -98,20 +98,20 @@ static inline int walBuildIdxName(SWal* pWal, int64_t fileFirstVer, char* buf) {
|
||||||
return sprintf(buf, "%s/%020" PRId64 "." WAL_INDEX_SUFFIX, pWal->path, fileFirstVer);
|
return sprintf(buf, "%s/%020" PRId64 "." WAL_INDEX_SUFFIX, pWal->path, fileFirstVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int walValidHeadCksum(SWalHead* pHead) {
|
static inline int walValidHeadCksum(SWalCkHead* pHead) {
|
||||||
return taosCheckChecksum((uint8_t*)&pHead->head, sizeof(SWalReadHead), pHead->cksumHead);
|
return taosCheckChecksum((uint8_t*)&pHead->head, sizeof(SWalCont), pHead->cksumHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int walValidBodyCksum(SWalHead* pHead) {
|
static inline int walValidBodyCksum(SWalCkHead* pHead) {
|
||||||
return taosCheckChecksum((uint8_t*)pHead->head.body, pHead->head.bodyLen, pHead->cksumBody);
|
return taosCheckChecksum((uint8_t*)pHead->head.body, pHead->head.bodyLen, pHead->cksumBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int walValidCksum(SWalHead* pHead, void* body, int64_t bodyLen) {
|
static inline int walValidCksum(SWalCkHead* pHead, void* body, int64_t bodyLen) {
|
||||||
return walValidHeadCksum(pHead) && walValidBodyCksum(pHead);
|
return walValidHeadCksum(pHead) && walValidBodyCksum(pHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t walCalcHeadCksum(SWalHead* pHead) {
|
static inline uint32_t walCalcHeadCksum(SWalCkHead* pHead) {
|
||||||
return taosCalcChecksum(0, (uint8_t*)&pHead->head, sizeof(SWalReadHead));
|
return taosCalcChecksum(0, (uint8_t*)&pHead->head, sizeof(SWalCont));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t walCalcBodyCksum(const void* body, uint32_t len) {
|
static inline uint32_t walCalcBodyCksum(const void* body, uint32_t len) {
|
||||||
|
|
|
@ -16,9 +16,13 @@
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "tref.h"
|
#include "tutil.h"
|
||||||
#include "walInt.h"
|
#include "walInt.h"
|
||||||
|
|
||||||
|
bool FORCE_INLINE walLogExist(SWal* pWal, int64_t ver) {
|
||||||
|
return !walIsEmpty(pWal) && walGetFirstVer(pWal) <= ver && walGetLastVer(pWal) >= ver;
|
||||||
|
}
|
||||||
|
|
||||||
bool FORCE_INLINE walIsEmpty(SWal* pWal) { return pWal->vers.firstVer == -1; }
|
bool FORCE_INLINE walIsEmpty(SWal* pWal) { return pWal->vers.firstVer == -1; }
|
||||||
|
|
||||||
int64_t FORCE_INLINE walGetFirstVer(SWal* pWal) { return pWal->vers.firstVer; }
|
int64_t FORCE_INLINE walGetFirstVer(SWal* pWal) { return pWal->vers.firstVer; }
|
||||||
|
@ -33,26 +37,9 @@ static FORCE_INLINE int walBuildMetaName(SWal* pWal, int metaVer, char* buf) {
|
||||||
return sprintf(buf, "%s/meta-ver%d", pWal->path, metaVer);
|
return sprintf(buf, "%s/meta-ver%d", pWal->path, metaVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* tmemmem(char* haystack, int hlen, char* needle, int nlen) {
|
|
||||||
char* limit;
|
|
||||||
|
|
||||||
if (nlen == 0 || hlen < nlen) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
limit = haystack + hlen - nlen + 1;
|
|
||||||
while ((haystack = (char*)memchr(haystack, needle[0], limit - haystack)) != NULL) {
|
|
||||||
if (memcmp(haystack, needle, nlen) == 0) {
|
|
||||||
return haystack;
|
|
||||||
}
|
|
||||||
haystack++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal) {
|
static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal) {
|
||||||
ASSERT(pWal->fileInfoSet != NULL);
|
ASSERT(pWal->fileInfoSet != NULL);
|
||||||
int sz = taosArrayGetSize(pWal->fileInfoSet);
|
int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
|
||||||
ASSERT(sz > 0);
|
ASSERT(sz > 0);
|
||||||
#if 0
|
#if 0
|
||||||
for (int i = 0; i < sz; i++) {
|
for (int i = 0; i < sz; i++) {
|
||||||
|
@ -97,14 +84,14 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal) {
|
||||||
char* candidate;
|
char* candidate;
|
||||||
while ((candidate = tmemmem(haystack, readSize - (haystack - buf), (char*)&magic, sizeof(uint64_t))) != NULL) {
|
while ((candidate = tmemmem(haystack, readSize - (haystack - buf), (char*)&magic, sizeof(uint64_t))) != NULL) {
|
||||||
// read and validate
|
// read and validate
|
||||||
SWalHead* logContent = (SWalHead*)candidate;
|
SWalCkHead* logContent = (SWalCkHead*)candidate;
|
||||||
if (walValidHeadCksum(logContent) == 0 && walValidBodyCksum(logContent) == 0) {
|
if (walValidHeadCksum(logContent) == 0 && walValidBodyCksum(logContent) == 0) {
|
||||||
found = candidate;
|
found = candidate;
|
||||||
}
|
}
|
||||||
haystack = candidate + 1;
|
haystack = candidate + 1;
|
||||||
}
|
}
|
||||||
if (found == buf) {
|
if (found == buf) {
|
||||||
SWalHead* logContent = (SWalHead*)found;
|
SWalCkHead* logContent = (SWalCkHead*)found;
|
||||||
if (walValidHeadCksum(logContent) != 0 || walValidBodyCksum(logContent) != 0) {
|
if (walValidHeadCksum(logContent) != 0 || walValidBodyCksum(logContent) != 0) {
|
||||||
// file has to be deleted
|
// file has to be deleted
|
||||||
taosMemoryFree(buf);
|
taosMemoryFree(buf);
|
||||||
|
@ -114,7 +101,7 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taosCloseFile(&pFile);
|
taosCloseFile(&pFile);
|
||||||
SWalHead* lastEntry = (SWalHead*)found;
|
SWalCkHead* lastEntry = (SWalCkHead*)found;
|
||||||
|
|
||||||
return lastEntry->head.version;
|
return lastEntry->head.version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,8 +117,8 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) {
|
||||||
pWal->lastRollSeq = -1;
|
pWal->lastRollSeq = -1;
|
||||||
|
|
||||||
// init write buffer
|
// init write buffer
|
||||||
memset(&pWal->writeHead, 0, sizeof(SWalHead));
|
memset(&pWal->writeHead, 0, sizeof(SWalCkHead));
|
||||||
pWal->writeHead.head.headVer = WAL_HEAD_VER;
|
pWal->writeHead.head.protoVer = WAL_PROTO_VER;
|
||||||
pWal->writeHead.magic = WAL_MAGIC;
|
pWal->writeHead.magic = WAL_MAGIC;
|
||||||
|
|
||||||
if (taosThreadMutexInit(&pWal->mutex, NULL) < 0) {
|
if (taosThreadMutexInit(&pWal->mutex, NULL) < 0) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ SWalReadHandle *walOpenReadHandle(SWal *pWal) {
|
||||||
|
|
||||||
taosThreadMutexInit(&pRead->mutex, NULL);
|
taosThreadMutexInit(&pRead->mutex, NULL);
|
||||||
|
|
||||||
pRead->pHead = taosMemoryMalloc(sizeof(SWalHead));
|
pRead->pHead = taosMemoryMalloc(sizeof(SWalCkHead));
|
||||||
if (pRead->pHead == NULL) {
|
if (pRead->pHead == NULL) {
|
||||||
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
||||||
taosMemoryFree(pRead);
|
taosMemoryFree(pRead);
|
||||||
|
@ -155,7 +155,7 @@ static int32_t walReadSeekVer(SWalReadHandle *pRead, int64_t ver) {
|
||||||
|
|
||||||
void walSetReaderCapacity(SWalReadHandle *pRead, int32_t capacity) { pRead->capacity = capacity; }
|
void walSetReaderCapacity(SWalReadHandle *pRead, int32_t capacity) { pRead->capacity = capacity; }
|
||||||
|
|
||||||
int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalHead *pHead) {
|
int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalCkHead *pHead) {
|
||||||
int64_t code;
|
int64_t code;
|
||||||
|
|
||||||
// TODO: valid ver
|
// TODO: valid ver
|
||||||
|
@ -170,8 +170,8 @@ int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalHead *pHead) {
|
||||||
|
|
||||||
ASSERT(taosValidFile(pRead->pReadLogTFile) == true);
|
ASSERT(taosValidFile(pRead->pReadLogTFile) == true);
|
||||||
|
|
||||||
code = taosReadFile(pRead->pReadLogTFile, pHead, sizeof(SWalHead));
|
code = taosReadFile(pRead->pReadLogTFile, pHead, sizeof(SWalCkHead));
|
||||||
if (code != sizeof(SWalHead)) {
|
if (code != sizeof(SWalCkHead)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalHead *pHead) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t walSkipFetchBody(SWalReadHandle *pRead, const SWalHead *pHead) {
|
int32_t walSkipFetchBody(SWalReadHandle *pRead, const SWalCkHead *pHead) {
|
||||||
int64_t code;
|
int64_t code;
|
||||||
|
|
||||||
ASSERT(pRead->curVersion == pHead->head.version);
|
ASSERT(pRead->curVersion == pHead->head.version);
|
||||||
|
@ -203,12 +203,12 @@ int32_t walSkipFetchBody(SWalReadHandle *pRead, const SWalHead *pHead) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t walFetchBody(SWalReadHandle *pRead, SWalHead **ppHead) {
|
int32_t walFetchBody(SWalReadHandle *pRead, SWalCkHead **ppHead) {
|
||||||
SWalReadHead *pReadHead = &((*ppHead)->head);
|
SWalCont *pReadHead = &((*ppHead)->head);
|
||||||
int64_t ver = pReadHead->version;
|
int64_t ver = pReadHead->version;
|
||||||
|
|
||||||
if (pRead->capacity < pReadHead->bodyLen) {
|
if (pRead->capacity < pReadHead->bodyLen) {
|
||||||
void *ptr = taosMemoryRealloc(*ppHead, sizeof(SWalHead) + pReadHead->bodyLen);
|
void *ptr = taosMemoryRealloc(*ppHead, sizeof(SWalCkHead) + pReadHead->bodyLen);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -241,18 +241,18 @@ int32_t walFetchBody(SWalReadHandle *pRead, SWalHead **ppHead) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t walReadWithHandle_s(SWalReadHandle *pRead, int64_t ver, SWalReadHead **ppHead) {
|
int32_t walReadWithHandle_s(SWalReadHandle *pRead, int64_t ver, SWalCont **ppHead) {
|
||||||
taosThreadMutexLock(&pRead->mutex);
|
taosThreadMutexLock(&pRead->mutex);
|
||||||
if (walReadWithHandle(pRead, ver) < 0) {
|
if (walReadWithHandle(pRead, ver) < 0) {
|
||||||
taosThreadMutexUnlock(&pRead->mutex);
|
taosThreadMutexUnlock(&pRead->mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*ppHead = taosMemoryMalloc(sizeof(SWalReadHead) + pRead->pHead->head.bodyLen);
|
*ppHead = taosMemoryMalloc(sizeof(SWalCont) + pRead->pHead->head.bodyLen);
|
||||||
if (*ppHead == NULL) {
|
if (*ppHead == NULL) {
|
||||||
taosThreadMutexUnlock(&pRead->mutex);
|
taosThreadMutexUnlock(&pRead->mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(*ppHead, &pRead->pHead->head, sizeof(SWalReadHead) + pRead->pHead->head.bodyLen);
|
memcpy(*ppHead, &pRead->pHead->head, sizeof(SWalCont) + pRead->pHead->head.bodyLen);
|
||||||
taosThreadMutexUnlock(&pRead->mutex);
|
taosThreadMutexUnlock(&pRead->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -282,8 +282,8 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) {
|
||||||
|
|
||||||
ASSERT(taosValidFile(pRead->pReadLogTFile) == true);
|
ASSERT(taosValidFile(pRead->pReadLogTFile) == true);
|
||||||
|
|
||||||
code = taosReadFile(pRead->pReadLogTFile, pRead->pHead, sizeof(SWalHead));
|
code = taosReadFile(pRead->pReadLogTFile, pRead->pHead, sizeof(SWalCkHead));
|
||||||
if (code != sizeof(SWalHead)) {
|
if (code != sizeof(SWalCkHead)) {
|
||||||
if (code < 0)
|
if (code < 0)
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
else {
|
else {
|
||||||
|
@ -301,7 +301,7 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRead->capacity < pRead->pHead->head.bodyLen) {
|
if (pRead->capacity < pRead->pHead->head.bodyLen) {
|
||||||
void *ptr = taosMemoryRealloc(pRead->pHead, sizeof(SWalHead) + pRead->pHead->head.bodyLen);
|
void *ptr = taosMemoryRealloc(pRead->pHead, sizeof(SWalCkHead) + pRead->pHead->head.bodyLen);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_WAL_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -142,10 +142,10 @@ int32_t walRollback(SWal *pWal, int64_t ver) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// validate offset
|
// validate offset
|
||||||
SWalHead head;
|
SWalCkHead head;
|
||||||
ASSERT(taosValidFile(pLogTFile));
|
ASSERT(taosValidFile(pLogTFile));
|
||||||
int64_t size = taosReadFile(pLogTFile, &head, sizeof(SWalHead));
|
int64_t size = taosReadFile(pLogTFile, &head, sizeof(SWalCkHead));
|
||||||
if (size != sizeof(SWalHead)) {
|
if (size != sizeof(SWalCkHead)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
code = walValidHeadCksum(&head);
|
code = walValidHeadCksum(&head);
|
||||||
|
@ -261,7 +261,7 @@ int32_t walEndSnapshot(SWal *pWal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int walRoll(SWal *pWal) {
|
int walRoll(SWal *pWal) {
|
||||||
int code = 0;
|
int32_t code = 0;
|
||||||
if (pWal->pWriteIdxTFile != NULL) {
|
if (pWal->pWriteIdxTFile != NULL) {
|
||||||
code = taosCloseFile(&pWal->pWriteIdxTFile);
|
code = taosCloseFile(&pWal->pWriteIdxTFile);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
@ -321,12 +321,13 @@ static int walWriteIndex(SWal *pWal, int64_t ver, int64_t offset) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLogMeta syncMeta, const void *body,
|
int32_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLogMeta syncMeta, const void *body,
|
||||||
int32_t bodyLen) {
|
int32_t bodyLen) {
|
||||||
int code = 0;
|
int32_t code = 0;
|
||||||
|
|
||||||
// no wal
|
// no wal
|
||||||
if (pWal->cfg.level == TAOS_WAL_NOLOG) return 0;
|
if (pWal->cfg.level == TAOS_WAL_NOLOG) return 0;
|
||||||
|
|
||||||
if (bodyLen > TSDB_MAX_WAL_SIZE) {
|
if (bodyLen > TSDB_MAX_WAL_SIZE) {
|
||||||
terrno = TSDB_CODE_WAL_SIZE_LIMIT;
|
terrno = TSDB_CODE_WAL_SIZE_LIMIT;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -356,6 +357,7 @@ int64_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog
|
||||||
terrno = TSDB_CODE_WAL_INVALID_VER;
|
terrno = TSDB_CODE_WAL_INVALID_VER;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (!tfValid(pWal->pWriteLogTFile)) return -1;*/
|
/*if (!tfValid(pWal->pWriteLogTFile)) return -1;*/
|
||||||
|
|
||||||
ASSERT(pWal->writeCur >= 0);
|
ASSERT(pWal->writeCur >= 0);
|
||||||
|
@ -380,7 +382,7 @@ int64_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog
|
||||||
pWal->writeHead.cksumHead = walCalcHeadCksum(&pWal->writeHead);
|
pWal->writeHead.cksumHead = walCalcHeadCksum(&pWal->writeHead);
|
||||||
pWal->writeHead.cksumBody = walCalcBodyCksum(body, bodyLen);
|
pWal->writeHead.cksumBody = walCalcBodyCksum(body, bodyLen);
|
||||||
|
|
||||||
if (taosWriteFile(pWal->pWriteLogTFile, &pWal->writeHead, sizeof(SWalHead)) != sizeof(SWalHead)) {
|
if (taosWriteFile(pWal->pWriteLogTFile, &pWal->writeHead, sizeof(SWalCkHead)) != sizeof(SWalCkHead)) {
|
||||||
// TODO ftruncate
|
// TODO ftruncate
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal),
|
wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal),
|
||||||
|
@ -405,19 +407,19 @@ int64_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog
|
||||||
// set status
|
// set status
|
||||||
if (pWal->vers.firstVer == -1) pWal->vers.firstVer = index;
|
if (pWal->vers.firstVer == -1) pWal->vers.firstVer = index;
|
||||||
pWal->vers.lastVer = index;
|
pWal->vers.lastVer = index;
|
||||||
pWal->totSize += sizeof(SWalHead) + bodyLen;
|
pWal->totSize += sizeof(SWalCkHead) + bodyLen;
|
||||||
if (walGetCurFileInfo(pWal)->firstVer == -1) {
|
if (walGetCurFileInfo(pWal)->firstVer == -1) {
|
||||||
walGetCurFileInfo(pWal)->firstVer = index;
|
walGetCurFileInfo(pWal)->firstVer = index;
|
||||||
}
|
}
|
||||||
walGetCurFileInfo(pWal)->lastVer = index;
|
walGetCurFileInfo(pWal)->lastVer = index;
|
||||||
walGetCurFileInfo(pWal)->fileSize += sizeof(SWalHead) + bodyLen;
|
walGetCurFileInfo(pWal)->fileSize += sizeof(SWalCkHead) + bodyLen;
|
||||||
|
|
||||||
taosThreadMutexUnlock(&pWal->mutex);
|
taosThreadMutexUnlock(&pWal->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t walWrite(SWal *pWal, int64_t index, tmsg_t msgType, const void *body, int32_t bodyLen) {
|
int32_t walWrite(SWal *pWal, int64_t index, tmsg_t msgType, const void *body, int32_t bodyLen) {
|
||||||
SSyncLogMeta syncMeta = {
|
SSyncLogMeta syncMeta = {
|
||||||
.isWeek = -1,
|
.isWeek = -1,
|
||||||
.seqNum = UINT64_MAX,
|
.seqNum = UINT64_MAX,
|
||||||
|
@ -435,27 +437,3 @@ void walFsync(SWal *pWal, bool forceFsync) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static int walValidateOffset(SWal* pWal, int64_t ver) {*/
|
|
||||||
/*int code = 0;*/
|
|
||||||
/*SWalHead *pHead = NULL;*/
|
|
||||||
/*code = (int)walRead(pWal, &pHead, ver);*/
|
|
||||||
/*if(pHead->head.version != ver) {*/
|
|
||||||
/*return -1;*/
|
|
||||||
/*}*/
|
|
||||||
/*return 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*static int64_t walGetOffset(SWal* pWal, int64_t ver) {*/
|
|
||||||
/*int code = walSeekVer(pWal, ver);*/
|
|
||||||
/*if(code != 0) {*/
|
|
||||||
/*return -1;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*code = walValidateOffset(pWal, ver);*/
|
|
||||||
/*if(code != 0) {*/
|
|
||||||
/*return -1;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*return 0;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ TEST_F(WalCleanEnv, createNew) {
|
||||||
walRollFileInfo(pWal);
|
walRollFileInfo(pWal);
|
||||||
ASSERT(pWal->fileInfoSet != NULL);
|
ASSERT(pWal->fileInfoSet != NULL);
|
||||||
ASSERT_EQ(pWal->fileInfoSet->size, 1);
|
ASSERT_EQ(pWal->fileInfoSet->size, 1);
|
||||||
WalFileInfo* pInfo = (WalFileInfo*)taosArrayGetLast(pWal->fileInfoSet);
|
SWalFileInfo* pInfo = (SWalFileInfo*)taosArrayGetLast(pWal->fileInfoSet);
|
||||||
ASSERT_EQ(pInfo->firstVer, 0);
|
ASSERT_EQ(pInfo->firstVer, 0);
|
||||||
ASSERT_EQ(pInfo->lastVer, -1);
|
ASSERT_EQ(pInfo->lastVer, -1);
|
||||||
ASSERT_EQ(pInfo->closeTs, -1);
|
ASSERT_EQ(pInfo->closeTs, -1);
|
||||||
|
|
|
@ -300,16 +300,14 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||||
return pFile;
|
return pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t taosCloseFile(TdFilePtr *ppFile) {
|
int32_t taosCloseFile(TdFilePtr *ppFile) {
|
||||||
|
int32_t code = 0;
|
||||||
if (ppFile == NULL || *ppFile == NULL) {
|
if (ppFile == NULL || *ppFile == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#if FILE_WITH_LOCK
|
#if FILE_WITH_LOCK
|
||||||
taosThreadRwlockWrlock(&((*ppFile)->rwlock));
|
taosThreadRwlockWrlock(&((*ppFile)->rwlock));
|
||||||
#endif
|
#endif
|
||||||
if (ppFile == NULL || *ppFile == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((*ppFile)->fp != NULL) {
|
if ((*ppFile)->fp != NULL) {
|
||||||
fflush((*ppFile)->fp);
|
fflush((*ppFile)->fp);
|
||||||
fclose((*ppFile)->fp);
|
fclose((*ppFile)->fp);
|
||||||
|
@ -320,9 +318,10 @@ int64_t taosCloseFile(TdFilePtr *ppFile) {
|
||||||
HANDLE h = (HANDLE)_get_osfhandle((*ppFile)->fd);
|
HANDLE h = (HANDLE)_get_osfhandle((*ppFile)->fd);
|
||||||
!FlushFileBuffers(h);
|
!FlushFileBuffers(h);
|
||||||
#else
|
#else
|
||||||
fsync((*ppFile)->fd);
|
// warning: never fsync silently in base lib
|
||||||
|
/*fsync((*ppFile)->fd);*/
|
||||||
#endif
|
#endif
|
||||||
close((*ppFile)->fd);
|
code = close((*ppFile)->fd);
|
||||||
(*ppFile)->fd = -1;
|
(*ppFile)->fd = -1;
|
||||||
}
|
}
|
||||||
(*ppFile)->refId = 0;
|
(*ppFile)->refId = 0;
|
||||||
|
@ -332,7 +331,7 @@ int64_t taosCloseFile(TdFilePtr *ppFile) {
|
||||||
#endif
|
#endif
|
||||||
taosMemoryFree(*ppFile);
|
taosMemoryFree(*ppFile);
|
||||||
*ppFile = NULL;
|
*ppFile = NULL;
|
||||||
return 0;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
||||||
|
@ -560,6 +559,8 @@ int32_t taosFsyncFile(TdFilePtr pFile) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this implementation is WRONG
|
||||||
|
// fflush is not a replacement of fsync
|
||||||
if (pFile->fp != NULL) return fflush(pFile->fp);
|
if (pFile->fp != NULL) return fflush(pFile->fp);
|
||||||
if (pFile->fd >= 0) {
|
if (pFile->fd >= 0) {
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ALLOW_FORBID_FUNC
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
void swapStr(char* j, char* J, int width) {
|
||||||
|
int i;
|
||||||
|
char tmp;
|
||||||
|
for (i = 0; i < width; i++) {
|
||||||
|
tmp = *j;
|
||||||
|
*j = *J;
|
||||||
|
*J = tmp;
|
||||||
|
j++;
|
||||||
|
J++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
int64_t i, j;
|
||||||
|
for (i = 0; i < sz - 1; i++) {
|
||||||
|
for (j = 0; j < sz - 1 - i; j++) {
|
||||||
|
if (compar((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0.00) {
|
||||||
|
swapStr((char*)arr + j * width, (char*)arr + (j + 1) * width, width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
qsort(arr, sz, width, compar);
|
||||||
|
#endif
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue