diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 920eb0c01d..32e9b11520 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -127,6 +127,25 @@ def pre_test(){ ''' return 1 } +def pre_test_build_mac() { + sh ''' + hostname + date + ''' + sh ''' + cd ${WK} + rm -rf debug + mkdir debug + ''' + sh ''' + cd ${WK}/debug + cmake .. + make -j8 + ''' + sh ''' + date + ''' +} def pre_test_win(){ bat ''' hostname @@ -334,6 +353,17 @@ pipeline { } } } + stage('mac test') { + agent{label " Mac_catalina "} + steps { + catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { + timeout(time: 20, unit: 'MINUTES'){ + pre_test() + pre_test_build_mac() + } + } + } + } stage('linux test') { agent{label " worker03 || slave215 || slave217 || slave219 "} options { skipDefaultCheckout() } diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 51b8ee2a00..dc128376e4 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -708,6 +708,7 @@ typedef struct { int32_t buffer; // MB int32_t pageSize; int32_t pages; + int32_t lastRowMem; int32_t daysPerFile; int32_t daysToKeep0; int32_t daysToKeep1; @@ -736,6 +737,7 @@ typedef struct { int32_t buffer; int32_t pageSize; int32_t pages; + int32_t lastRowMem; int32_t daysPerFile; int32_t daysToKeep0; int32_t daysToKeep1; @@ -1023,8 +1025,10 @@ typedef struct { int64_t clusterId; int64_t rebootTime; int64_t updateTime; - int32_t numOfCores; + float numOfCores; int32_t numOfSupportVnodes; + int64_t memTotal; + int64_t memAvail; char dnodeEp[TSDB_EP_LEN]; SMnodeLoad mload; SQnodeLoad qload; @@ -1079,6 +1083,7 @@ typedef struct { int32_t buffer; int32_t pageSize; int32_t pages; + int32_t lastRowMem; int32_t daysPerFile; int32_t daysToKeep0; int32_t daysToKeep1; @@ -1131,6 +1136,7 @@ typedef struct { int32_t buffer; int32_t pageSize; int32_t pages; + int32_t lastRowMem; int32_t daysPerFile; int32_t daysToKeep0; int32_t daysToKeep1; diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index bfcaeeb59c..9d09861b8e 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -37,9 +37,6 @@ typedef struct SReadHandle { void* mnd; SMsgCb* pMsgCb; - /* XXXXXXXXXXXXXXXXXXXX */ - int32_t deleteQuery; - /* XXXXXXXXXXXXXXXXXXXX */ // int8_t initTsdbReader; bool tqReader; } SReadHandle; diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 0b71cec888..f1891c3764 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -22,8 +22,8 @@ extern "C" { #include "tdef.h" -#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type) -#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type)) +#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type) +#define setNodeType(nodeptr, nodetype) (((SNode*)(nodeptr))->type = (nodetype)) #define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0) @@ -119,6 +119,7 @@ typedef enum ENodeType { QUERY_NODE_DROP_TABLE_STMT, QUERY_NODE_DROP_SUPER_TABLE_STMT, QUERY_NODE_ALTER_TABLE_STMT, + QUERY_NODE_ALTER_SUPER_TABLE_STMT, QUERY_NODE_CREATE_USER_STMT, QUERY_NODE_ALTER_USER_STMT, QUERY_NODE_DROP_USER_STMT, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 3558e04bbf..b71fac459d 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -320,6 +320,7 @@ typedef struct SInterpFuncPhysiNode { SNodeList* pFuncs; STimeWindow timeRange; int64_t interval; + int8_t intervalUnit; EFillMode fillMode; SNode* pFillValues; // SNodeListNode SNode* pTimeSeries; // SColumnNode diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index 555274599a..aaebffa118 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -25,6 +25,8 @@ extern "C" { typedef struct SFilterInfo SFilterInfo; +int32_t scalarGetOperatorResultType(SDataType left, SDataType right, EOperatorType op, SDataType* pRes); + /* pNode will be freed in API; *pRes need to freed in caller diff --git a/include/libs/scheduler/scheduler.h b/include/libs/scheduler/scheduler.h index be3d16ab0d..1c73b2c2c8 100644 --- a/include/libs/scheduler/scheduler.h +++ b/include/libs/scheduler/scheduler.h @@ -130,7 +130,7 @@ void schedulerStopQueryHb(void *pTrans); * Free the query job * @param pJob */ -void schedulerFreeJob(int64_t job, int32_t errCode); +void schedulerFreeJob(int64_t* job, int32_t errCode); void schedulerDestroy(void); diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index d07cf0adf1..a93b359ef3 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -31,6 +31,12 @@ extern bool gRaftDetailLog; #define SYNC_INDEX_INVALID -1 #define SYNC_TERM_INVALID 0xFFFFFFFFFFFFFFFF +typedef enum { + SYNC_STRATEGY_NO_SNAPSHOT = 0, + SYNC_STRATEGY_STANDARD_SNAPSHOT = 1, + SYNC_STRATEGY_WAL_FIRST = 2, +} ESyncStrategy; + typedef uint64_t SyncNodeId; typedef int32_t SyncGroupId; typedef int64_t SyncIndex; @@ -48,11 +54,6 @@ typedef enum { TAOS_SYNC_STATE_ERROR = 103, } ESyncState; -typedef enum { - TAOS_SYNC_FSM_CB_SUCCESS = 0, - TAOS_SYNC_FSM_CB_OTHER_ERROR = 1, -} ESyncFsmCbCode; - typedef struct SNodeInfo { uint16_t nodePort; char nodeFqdn[TSDB_FQDN_LEN]; @@ -96,6 +97,11 @@ typedef struct SReConfigCbMeta { } SReConfigCbMeta; +typedef struct SSnapshotParam { + SyncIndex start; + SyncIndex end; +} SSnapshotParam; + typedef struct SSnapshot { void* data; SyncIndex lastApplyIndex; @@ -125,7 +131,7 @@ typedef struct SSyncFSM { int32_t (*FpSnapshotStopRead)(struct SSyncFSM* pFsm, void* pReader); int32_t (*FpSnapshotDoRead)(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len); - int32_t (*FpSnapshotStartWrite)(struct SSyncFSM* pFsm, void** ppWriter); + int32_t (*FpSnapshotStartWrite)(struct SSyncFSM* pFsm, void* pWriterParam, void** ppWriter); int32_t (*FpSnapshotStopWrite)(struct SSyncFSM* pFsm, void* pWriter, bool isApply); int32_t (*FpSnapshotDoWrite)(struct SSyncFSM* pFsm, void* pWriter, void* pBuf, int32_t len); @@ -178,15 +184,15 @@ typedef struct SSyncLogStore { } SSyncLogStore; typedef struct SSyncInfo { - bool isStandBy; - bool snapshotEnable; - SyncGroupId vgId; - int32_t batchSize; - SSyncCfg syncCfg; - char path[TSDB_FILENAME_LEN]; - SWal* pWal; - SSyncFSM* pFsm; - SMsgCb* msgcb; + bool isStandBy; + ESyncStrategy snapshotStrategy; + SyncGroupId vgId; + int32_t batchSize; + SSyncCfg syncCfg; + char path[TSDB_FILENAME_LEN]; + SWal* pWal; + SSyncFSM* pFsm; + SMsgCb* msgcb; int32_t (*FpSendMsg)(const SEpSet* pEpSet, SRpcMsg* pMsg); int32_t (*FpEqMsg)(const SMsgCb* msgcb, SRpcMsg* pMsg); } SSyncInfo; @@ -205,7 +211,7 @@ SyncGroupId syncGetVgId(int64_t rid); void syncGetEpSet(int64_t rid, SEpSet* pEpSet); void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet); int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak); -// int32_t syncProposeBatch(int64_t rid, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize); +int32_t syncProposeBatch(int64_t rid, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize); bool syncEnvIsStart(); const char* syncStr(ESyncState state); bool syncIsRestoreFinish(int64_t rid); diff --git a/include/libs/sync/syncTools.h b/include/libs/sync/syncTools.h index 745c63d5b3..7e95623740 100644 --- a/include/libs/sync/syncTools.h +++ b/include/libs/sync/syncTools.h @@ -191,12 +191,12 @@ void syncTimeoutLog2(char* s, const SyncTimeout* pMsg); typedef struct SyncClientRequest { uint32_t bytes; int32_t vgId; - uint32_t msgType; // SyncClientRequest msgType - uint32_t originalRpcType; // user RpcMsg msgType + uint32_t msgType; // TDMT_SYNC_CLIENT_REQUEST + uint32_t originalRpcType; // origin RpcMsg msgType uint64_t seqNum; bool isWeak; - uint32_t dataLen; // user RpcMsg.contLen - char data[]; // user RpcMsg.pCont + uint32_t dataLen; // origin RpcMsg.contLen + char data[]; // origin RpcMsg.pCont } SyncClientRequest; SyncClientRequest* syncClientRequestBuild(uint32_t dataLen); @@ -220,11 +220,6 @@ void syncClientRequestLog(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; @@ -232,20 +227,33 @@ typedef struct SRaftMeta { // block1: // block2: SRaftMeta array -// block3: rpc msg array (with pCont) +// block3: rpc msg array (with pCont pointer) typedef struct SyncClientRequestBatch { uint32_t bytes; int32_t vgId; - uint32_t msgType; // SyncClientRequestBatch msgType + uint32_t msgType; // TDMT_SYNC_CLIENT_REQUEST_BATCH uint32_t dataCount; - uint32_t dataLen; // user RpcMsg.contLen - char data[]; // user RpcMsg.pCont + uint32_t dataLen; + char data[]; // block2, block3 } SyncClientRequestBatch; SyncClientRequestBatch* syncClientRequestBatchBuild(SRpcMsg* rpcMsgArr, SRaftMeta* raftArr, int32_t arrSize, int32_t vgId); void syncClientRequestBatch2RpcMsg(const SyncClientRequestBatch* pSyncMsg, SRpcMsg* pRpcMsg); +void syncClientRequestBatchDestroy(SyncClientRequestBatch* pMsg); +void syncClientRequestBatchDestroyDeep(SyncClientRequestBatch* pMsg); +SRaftMeta* syncClientRequestBatchMetaArr(const SyncClientRequestBatch* pSyncMsg); +SRpcMsg* syncClientRequestBatchRpcMsgArr(const SyncClientRequestBatch* pSyncMsg); +SyncClientRequestBatch* syncClientRequestBatchFromRpcMsg(const SRpcMsg* pRpcMsg); +cJSON* syncClientRequestBatch2Json(const SyncClientRequestBatch* pMsg); +char* syncClientRequestBatch2Str(const SyncClientRequestBatch* pMsg); + +// for debug ---------------------- +void syncClientRequestBatchPrint(const SyncClientRequestBatch* pMsg); +void syncClientRequestBatchPrint2(char* s, const SyncClientRequestBatch* pMsg); +void syncClientRequestBatchLog(const SyncClientRequestBatch* pMsg); +void syncClientRequestBatchLog2(char* s, const SyncClientRequestBatch* pMsg); // --------------------------------------------- typedef struct SyncClientRequestReply { @@ -318,12 +326,15 @@ void syncRequestVoteReplyLog(const SyncRequestVoteReply* pMsg); void syncRequestVoteReplyLog2(char* s, const SyncRequestVoteReply* pMsg); // --------------------------------------------- +// data: entry + typedef struct SyncAppendEntries { uint32_t bytes; int32_t vgId; uint32_t msgType; SRaftId srcId; SRaftId destId; + // private data SyncTerm term; SyncIndex prevLogIndex; @@ -354,18 +365,14 @@ 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 +// data: +// block1: SOffsetAndContLen Array +// block2: entry Array typedef struct SyncAppendEntriesBatch { uint32_t bytes; @@ -382,10 +389,11 @@ typedef struct SyncAppendEntriesBatch { SyncTerm privateTerm; int32_t dataCount; uint32_t dataLen; - char data[]; + char data[]; // block1, block2 } SyncAppendEntriesBatch; -SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SRpcMsg* rpcMsgArr, int32_t arrSize, int32_t vgId); +SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SSyncRaftEntry** entryPArr, int32_t arrSize, int32_t vgId); +SOffsetAndContLen* syncAppendEntriesBatchMetaTableArray(SyncAppendEntriesBatch* pMsg); void syncAppendEntriesBatchDestroy(SyncAppendEntriesBatch* pMsg); void syncAppendEntriesBatchSerialize(const SyncAppendEntriesBatch* pMsg, char* buf, uint32_t bufLen); void syncAppendEntriesBatchDeserialize(const char* buf, uint32_t len, SyncAppendEntriesBatch* pMsg); @@ -396,8 +404,6 @@ void syncAppendEntriesBatchFromRpcMsg(const SRpcMsg* pRpcMsg, 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); @@ -477,9 +483,10 @@ typedef struct SyncSnapshotSend { SRaftId destId; SyncTerm term; - SyncIndex lastIndex; // lastIndex of snapshot - SyncTerm lastTerm; // lastTerm of snapshot - SyncIndex lastConfigIndex; + SyncIndex beginIndex; // snapshot.beginIndex + SyncIndex lastIndex; // snapshot.lastIndex + SyncTerm lastTerm; // snapshot.lastTerm + SyncIndex lastConfigIndex; // snapshot.lastConfigIndex SSyncCfg lastConfig; SyncTerm privateTerm; int32_t seq; @@ -617,6 +624,9 @@ int32_t syncNodeOnRequestVoteReplySnapshotCb(SSyncNode* ths, SyncRequestVoteRepl int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg); int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg); +int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatch* pMsg); +int32_t syncNodeOnAppendEntriesReplySnapshot2Cb(SSyncNode* ths, SyncAppendEntriesReply* pMsg); + int32_t syncNodeOnSnapshotSendCb(SSyncNode* ths, SyncSnapshotSend* pMsg); int32_t syncNodeOnSnapshotRspCb(SSyncNode* ths, SyncSnapshotRsp* pMsg); @@ -633,7 +643,8 @@ typedef int32_t (*FpOnSnapshotSendCb)(SSyncNode* ths, SyncSnapshotSend* pMsg); typedef int32_t (*FpOnSnapshotRspCb)(SSyncNode* ths, SyncSnapshotRsp* pMsg); // option ---------------------------------- -bool syncNodeSnapshotEnable(SSyncNode* pSyncNode); +bool syncNodeSnapshotEnable(SSyncNode* pSyncNode); +ESyncStrategy syncNodeStrategy(SSyncNode* pSyncNode); // --------------------------------------------- diff --git a/include/libs/transport/trpc.h b/include/libs/transport/trpc.h index 8471aa8286..48550b890a 100644 --- a/include/libs/transport/trpc.h +++ b/include/libs/transport/trpc.h @@ -110,12 +110,15 @@ typedef struct { } SRpcCtx; int32_t rpcInit(); -void rpcCleanup(); -void * rpcOpen(const SRpcInit *pRpc); -void rpcClose(void *); -void * rpcMallocCont(int32_t contLen); -void rpcFreeCont(void *pCont); -void * rpcReallocCont(void *ptr, int32_t contLen); + +void rpcCleanup(); +void *rpcOpen(const SRpcInit *pRpc); + +void rpcClose(void *); +void rpcCloseImpl(void *); +void *rpcMallocCont(int32_t contLen); +void rpcFreeCont(void *pCont); +void *rpcReallocCont(void *ptr, int32_t contLen); // Because taosd supports multi-process mode // These functions should not be used on the server side diff --git a/include/util/tRealloc.h b/include/util/tRealloc.h index c051369488..8d40f6cc5d 100644 --- a/include/util/tRealloc.h +++ b/include/util/tRealloc.h @@ -38,7 +38,7 @@ static FORCE_INLINE int32_t tRealloc(uint8_t **ppBuf, int64_t size) { bsize *= 2; } - pBuf = taosMemoryRealloc(*ppBuf ? (*ppBuf) - sizeof(int64_t) : *ppBuf, bsize + sizeof(int64_t)); + pBuf = (uint8_t *)taosMemoryRealloc(*ppBuf ? (*ppBuf) - sizeof(int64_t) : *ppBuf, bsize + sizeof(int64_t)); if (pBuf == NULL) { code = TSDB_CODE_OUT_OF_MEMORY; goto _exit; @@ -61,4 +61,4 @@ static FORCE_INLINE void tFree(uint8_t *pBuf) { } #endif -#endif /*_TD_UTIL_TREALLOC_H_*/ \ No newline at end of file +#endif /*_TD_UTIL_TREALLOC_H_*/ diff --git a/include/util/taoserror.h b/include/util/taoserror.h index ccc192e601..f23b6950dc 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -174,11 +174,12 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_DNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0341) #define TSDB_CODE_MND_TOO_MANY_DNODES TAOS_DEF_ERROR_CODE(0, 0x0342) #define TSDB_CODE_MND_NO_ENOUGH_DNODES TAOS_DEF_ERROR_CODE(0, 0x0343) -#define TSDB_CODE_MND_INVALID_CLUSTER_CFG TAOS_DEF_ERROR_CODE(0, 0x0344) -#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x0345) -#define TSDB_CODE_MND_INVALID_DNODE_CFG TAOS_DEF_ERROR_CODE(0, 0x0346) -#define TSDB_CODE_MND_INVALID_DNODE_EP TAOS_DEF_ERROR_CODE(0, 0x0347) -#define TSDB_CODE_MND_INVALID_DNODE_ID TAOS_DEF_ERROR_CODE(0, 0x0348) +#define TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0344) +#define TSDB_CODE_MND_INVALID_CLUSTER_CFG TAOS_DEF_ERROR_CODE(0, 0x0345) +#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x0346) +#define TSDB_CODE_MND_INVALID_DNODE_CFG TAOS_DEF_ERROR_CODE(0, 0x0347) +#define TSDB_CODE_MND_INVALID_DNODE_EP TAOS_DEF_ERROR_CODE(0, 0x0348) +#define TSDB_CODE_MND_INVALID_DNODE_ID TAOS_DEF_ERROR_CODE(0, 0x0349) // mnode-node #define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0350) @@ -429,6 +430,7 @@ int32_t* taosGetErrno(); #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_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913) +#define TSDB_CODE_SYN_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x0914) #define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF) // tq @@ -579,6 +581,7 @@ int32_t* taosGetErrno(); #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_NO_VALID_FUNC_IN_WIN TAOS_DEF_ERROR_CODE(0, 0x265E) +#define TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE TAOS_DEF_ERROR_CODE(0, 0x265F) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/include/util/tdef.h b/include/util/tdef.h index 7c7413a421..84bc30b9e7 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -334,6 +334,9 @@ typedef enum ELogicConditionType { #define TSDB_MIN_DB_CACHE_LAST_ROW 0 #define TSDB_MAX_DB_CACHE_LAST_ROW 3 #define TSDB_DEFAULT_CACHE_LAST_ROW 0 +#define TSDB_MIN_DB_LAST_ROW_MEM 1 // MB +#define TSDB_MAX_DB_LAST_ROW_MEM 65536 +#define TSDB_DEFAULT_LAST_ROW_MEM 1 #define TSDB_DB_STREAM_MODE_OFF 0 #define TSDB_DB_STREAM_MODE_ON 1 #define TSDB_DEFAULT_DB_STREAM_MODE 0 diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 53292ed46a..b930f57d92 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -65,7 +65,7 @@ enum { typedef struct SAppInstInfo SAppInstInfo; typedef struct { - char* key; + char* key; // statistics int32_t reportCnt; int32_t connKeyCnt; @@ -177,14 +177,14 @@ typedef struct SReqResultInfo { } SReqResultInfo; typedef struct SRequestSendRecvBody { - tsem_t rspSem; // not used now - __taos_async_fn_t queryFp; - __taos_async_fn_t fetchFp; - void* param; - SDataBuf requestMsg; - int64_t queryJob; // query job, created according to sql query DAG. - int32_t subplanNum; - SReqResultInfo resInfo; + tsem_t rspSem; // not used now + __taos_async_fn_t queryFp; + __taos_async_fn_t fetchFp; + void* param; + SDataBuf requestMsg; + int64_t queryJob; // query job, created according to sql query DAG. + int32_t subplanNum; + SReqResultInfo resInfo; } SRequestSendRecvBody; typedef struct { @@ -284,6 +284,7 @@ static FORCE_INLINE SReqResultInfo* tscGetCurResInfo(TAOS_RES* res) { extern SAppInfo appInfo; extern int32_t clientReqRefPool; extern int32_t clientConnRefPool; +extern void* tscQhandle; __async_send_cb_fn_t getMsgRspHandle(int32_t msgType); @@ -301,7 +302,7 @@ void destroyRequest(SRequestObj* pRequest); SRequestObj* acquireRequest(int64_t rid); int32_t releaseRequest(int64_t rid); int32_t removeRequest(int64_t rid); -void doDestroyRequest(void *p); +void doDestroyRequest(void* p); char* getDbOfConnection(STscObj* pObj); void setConnectionDB(STscObj* pTscObj, const char* db); @@ -336,8 +337,9 @@ int hbHandleRsp(SClientHbBatchRsp* hbRsp); // cluster level SAppHbMgr* appHbMgrInit(SAppInstInfo* pAppInstInfo, char* key); void appHbMgrCleanup(void); -void hbRemoveAppHbMrg(SAppHbMgr **pAppHbMgr); -void closeAllRequests(SHashObj *pRequests); +void hbRemoveAppHbMrg(SAppHbMgr** pAppHbMgr); +void destroyAllRequests(SHashObj* pRequests); +void stopAllRequests(SHashObj* pRequests); // conn level int hbRegisterConn(SAppHbMgr* pAppHbMgr, int64_t tscRefId, int64_t clusterId, int8_t connType); @@ -356,6 +358,9 @@ int32_t removeMeta(STscObj* pTscObj, SArray* tbList); // todo move to clie int32_t handleAlterTbExecRes(void* res, struct SCatalog* pCatalog); // todo move to xxx bool qnodeRequired(SRequestObj* pRequest); +void initTscQhandle(); +void cleanupTscQhandle(); + #ifdef __cplusplus } #endif diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index a234311569..797d58e6ef 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -25,6 +25,7 @@ #include "tmsg.h" #include "tref.h" #include "trpc.h" +#include "tsched.h" #include "ttime.h" #define TSC_VAR_NOT_RELEASE 1 @@ -34,9 +35,20 @@ SAppInfo appInfo; int32_t clientReqRefPool = -1; int32_t clientConnRefPool = -1; +void *tscQhandle = NULL; + static TdThreadOnce tscinit = PTHREAD_ONCE_INIT; volatile int32_t tscInitRes = 0; +void initTscQhandle() { + // init handle + tscQhandle = taosInitScheduler(4096, 5, "tsc"); +} + +void cleanupTscQhandle() { + // destroy handle + taosCleanUpScheduler(tscQhandle); +} static int32_t registerRequest(SRequestObj *pRequest) { STscObj *pTscObj = acquireTscObj(pRequest->pTscObj->id); if (NULL == pTscObj) { @@ -121,12 +133,31 @@ void *openTransporter(const char *user, const char *auth, int32_t numOfThread) { return pDnodeConn; } -void closeAllRequests(SHashObj *pRequests) { +void destroyAllRequests(SHashObj *pRequests) { void *pIter = taosHashIterate(pRequests, NULL); while (pIter != NULL) { int64_t *rid = pIter; - removeRequest(*rid); + SRequestObj *pRequest = acquireRequest(*rid); + if (pRequest) { + destroyRequest(pRequest); + releaseRequest(*rid); + } + + pIter = taosHashIterate(pRequests, pIter); + } +} + +void stopAllRequests(SHashObj *pRequests) { + void *pIter = taosHashIterate(pRequests, NULL); + while (pIter != NULL) { + int64_t *rid = pIter; + + SRequestObj *pRequest = acquireRequest(*rid); + if (pRequest) { + taos_stop_query(pRequest); + releaseRequest(*rid); + } pIter = taosHashIterate(pRequests, pIter); } @@ -153,12 +184,18 @@ void destroyAppInst(SAppInstInfo *pAppInfo) { } void destroyTscObj(void *pObj) { + if (NULL == pObj) { + return; + } + STscObj *pTscObj = pObj; + int64_t tscId = pTscObj->id; + tscTrace("begin to destroy tscObj %" PRIx64 " p:%p", tscId, pTscObj); SClientHbKey connKey = {.tscRid = pTscObj->id, .connType = pTscObj->connType}; hbDeregisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey); int64_t connNum = atomic_sub_fetch_64(&pTscObj->pAppInfo->numOfConns, 1); - closeAllRequests(pTscObj->pRequests); + destroyAllRequests(pTscObj->pRequests); schedulerStopQueryHb(pTscObj->pAppInfo->pTransporter); tscDebug("connObj 0x%" PRIx64 " p:%p destroyed, remain inst totalConn:%" PRId64, pTscObj->id, pTscObj, pTscObj->pAppInfo->numOfConns); @@ -167,7 +204,9 @@ void destroyTscObj(void *pObj) { destroyAppInst(pTscObj->pAppInfo); } taosThreadMutexDestroy(&pTscObj->mutex); - taosMemoryFreeClear(pTscObj); + taosMemoryFree(pTscObj); + + tscTrace("end to destroy tscObj %" PRIx64 " p:%p", tscId, pTscObj); } void *createTscObj(const char *user, const char *auth, const char *db, int32_t connType, SAppInstInfo *pAppInfo) { @@ -261,14 +300,18 @@ int32_t releaseRequest(int64_t rid) { return taosReleaseRef(clientReqRefPool, ri int32_t removeRequest(int64_t rid) { return taosRemoveRef(clientReqRefPool, rid); } void doDestroyRequest(void *p) { - assert(p != NULL); + if (NULL == p) { + return; + } + SRequestObj *pRequest = (SRequestObj *)p; + int64_t reqId = pRequest->self; + tscTrace("begin to destroy request %" PRIx64 " p:%p", reqId, pRequest); + taosHashRemove(pRequest->pTscObj->pRequests, &pRequest->self, sizeof(pRequest->self)); - if (pRequest->body.queryJob != 0) { - schedulerFreeJob(pRequest->body.queryJob, 0); - } + schedulerFreeJob(&pRequest->body.queryJob, 0); taosMemoryFreeClear(pRequest->msgBuf); taosMemoryFreeClear(pRequest->sqlstr); @@ -284,7 +327,9 @@ void doDestroyRequest(void *p) { if (pRequest->self) { deregisterRequest(pRequest); } - taosMemoryFreeClear(pRequest); + taosMemoryFree(pRequest); + + tscTrace("end to destroy request %" PRIx64 " p:%p", reqId, pRequest); } void destroyRequest(SRequestObj *pRequest) { @@ -292,6 +337,8 @@ void destroyRequest(SRequestObj *pRequest) { return; } + taos_stop_query(pRequest); + removeRequest(pRequest->self); } @@ -299,7 +346,7 @@ void taos_init_imp(void) { // In the APIs of other program language, taos_cleanup is not available yet. // So, to make sure taos_cleanup will be invoked to clean up the allocated resource to suppress the valgrind warning. atexit(taos_cleanup); - + initTscQhandle(); errno = TSDB_CODE_SUCCESS; taosSeedRand(taosGetTimestampSec()); diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 7d42bbdad9..ff0c2df25e 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -25,6 +25,7 @@ #include "tmsgtype.h" #include "tpagedbuf.h" #include "tref.h" +#include "tsched.h" static int32_t initEpSetFromCfg(const char* firstEp, const char* secondEp, SCorEpSet* pEpSet); static SMsgSendInfo* buildConnectMsg(SRequestObj* pRequest); @@ -56,14 +57,14 @@ static char* getClusterKey(const char* user, const char* auth, const char* ip, i } bool chkRequestKilled(void* param) { - bool killed = false; + bool killed = false; SRequestObj* pRequest = acquireRequest((int64_t)param); if (NULL == pRequest || pRequest->killed) { killed = true; } releaseRequest((int64_t)param); - + return killed; } @@ -645,9 +646,7 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList pRequest->body.resInfo.execRes = res.res; if (code != TSDB_CODE_SUCCESS) { - if (pRequest->body.queryJob != 0) { - schedulerFreeJob(pRequest->body.queryJob, 0); - } + schedulerFreeJob(&pRequest->body.queryJob, 0); pRequest->code = code; terrno = code; @@ -658,9 +657,7 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList TDMT_VND_CREATE_TABLE == pRequest->type) { pRequest->body.resInfo.numOfRows = res.numOfRows; - if (pRequest->body.queryJob != 0) { - schedulerFreeJob(pRequest->body.queryJob, 0); - } + schedulerFreeJob(&pRequest->body.queryJob, 0); } pRequest->code = res.code; @@ -769,7 +766,7 @@ int32_t handleQueryExecRsp(SRequestObj* pRequest) { code = handleSubmitExecRes(pRequest, pRes->res, pCatalog, &epset); break; } - case TDMT_SCH_QUERY: + case TDMT_SCH_QUERY: case TDMT_SCH_MERGE_QUERY: { code = handleQueryExecRes(pRequest, pRes->res, pCatalog, &epset); break; @@ -792,10 +789,7 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) { TDMT_VND_CREATE_TABLE == pRequest->type) { pRequest->body.resInfo.numOfRows = pResult->numOfRows; - if (pRequest->body.queryJob != 0) { - schedulerFreeJob(pRequest->body.queryJob, 0); - pRequest->body.queryJob = 0; - } + schedulerFreeJob(&pRequest->body.queryJob, 0); } taosMemoryFree(pResult); @@ -1239,7 +1233,16 @@ void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg, } } -void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { +typedef struct SchedArg { + SRpcMsg msg; + SEpSet* pEpset; +} SchedArg; + +void doProcessMsgFromServer(SSchedMsg* schedMsg) { + SchedArg* arg = (SchedArg*)schedMsg->ahandle; + SRpcMsg* pMsg = &arg->msg; + SEpSet* pEpSet = arg->pEpset; + SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->info.ahandle; assert(pMsg->info.ahandle != NULL); STscObj* pTscObj = NULL; @@ -1272,7 +1275,8 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { updateTargetEpSet(pSendInfo, pTscObj, pMsg, pEpSet); - SDataBuf buf = {.msgType = pMsg->msgType, .len = pMsg->contLen, .pData = NULL, .handle = pMsg->info.handle, .pEpSet = pEpSet}; + SDataBuf buf = { + .msgType = pMsg->msgType, .len = pMsg->contLen, .pData = NULL, .handle = pMsg->info.handle, .pEpSet = pEpSet}; if (pMsg->contLen > 0) { buf.pData = taosMemoryCalloc(1, pMsg->contLen); @@ -1287,6 +1291,25 @@ void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { pSendInfo->fp(pSendInfo->param, &buf, pMsg->code); rpcFreeCont(pMsg->pCont); destroySendMsgInfo(pSendInfo); + + taosMemoryFree(arg); +} + +void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) { + SSchedMsg schedMsg = {0}; + + SEpSet* tEpSet = pEpSet != NULL ? taosMemoryCalloc(1, sizeof(SEpSet)) : NULL; + if (tEpSet != NULL) { + *tEpSet = *pEpSet; + } + + SchedArg* arg = taosMemoryCalloc(1, sizeof(SchedArg)); + arg->msg = *pMsg; + arg->pEpset = tEpSet; + + schedMsg.fp = doProcessMsgFromServer; + schedMsg.ahandle = arg; + taosScheduleTask(tscQhandle, &schedMsg); } TAOS* taos_connect_auth(const char* ip, const char* user, const char* auth, const char* db, uint16_t port) { @@ -1415,7 +1438,7 @@ void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertU pParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam)); tsem_init(&pParam->sem, 0, 0); } - + // convert ucs4 to native multi-bytes string pResultInfo->convertUcs4 = convertUcs4; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index d8a9ce581a..136ee34950 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -47,11 +47,9 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) { atomic_store_32(&lock, 0); return ret; } - // this function may be called by user or system, or by both simultaneously. void taos_cleanup(void) { - tscInfo("start to cleanup client environment"); - + tscInfo("start to cleanup client environment"); if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) { return; } @@ -74,8 +72,8 @@ void taos_cleanup(void) { catalogDestroy(); schedulerDestroy(); + cleanupTscQhandle(); rpcCleanup(); - tscInfo("all local resources released"); taosCleanupCfg(); taosCloseLog(); @@ -108,7 +106,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha if (pObj) { int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t)); *rid = pObj->id; - return (TAOS*)rid; + return (TAOS *)rid; } return NULL; @@ -196,10 +194,10 @@ void taos_kill_query(TAOS *taos) { if (NULL == taos) { return; } - int64_t rid = *(int64_t*)taos; - - STscObj* pTscObj = acquireTscObj(rid); - closeAllRequests(pTscObj->pRequests); + + int64_t rid = *(int64_t *)taos; + STscObj *pTscObj = acquireTscObj(rid); + stopAllRequests(pTscObj->pRequests); releaseTscObj(rid); } @@ -244,7 +242,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { #endif } else if (TD_RES_TMQ(res)) { - SMqRspObj *msg = ((SMqRspObj *)res); + SMqRspObj * msg = ((SMqRspObj *)res); SReqResultInfo *pResultInfo; if (msg->resIter == -1) { pResultInfo = tmqGetNextResInfo(res, true); @@ -420,7 +418,7 @@ int taos_affected_rows(TAOS_RES *res) { return 0; } - SRequestObj *pRequest = (SRequestObj *)res; + SRequestObj * pRequest = (SRequestObj *)res; SReqResultInfo *pResInfo = &pRequest->body.resInfo; return pResInfo->numOfRows; } @@ -480,9 +478,7 @@ void taos_stop_query(TAOS_RES *res) { return; } - if (pRequest->body.queryJob) { - schedulerFreeJob(pRequest->body.queryJob, TSDB_CODE_TSC_QUERY_KILLED); - } + schedulerFreeJob(&pRequest->body.queryJob, TSDB_CODE_TSC_QUERY_KILLED); tscDebug("request %" PRIx64 " killed", pRequest->requestId); } @@ -606,7 +602,7 @@ int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) { } SReqResultInfo *pResInfo = tscGetCurResInfo(res); - TAOS_FIELD *pField = &pResInfo->userFields[columnIndex]; + TAOS_FIELD * pField = &pResInfo->userFields[columnIndex]; if (!IS_VAR_DATA_TYPE(pField->type)) { return 0; } @@ -650,8 +646,8 @@ const char *taos_get_server_info(TAOS *taos) { typedef struct SqlParseWrapper { SParseContext *pCtx; SCatalogReq catalogReq; - SRequestObj *pRequest; - SQuery *pQuery; + SRequestObj * pRequest; + SQuery * pQuery; } SqlParseWrapper; static void destorySqlParseWrapper(SqlParseWrapper *pWrapper) { @@ -672,8 +668,8 @@ void retrieveMetaCallback(SMetaData *pResultMeta, void *param, int32_t code) { tscDebug("enter meta callback, code %s", tstrerror(code)); SqlParseWrapper *pWrapper = (SqlParseWrapper *)param; - SQuery *pQuery = pWrapper->pQuery; - SRequestObj *pRequest = pWrapper->pRequest; + SQuery * pQuery = pWrapper->pQuery; + SRequestObj * pRequest = pWrapper->pRequest; if (code == TSDB_CODE_SUCCESS) { code = qAnalyseSqlSemantic(pWrapper->pCtx, &pWrapper->catalogReq, pResultMeta, pQuery); @@ -722,31 +718,29 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt) { return TSDB_CODE_OUT_OF_MEMORY; } - **pCxt = (SParseContext){ - .requestId = pRequest->requestId, - .requestRid = pRequest->self, - .acctId = pTscObj->acctId, - .db = pRequest->pDb, - .topicQuery = false, - .pSql = pRequest->sqlstr, - .sqlLen = pRequest->sqlLen, - .pMsg = pRequest->msgBuf, - .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, - .pTransporter = pTscObj->pAppInfo->pTransporter, - .pStmtCb = NULL, - .pUser = pTscObj->user, - .schemalessType = pTscObj->schemalessType, - .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)), - .async = true, - .svrVer = pTscObj->sVer, - .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes) - }; + **pCxt = (SParseContext){.requestId = pRequest->requestId, + .requestRid = pRequest->self, + .acctId = pTscObj->acctId, + .db = pRequest->pDb, + .topicQuery = false, + .pSql = pRequest->sqlstr, + .sqlLen = pRequest->sqlLen, + .pMsg = pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, + .pTransporter = pTscObj->pAppInfo->pTransporter, + .pStmtCb = NULL, + .pUser = pTscObj->user, + .schemalessType = pTscObj->schemalessType, + .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)), + .async = true, + .svrVer = pTscObj->sVer, + .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes)}; return TSDB_CODE_SUCCESS; } void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) { SParseContext *pCxt = NULL; - STscObj *pTscObj = pRequest->pTscObj; + STscObj * pTscObj = pRequest->pTscObj; int32_t code = 0; if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) { @@ -911,10 +905,10 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { return terrno; } - int64_t rid = *(int64_t*)taos; + int64_t rid = *(int64_t *)taos; const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024; // 12MB list int32_t code = 0; - SRequestObj *pRequest = NULL; + SRequestObj * pRequest = NULL; SCatalogReq catalogReq = {0}; if (NULL == tableNameList) { diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index b72fd961f5..bca740e9ce 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -895,7 +895,7 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) { SBlockOrderInfo* pOrder = taosArrayGet(pOrderInfo, 0); int64_t p0 = taosGetTimestampUs(); - + __compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order); taosSort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn); @@ -923,8 +923,9 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) { pInfo->pColData = taosArrayGet(pDataBlock->pDataBlock, pInfo->slotId); } + terrno = 0; taosqsort(index, rows, sizeof(int32_t), &helper, dataBlockCompar); - if(terrno) return terrno; + if (terrno) return terrno; int64_t p1 = taosGetTimestampUs(); @@ -1438,21 +1439,21 @@ static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) { } } -static int32_t colDataMoveVarData(SColumnInfoData* pColInfoData, size_t start, size_t end){ +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){ + while (beigin < end) { int32_t offset = pColInfoData->varmeta.offset[beigin]; - if(offset == -1) { + if (offset == -1) { beigin++; continue; } - if(start != 0) { + if (start != 0) { pColInfoData->varmeta.offset[beigin] = dataLen; } - char *data = pColInfoData->pData + offset; - if(dataOffset == -1) dataOffset = offset; // mark the begin of data + 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); @@ -1461,7 +1462,7 @@ static int32_t colDataMoveVarData(SColumnInfoData* pColInfoData, size_t start, s } beigin++; } - if(dataOffset > 0){ + if (dataOffset > 0) { memmove(pColInfoData->pData, pColInfoData->pData + dataOffset, dataLen); memmove(pColInfoData->varmeta.offset, &pColInfoData->varmeta.offset[start], (end - start) * sizeof(int32_t)); } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 53b4f141ea..192a41a70e 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -947,8 +947,10 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { if (tEncodeI64(&encoder, pReq->clusterId) < 0) return -1; if (tEncodeI64(&encoder, pReq->rebootTime) < 0) return -1; if (tEncodeI64(&encoder, pReq->updateTime) < 0) return -1; - if (tEncodeI32(&encoder, pReq->numOfCores) < 0) return -1; + if (tEncodeFloat(&encoder, pReq->numOfCores) < 0) return -1; if (tEncodeI32(&encoder, pReq->numOfSupportVnodes) < 0) return -1; + if (tEncodeI64(&encoder, pReq->memTotal) < 0) return -1; + if (tEncodeI64(&encoder, pReq->memAvail) < 0) return -1; if (tEncodeCStr(&encoder, pReq->dnodeEp) < 0) return -1; // cluster cfg @@ -1008,8 +1010,10 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { if (tDecodeI64(&decoder, &pReq->clusterId) < 0) return -1; if (tDecodeI64(&decoder, &pReq->rebootTime) < 0) return -1; if (tDecodeI64(&decoder, &pReq->updateTime) < 0) return -1; - if (tDecodeI32(&decoder, &pReq->numOfCores) < 0) return -1; + if (tDecodeFloat(&decoder, &pReq->numOfCores) < 0) return -1; if (tDecodeI32(&decoder, &pReq->numOfSupportVnodes) < 0) return -1; + if (tDecodeI64(&decoder, &pReq->memTotal) < 0) return -1; + if (tDecodeI64(&decoder, &pReq->memAvail) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->dnodeEp) < 0) return -1; // cluster cfg @@ -1974,6 +1978,7 @@ int32_t tSerializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq) { if (tEncodeI32(&encoder, pReq->buffer) < 0) return -1; if (tEncodeI32(&encoder, pReq->pageSize) < 0) return -1; if (tEncodeI32(&encoder, pReq->pages) < 0) return -1; + if (tEncodeI32(&encoder, pReq->lastRowMem) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysPerFile) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep0) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep1) < 0) return -1; @@ -2015,6 +2020,7 @@ int32_t tDeserializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq) if (tDecodeI32(&decoder, &pReq->buffer) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pageSize) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pages) < 0) return -1; + if (tDecodeI32(&decoder, &pReq->lastRowMem) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysPerFile) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep0) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep1) < 0) return -1; @@ -2069,6 +2075,7 @@ int32_t tSerializeSAlterDbReq(void *buf, int32_t bufLen, SAlterDbReq *pReq) { if (tEncodeI32(&encoder, pReq->buffer) < 0) return -1; if (tEncodeI32(&encoder, pReq->pageSize) < 0) return -1; if (tEncodeI32(&encoder, pReq->pages) < 0) return -1; + if (tEncodeI32(&encoder, pReq->lastRowMem) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysPerFile) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep0) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep1) < 0) return -1; @@ -2094,6 +2101,7 @@ int32_t tDeserializeSAlterDbReq(void *buf, int32_t bufLen, SAlterDbReq *pReq) { if (tDecodeI32(&decoder, &pReq->buffer) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pageSize) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pages) < 0) return -1; + if (tDecodeI32(&decoder, &pReq->lastRowMem) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysPerFile) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep0) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep1) < 0) return -1; @@ -2679,10 +2687,12 @@ int32_t tDeserializeSDbCfgRsp(void *buf, int32_t bufLen, SDbCfgRsp *pRsp) { if (tDecodeI8(&decoder, &pRsp->strict) < 0) return -1; if (tDecodeI8(&decoder, &pRsp->cacheLastRow) < 0) return -1; if (tDecodeI32(&decoder, &pRsp->numOfRetensions) < 0) return -1; - pRsp->pRetensions = taosArrayInit(pRsp->numOfRetensions, sizeof(SRetention)); - if (pRsp->pRetensions == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; + if (pRsp->numOfRetensions > 0) { + pRsp->pRetensions = taosArrayInit(pRsp->numOfRetensions, sizeof(SRetention)); + if (pRsp->pRetensions == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } } for (int32_t i = 0; i < pRsp->numOfRetensions; ++i) { @@ -3586,6 +3596,7 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR if (tEncodeI32(&encoder, pReq->buffer) < 0) return -1; if (tEncodeI32(&encoder, pReq->pageSize) < 0) return -1; if (tEncodeI32(&encoder, pReq->pages) < 0) return -1; + if (tEncodeI32(&encoder, pReq->lastRowMem) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysPerFile) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep0) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep1) < 0) return -1; @@ -3643,6 +3654,7 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq * if (tDecodeI32(&decoder, &pReq->buffer) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pageSize) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pages) < 0) return -1; + if (tDecodeI32(&decoder, &pReq->lastRowMem) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysPerFile) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep0) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep1) < 0) return -1; @@ -3665,7 +3677,6 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq * SReplica *pReplica = &pReq->replicas[i]; if (tDecodeSReplica(&decoder, pReplica) < 0) return -1; } - if (tDecodeI32(&decoder, &pReq->numOfRetensions) < 0) return -1; pReq->pRetensions = taosArrayInit(pReq->numOfRetensions, sizeof(SRetention)); if (pReq->pRetensions == NULL) { @@ -3768,6 +3779,7 @@ int32_t tSerializeSAlterVnodeReq(void *buf, int32_t bufLen, SAlterVnodeReq *pReq if (tEncodeI32(&encoder, pReq->buffer) < 0) return -1; if (tEncodeI32(&encoder, pReq->pageSize) < 0) return -1; if (tEncodeI32(&encoder, pReq->pages) < 0) return -1; + if (tEncodeI32(&encoder, pReq->lastRowMem) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysPerFile) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep0) < 0) return -1; if (tEncodeI32(&encoder, pReq->daysToKeep1) < 0) return -1; @@ -3782,7 +3794,6 @@ int32_t tSerializeSAlterVnodeReq(void *buf, int32_t bufLen, SAlterVnodeReq *pReq SReplica *pReplica = &pReq->replicas[i]; if (tEncodeSReplica(&encoder, pReplica) < 0) return -1; } - tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -3799,6 +3810,7 @@ int32_t tDeserializeSAlterVnodeReq(void *buf, int32_t bufLen, SAlterVnodeReq *pR if (tDecodeI32(&decoder, &pReq->buffer) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pageSize) < 0) return -1; if (tDecodeI32(&decoder, &pReq->pages) < 0) return -1; + if (tDecodeI32(&decoder, &pReq->lastRowMem) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysPerFile) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep0) < 0) return -1; if (tDecodeI32(&decoder, &pReq->daysToKeep1) < 0) return -1; diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c index 234a133243..59b442881a 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c @@ -67,6 +67,8 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) { req.updateTime = pMgmt->pData->updateTime; req.numOfCores = tsNumOfCores; req.numOfSupportVnodes = tsNumOfSupportVnodes; + req.memTotal = tsTotalMemoryKB * 1024; + req.memAvail = req.memTotal - tsRpcQueueMemoryAllowed - 16 * 1024 * 1024; tstrncpy(req.dnodeEp, tsLocalEp, TSDB_EP_LEN); req.clusterCfg.statusInterval = tsStatusInterval; diff --git a/source/dnode/mgmt/node_mgmt/src/dmProc.c b/source/dnode/mgmt/node_mgmt/src/dmProc.c index 72878d0d85..cbf13924d7 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmProc.c +++ b/source/dnode/mgmt/node_mgmt/src/dmProc.c @@ -87,8 +87,8 @@ static SProcQueue *dmInitProcQueue(SProc *proc, char *ptr, int32_t size) { static void dmCleanupProcQueue(SProcQueue *queue) {} static inline int32_t dmPushToProcQueue(SProc *proc, SProcQueue *queue, SRpcMsg *pMsg, EProcFuncType ftype) { - const void *pHead = pMsg; - const void *pBody = pMsg->pCont; + const void * pHead = pMsg; + const void * pBody = pMsg->pCont; const int16_t rawHeadLen = sizeof(SRpcMsg); const int32_t rawBodyLen = pMsg->contLen; const int16_t headLen = CEIL8(rawHeadLen); @@ -257,7 +257,7 @@ int32_t dmInitProc(struct SMgmtWrapper *pWrapper) { proc->wrapper = pWrapper; proc->name = pWrapper->name; - SShm *shm = &proc->shm; + SShm * shm = &proc->shm; int32_t cstart = 0; int32_t csize = CEIL8(shm->size / 2); int32_t pstart = csize; @@ -281,13 +281,13 @@ int32_t dmInitProc(struct SMgmtWrapper *pWrapper) { } static void *dmConsumChildQueue(void *param) { - SProc *proc = param; + SProc * proc = param; SMgmtWrapper *pWrapper = proc->wrapper; - SProcQueue *queue = proc->cqueue; + SProcQueue * queue = proc->cqueue; int32_t numOfMsgs = 0; int32_t code = 0; EProcFuncType ftype = DND_FUNC_REQ; - SRpcMsg *pMsg = NULL; + SRpcMsg * pMsg = NULL; dDebug("node:%s, start to consume from cqueue", proc->name); do { @@ -324,13 +324,13 @@ static void *dmConsumChildQueue(void *param) { } static void *dmConsumParentQueue(void *param) { - SProc *proc = param; + SProc * proc = param; SMgmtWrapper *pWrapper = proc->wrapper; - SProcQueue *queue = proc->pqueue; + SProcQueue * queue = proc->pqueue; int32_t numOfMsgs = 0; int32_t code = 0; EProcFuncType ftype = DND_FUNC_REQ; - SRpcMsg *pMsg = NULL; + SRpcMsg * pMsg = NULL; dDebug("node:%s, start to consume from pqueue", proc->name); do { @@ -353,7 +353,7 @@ static void *dmConsumParentQueue(void *param) { rpcRegisterBrokenLinkArg(pMsg); } else if (ftype == DND_FUNC_RELEASE) { dmRemoveProcRpcHandle(proc, pMsg->info.handle); - rpcReleaseHandle(pMsg->info.handle, (int8_t)pMsg->code); + rpcReleaseHandle(&pMsg->info, TAOS_CONN_SERVER); } else { dError("node:%s, invalid ftype:%d from pqueue", proc->name, ftype); rpcFreeCont(pMsg->pCont); diff --git a/source/dnode/mgmt/node_mgmt/src/dmTransport.c b/source/dnode/mgmt/node_mgmt/src/dmTransport.c index 35d478177a..df3c9c4e88 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmTransport.c +++ b/source/dnode/mgmt/node_mgmt/src/dmTransport.c @@ -245,7 +245,7 @@ static inline void dmReleaseHandle(SRpcHandleInfo *pHandle, int8_t type) { SRpcMsg msg = {.code = type, .info = *pHandle}; dmPutToProcPQueue(&pWrapper->proc, &msg, DND_FUNC_RELEASE); } else { - rpcReleaseHandle(pHandle->handle, type); + rpcReleaseHandle(pHandle, type); } } diff --git a/source/dnode/mgmt/node_util/src/dmEps.c b/source/dnode/mgmt/node_util/src/dmEps.c index 096fc753b2..7fe7d44827 100644 --- a/source/dnode/mgmt/node_util/src/dmEps.c +++ b/source/dnode/mgmt/node_util/src/dmEps.c @@ -280,7 +280,7 @@ static void dmPrintEps(SDnodeData *pData) { dDebug("print dnode list, num:%d", numOfEps); for (int32_t i = 0; i < numOfEps; i++) { SDnodeEp *pEp = taosArrayGet(pData->dnodeEps, i); - dDebug("dnode:%d, fqdn:%s port:%u is_mnode:%d", pEp->id, pEp->ep.fqdn, pEp->ep.port, pEp->isMnode); + dDebug("dnode:%d, fqdn:%s port:%u isMnode:%d", pEp->id, pEp->ep.fqdn, pEp->ep.port, pEp->isMnode); } } diff --git a/source/dnode/mgmt/test/sut/src/sut.cpp b/source/dnode/mgmt/test/sut/src/sut.cpp index 21d9351ceb..a5e6128800 100644 --- a/source/dnode/mgmt/test/sut/src/sut.cpp +++ b/source/dnode/mgmt/test/sut/src/sut.cpp @@ -30,12 +30,14 @@ void Testbase::InitLog(const char* path) { tsdbDebugFlag = 0; tsLogEmbedded = 1; tsAsyncLog = 0; - tsRpcQueueMemoryAllowed = 1024 * 1024 * 64; - + taosRemoveDir(path); taosMkDir(path); tstrncpy(tsLogDir, path, PATH_MAX); - if (taosInitLog("taosdlog", 1) != 0) { + + taosGetSystemInfo(); + tsRpcQueueMemoryAllowed = tsTotalMemoryKB * 0.1; +if (taosInitLog("taosdlog", 1) != 0) { printf("failed to init log file\n"); } } diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 21002f5f9c..f39a848992 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -148,7 +148,10 @@ typedef struct { int32_t accessTimes; int32_t numOfVnodes; int32_t numOfSupportVnodes; - int32_t numOfCores; + float numOfCores; + int64_t memTotal; + int64_t memAvail; + int64_t memUsed; EDndReason offlineReason; uint16_t port; char fqdn[TSDB_FQDN_LEN]; @@ -243,6 +246,7 @@ typedef struct { int32_t buffer; int32_t pageSize; int32_t pages; + int32_t lastRowMem; int32_t daysPerFile; int32_t daysToKeep0; int32_t daysToKeep1; @@ -255,8 +259,8 @@ typedef struct { int8_t compression; int8_t replications; int8_t strict; - int8_t cacheLastRow; int8_t hashMethod; // default is 1 + int8_t cacheLastRow; int32_t numOfRetensions; SArray* pRetensions; int8_t schemaless; diff --git a/source/dnode/mnode/impl/inc/mndVgroup.h b/source/dnode/mnode/impl/inc/mndVgroup.h index 6622b89b1d..c8237d17d8 100644 --- a/source/dnode/mnode/impl/inc/mndVgroup.h +++ b/source/dnode/mnode/impl/inc/mndVgroup.h @@ -30,6 +30,8 @@ SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup); SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup); int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId); void mndSortVnodeGid(SVgObj *pVgroup); +int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId); +int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup); SArray *mndBuildDnodesArray(SMnode *, int32_t exceptDnodeId); int32_t mndAllocSmaVgroup(SMnode *, SDbObj *pDb, SVgObj *pVgroup); diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 4f958de121..6770cd578a 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -93,6 +93,7 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb) { SDB_SET_INT32(pRaw, dataPos, pDb->cfg.buffer, _OVER) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.pageSize, _OVER) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.pages, _OVER) + SDB_SET_INT32(pRaw, dataPos, pDb->cfg.lastRowMem, _OVER) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.daysPerFile, _OVER) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.daysToKeep0, _OVER) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.daysToKeep1, _OVER) @@ -165,6 +166,7 @@ static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw) { SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.buffer, _OVER) SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.pageSize, _OVER) SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.pages, _OVER) + SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.lastRowMem, _OVER) SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.daysPerFile, _OVER) SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.daysToKeep0, _OVER) SDB_GET_INT32(pRaw, dataPos, &pDb->cfg.daysToKeep1, _OVER) @@ -230,8 +232,9 @@ static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOld, SDbObj *pNew) { pOld->cfgVersion = pNew->cfgVersion; pOld->vgVersion = pNew->vgVersion; pOld->cfg.buffer = pNew->cfg.buffer; - pOld->cfg.pages = pNew->cfg.pages; pOld->cfg.pageSize = pNew->cfg.pageSize; + pOld->cfg.pages = pNew->cfg.pages; + pOld->cfg.lastRowMem = pNew->cfg.lastRowMem; pOld->cfg.daysPerFile = pNew->cfg.daysPerFile; pOld->cfg.daysToKeep0 = pNew->cfg.daysToKeep0; pOld->cfg.daysToKeep1 = pNew->cfg.daysToKeep1; @@ -288,6 +291,7 @@ static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) { if (pCfg->buffer < TSDB_MIN_BUFFER_PER_VNODE || pCfg->buffer > TSDB_MAX_BUFFER_PER_VNODE) return -1; if (pCfg->pageSize < TSDB_MIN_PAGESIZE_PER_VNODE || pCfg->pageSize > TSDB_MAX_PAGESIZE_PER_VNODE) return -1; if (pCfg->pages < TSDB_MIN_PAGES_PER_VNODE || pCfg->pages > TSDB_MAX_PAGES_PER_VNODE) return -1; + if (pCfg->lastRowMem < TSDB_MIN_DB_LAST_ROW_MEM || pCfg->lastRowMem > TSDB_MAX_DB_LAST_ROW_MEM) return -1; if (pCfg->daysPerFile < TSDB_MIN_DAYS_PER_FILE || pCfg->daysPerFile > TSDB_MAX_DAYS_PER_FILE) return -1; if (pCfg->daysToKeep0 < TSDB_MIN_KEEP || pCfg->daysToKeep0 > TSDB_MAX_KEEP) return -1; if (pCfg->daysToKeep1 < TSDB_MIN_KEEP || pCfg->daysToKeep1 > TSDB_MAX_KEEP) return -1; @@ -336,6 +340,7 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) { if (pCfg->replications < 0) pCfg->replications = TSDB_DEFAULT_DB_REPLICA; if (pCfg->strict < 0) pCfg->strict = TSDB_DEFAULT_DB_STRICT; if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW; + if (pCfg->lastRowMem <= 0) pCfg->lastRowMem = TSDB_DEFAULT_LAST_ROW_MEM; if (pCfg->numOfRetensions < 0) pCfg->numOfRetensions = 0; if (pCfg->schemaless < 0) pCfg->schemaless = TSDB_DB_SCHEMALESS_OFF; } @@ -434,6 +439,7 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate, .buffer = pCreate->buffer, .pageSize = pCreate->pageSize, .pages = pCreate->pages, + .lastRowMem = pCreate->lastRowMem, .daysPerFile = pCreate->daysPerFile, .daysToKeep0 = pCreate->daysToKeep0, .daysToKeep1 = pCreate->daysToKeep1, @@ -475,7 +481,7 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate, int32_t code = -1; STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq); if (pTrans == NULL) goto _OVER; - + // mndTransSetSerial(pTrans); mDebug("trans:%d, used to create db:%s", pTrans->id, pCreate->db); mndTransSetDbName(pTrans, dbObj.name, NULL); @@ -622,6 +628,11 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) { terrno = 0; } + if (pAlter->lastRowMem > 0 && pAlter->lastRowMem != pDb->cfg.lastRowMem) { + pDb->cfg.lastRowMem = pAlter->lastRowMem; + terrno = 0; + } + if (pAlter->replications > 0 && pAlter->replications != pDb->cfg.replications) { #if 1 terrno = TSDB_CODE_OPS_NOT_SUPPORT; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 8198445753..1073ebc316 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -15,8 +15,8 @@ #define _DEFAULT_SOURCE #include "mndDnode.h" -#include "mndPrivilege.h" #include "mndMnode.h" +#include "mndPrivilege.h" #include "mndQnode.h" #include "mndShow.h" #include "mndSnode.h" @@ -432,7 +432,8 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) { } if (!online) { - mInfo("dnode:%d, from offline to online", pDnode->id); + mInfo("dnode:%d, from offline to online, memory avail:%" PRId64 " total:%" PRId64 " cores:%.2f", pDnode->id, + statusReq.memAvail, statusReq.memTotal, statusReq.numOfCores); } else { mDebug("dnode:%d, send dnode epset, online:%d dnodeVer:%" PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online, statusReq.dnodeVer, dnodeVer, reboot); @@ -441,6 +442,8 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) { pDnode->rebootTime = statusReq.rebootTime; pDnode->numOfCores = statusReq.numOfCores; pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes; + pDnode->memAvail = statusReq.memAvail; + pDnode->memTotal = statusReq.memTotal; SStatusRsp statusRsp = {0}; statusRsp.dnodeVer = dnodeVer; @@ -580,7 +583,7 @@ static int32_t mndProcessShowVariablesReq(SRpcMsg *pReq) { strcpy(info.name, "timezone"); snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%s", tsTimezoneStr); taosArrayPush(rsp.variables, &info); - + strcpy(info.name, "locale"); snprintf(info.value, TSDB_CONFIG_VALUE_LEN, "%s", tsLocale); taosArrayPush(rsp.variables, &info); diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index c39c9847a9..bc6830b8f3 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -58,7 +58,7 @@ static void *mndBuildTimerMsg(int32_t *pContLen) { static void mndPullupTrans(SMnode *pMnode) { int32_t contLen = 0; - void * pReq = mndBuildTimerMsg(&contLen); + void *pReq = mndBuildTimerMsg(&contLen); if (pReq != NULL) { SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS_TIMER, .pCont = pReq, .contLen = contLen}; tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); @@ -67,14 +67,14 @@ static void mndPullupTrans(SMnode *pMnode) { static void mndTtlTimer(SMnode *pMnode) { int32_t contLen = 0; - void * pReq = mndBuildTimerMsg(&contLen); + void *pReq = mndBuildTimerMsg(&contLen); SRpcMsg rpcMsg = {.msgType = TDMT_MND_TTL_TIMER, .pCont = pReq, .contLen = contLen}; tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); } static void mndCalMqRebalance(SMnode *pMnode) { int32_t contLen = 0; - void * pReq = mndBuildTimerMsg(&contLen); + void *pReq = mndBuildTimerMsg(&contLen); if (pReq != NULL) { SRpcMsg rpcMsg = {.msgType = TDMT_MND_MQ_TIMER, .pCont = pReq, .contLen = contLen}; tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); @@ -83,7 +83,7 @@ static void mndCalMqRebalance(SMnode *pMnode) { static void mndPullupTelem(SMnode *pMnode) { int32_t contLen = 0; - void * pReq = mndBuildTimerMsg(&contLen); + void *pReq = mndBuildTimerMsg(&contLen); if (pReq != NULL) { SRpcMsg rpcMsg = {.msgType = TDMT_MND_TELEM_TIMER, .pCont = pReq, .contLen = contLen}; tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); @@ -395,7 +395,7 @@ void mndStop(SMnode *pMnode) { } int32_t mndProcessSyncMsg(SRpcMsg *pMsg) { - SMnode * pMnode = pMsg->info.node; + SMnode *pMnode = pMsg->info.node; SSyncMgmt *pMgmt = &pMnode->syncMgmt; int32_t code = 0; @@ -413,7 +413,7 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) { } do { - char * syncNodeStr = sync2SimpleStr(pMgmt->sync); + char *syncNodeStr = sync2SimpleStr(pMgmt->sync); static int64_t mndTick = 0; if (++mndTick % 10 == 1) { mTrace("vgId:%d, sync trace msg:%s, %s", syncGetVgId(pMgmt->sync), TMSG_INFO(pMsg->msgType), syncNodeStr); @@ -427,7 +427,7 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) { } while (0); // ToDo: ugly! use function pointer - if (syncNodeSnapshotEnable(pSyncNode)) { + if (syncNodeStrategy(pSyncNode) == SYNC_STRATEGY_STANDARD_SNAPSHOT) { if (pMsg->msgType == TDMT_SYNC_TIMEOUT) { SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pMsg); code = syncNodeOnTimeoutCb(pSyncNode, pSyncMsg); @@ -579,7 +579,7 @@ static int32_t mndCheckMsgContent(SRpcMsg *pMsg) { } int32_t mndProcessRpcMsg(SRpcMsg *pMsg) { - SMnode * pMnode = pMsg->info.node; + SMnode *pMnode = pMsg->info.node; const STraceId *trace = &pMsg->info.traceId; MndMsgFp fp = pMnode->msgFp[TMSG_INDEX(pMsg->msgType)]; @@ -632,7 +632,7 @@ int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgr SMonStbInfo *pStbInfo, SMonGrantInfo *pGrantInfo) { if (mndAcquireRpcRef(pMnode) != 0) return -1; - SSdb * pSdb = pMnode->pSdb; + SSdb *pSdb = pMnode->pSdb; int64_t ms = taosGetTimestampMs(); pClusterInfo->dnodes = taosArrayInit(sdbGetSize(pSdb, SDB_DNODE), sizeof(SMonDnodeDesc)); @@ -713,7 +713,7 @@ int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgr pGrantInfo->timeseries_used += pVgroup->numOfTimeSeries; tstrncpy(desc.status, "unsynced", sizeof(desc.status)); for (int32_t i = 0; i < pVgroup->replica; ++i) { - SVnodeGid * pVgid = &pVgroup->vnodeGid[i]; + SVnodeGid *pVgid = &pVgroup->vnodeGid[i]; SMonVnodeDesc *pVnDesc = &desc.vnodes[i]; pVnDesc->dnode_id = pVgid->dnodeId; tstrncpy(pVnDesc->vnode_role, syncStr(pVgid->role), sizeof(pVnDesc->vnode_role)); diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 693eed5222..2053f3886c 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -134,7 +134,7 @@ int32_t mndSnapshotDoRead(struct SSyncFSM *pFsm, void *pReader, void **ppBuf, in return sdbDoRead(pMnode->pSdb, pReader, ppBuf, len); } -int32_t mndSnapshotStartWrite(struct SSyncFSM *pFsm, void **ppWriter) { +int32_t mndSnapshotStartWrite(struct SSyncFSM *pFsm, void *pParam, void **ppWriter) { mInfo("start to apply snapshot to sdb"); SMnode *pMnode = pFsm->data; return sdbStartWrite(pMnode->pSdb, (SSdbIter **)ppWriter); @@ -178,7 +178,7 @@ int32_t mndInitSync(SMnode *pMnode) { syncInfo.pWal = pMnode->pWal; syncInfo.pFsm = mndSyncMakeFsm(pMnode); syncInfo.isStandBy = pMgmt->standby; - syncInfo.snapshotEnable = true; + syncInfo.snapshotStrategy = SYNC_STRATEGY_STANDARD_SNAPSHOT; mInfo("start to open mnode sync, standby:%d", pMgmt->standby); if (pMgmt->standby || pMgmt->replica.id > 0) { diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index c53e831e84..3a3331a0b3 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -207,6 +207,7 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg createReq.buffer = pDb->cfg.buffer; createReq.pageSize = pDb->cfg.pageSize; createReq.pages = pDb->cfg.pages; + createReq.lastRowMem = pDb->cfg.lastRowMem; createReq.daysPerFile = pDb->cfg.daysPerFile; createReq.daysToKeep0 = pDb->cfg.daysToKeep0; createReq.daysToKeep1 = pDb->cfg.daysToKeep1; @@ -274,8 +275,9 @@ void *mndBuildAlterVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_ SAlterVnodeReq alterReq = {0}; alterReq.vgVersion = pVgroup->version; alterReq.buffer = pDb->cfg.buffer; - alterReq.pages = pDb->cfg.pages; alterReq.pageSize = pDb->cfg.pageSize; + alterReq.pages = pDb->cfg.pages; + alterReq.lastRowMem = pDb->cfg.lastRowMem; alterReq.daysPerFile = pDb->cfg.daysPerFile; alterReq.daysToKeep0 = pDb->cfg.daysToKeep0; alterReq.daysToKeep1 = pDb->cfg.daysToKeep1; @@ -392,9 +394,10 @@ static bool mndBuildDnodesArrayFp(SMnode *pMnode, void *pObj, void *p1, void *p2 bool online = mndIsDnodeOnline(pDnode, curMs); bool isMnode = mndIsMnode(pMnode, pDnode->id); pDnode->numOfVnodes = mndGetVnodesNum(pMnode, pDnode->id); + pDnode->memUsed = mndGetVnodesMemory(pMnode, pDnode->id); - mDebug("dnode:%d, vnodes:%d support_vnodes:%d is_mnode:%d online:%d", pDnode->id, pDnode->numOfVnodes, - pDnode->numOfSupportVnodes, isMnode, online); + mDebug("dnode:%d, vnodes:%d supportVnodes:%d isMnode:%d online:%d memory avail:%" PRId64 " used:%" PRId64, pDnode->id, + pDnode->numOfVnodes, pDnode->numOfSupportVnodes, isMnode, online, pDnode->memAvail, pDnode->memUsed); if (isMnode) { pDnode->numOfVnodes++; @@ -426,15 +429,7 @@ static int32_t mndCompareDnodeId(int32_t *dnode1Id, int32_t *dnode2Id) { return static int32_t mndCompareDnodeVnodes(SDnodeObj *pDnode1, SDnodeObj *pDnode2) { float d1Score = (float)pDnode1->numOfVnodes / pDnode1->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; -#endif } void mndSortVnodeGid(SVgObj *pVgroup) { @@ -447,7 +442,7 @@ void mndSortVnodeGid(SVgObj *pVgroup) { } } -static int32_t mndGetAvailableDnode(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray) { +static int32_t mndGetAvailableDnode(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) { SSdb *pSdb = pMnode->pSdb; int32_t allocedVnodes = 0; void *pIter = NULL; @@ -470,6 +465,16 @@ static int32_t mndGetAvailableDnode(SMnode *pMnode, SVgObj *pVgroup, SArray *pAr return -1; } + int64_t vgMem = mndGetVgroupMemory(pMnode, pDb, pVgroup); + if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) { + mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d, avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed); + terrno = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE; + return -1; + } else { + pDnode->memUsed += vgMem; + } + pVgid->dnodeId = pDnode->id; if (pVgroup->replica == 1) { pVgid->role = TAOS_SYNC_STATE_LEADER; @@ -477,7 +482,8 @@ static int32_t mndGetAvailableDnode(SMnode *pMnode, SVgObj *pVgroup, SArray *pAr pVgid->role = TAOS_SYNC_STATE_FOLLOWER; } - mInfo("db:%s, vgId:%d, vn:%d dnode:%d is alloced", pVgroup->dbName, pVgroup->vgId, v, pVgid->dnodeId); + mInfo("db:%s, vgId:%d, vn:%d is alloced, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, v, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed); pDnode->numOfVnodes++; } @@ -498,7 +504,7 @@ int32_t mndAllocSmaVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup) { pVgroup->dbUid = pDb->uid; pVgroup->replica = 1; - if (mndGetAvailableDnode(pMnode, pVgroup, pArray) != 0) return -1; + if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) return -1; mInfo("db:%s, sma vgId:%d is alloced", pDb->name, pVgroup->vgId); return 0; @@ -546,8 +552,7 @@ int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups) { pVgroup->dbUid = pDb->uid; pVgroup->replica = pDb->cfg.replications; - if (mndGetAvailableDnode(pMnode, pVgroup, pArray) != 0) { - terrno = TSDB_CODE_MND_NO_ENOUGH_DNODES; + if (mndGetAvailableDnode(pMnode, pDb, pVgroup, pArray) != 0) { goto _OVER; } @@ -728,6 +733,43 @@ int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId) { return numOfVnodes; } +int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) { + SDbObj *pDb = pDbInput; + if (pDbInput == NULL) { + pDb = mndAcquireDb(pMnode, pVgroup->dbName); + } + + int64_t vgroupMemroy = (int64_t)pDb->cfg.buffer * 1024 * 1024 + (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024; + if (pDb->cfg.cacheLastRow > 0) { + vgroupMemroy += (int64_t)pDb->cfg.lastRowMem * 1024 * 1024; + } + + if (pDbInput == NULL) { + mndReleaseDb(pMnode, pDb); + } + return vgroupMemroy; +} + +static bool mndGetVnodeMemroyFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) { + SVgObj *pVgroup = pObj; + int32_t dnodeId = *(int32_t *)p1; + int64_t *pVnodeMemory = (int64_t *)p2; + + for (int32_t v = 0; v < pVgroup->replica; ++v) { + if (pVgroup->vnodeGid[v].dnodeId == dnodeId) { + *pVnodeMemory += mndGetVgroupMemory(pMnode, NULL, pVgroup); + } + } + + return true; +} + +int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) { + int64_t vnodeMemory = 0; + sdbTraverse(pMnode->pSdb, SDB_VGROUP, mndGetVnodeMemroyFp, &dnodeId, &vnodeMemory, NULL); + return vnodeMemory; +} + static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { SMnode *pMnode = pReq->info.node; SSdb *pSdb = pMnode->pSdb; @@ -807,9 +849,20 @@ int32_t mndAddVnodeToVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray) { return -1; } + int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup); + if (pDnode->memAvail - vgMem - pDnode->memUsed <= 0) { + mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vgMem, pDnode->id, pDnode->memAvail, pDnode->memUsed); + terrno = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE; + return -1; + } else { + pDnode->memUsed += vgMem; + } + pVgid->dnodeId = pDnode->id; pVgid->role = TAOS_SYNC_STATE_ERROR; - mInfo("db:%s, vgId:%d, vn:%d dnode:%d, is added", pVgroup->dbName, pVgroup->vgId, pVgroup->replica, pVgid->dnodeId); + mInfo("db:%s, vgId:%d, vn:%d is added, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, pVgroup->replica, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed); pVgroup->replica++; pDnode->numOfVnodes++; @@ -835,7 +888,10 @@ int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray for (int32_t vn = 0; vn < pVgroup->replica; ++vn) { SVnodeGid *pVgid = &pVgroup->vnodeGid[vn]; if (pVgid->dnodeId == pDnode->id) { - mInfo("db:%s, vgId:%d, vn:%d dnode:%d, is removed", pVgroup->dbName, pVgroup->vgId, vn, pVgid->dnodeId); + int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup); + pDnode->memUsed -= vgMem; + mInfo("db:%s, vgId:%d, vn:%d is removed, memory:%" PRId64 ", dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vn, vgMem, pVgid->dnodeId, pDnode->memAvail, pDnode->memUsed); pDnode->numOfVnodes--; pVgroup->replica--; *pDelVgid = *pVgid; @@ -1161,6 +1217,17 @@ static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, terrno = TSDB_CODE_MND_NO_ENOUGH_DNODES; goto _OVER; } + + int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup); + if (pNew1->memAvail - vgMem - pNew1->memUsed <= 0) { + mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vgMem, pNew1->id, pNew1->memAvail, pNew1->memUsed); + terrno = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE; + return -1; + } else { + pNew1->memUsed += vgMem; + } + if (mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew1->id) != 0) goto _OVER; if (mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld1->id) != 0) goto _OVER; } @@ -1173,6 +1240,15 @@ static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, terrno = TSDB_CODE_MND_NO_ENOUGH_DNODES; goto _OVER; } + int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup); + if (pNew2->memAvail - vgMem - pNew2->memUsed <= 0) { + mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vgMem, pNew2->id, pNew2->memAvail, pNew2->memUsed); + terrno = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE; + return -1; + } else { + pNew2->memUsed += vgMem; + } if (mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew2->id) != 0) goto _OVER; if (mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld2->id) != 0) goto _OVER; } @@ -1185,6 +1261,15 @@ static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, terrno = TSDB_CODE_MND_NO_ENOUGH_DNODES; goto _OVER; } + int64_t vgMem = mndGetVgroupMemory(pMnode, NULL, pVgroup); + if (pNew3->memAvail - vgMem - pNew3->memUsed <= 0) { + mError("db:%s, vgId:%d, no enough memory:%" PRId64 " in dnode:%d avail:%" PRId64 " used:%" PRId64, + pVgroup->dbName, pVgroup->vgId, vgMem, pNew3->id, pNew3->memAvail, pNew3->memUsed); + terrno = TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE; + return -1; + } else { + pNew3->memUsed += vgMem; + } if (mndAddIncVgroupReplicaToTrans(pMnode, pTrans, pDb, &newVg, pNew3->id) != 0) goto _OVER; if (mndAddDecVgroupReplicaFromTrans(pMnode, pTrans, pDb, &newVg, pOld3->id) != 0) goto _OVER; } @@ -1415,7 +1500,7 @@ _OVER: mndReleaseDb(pMnode, pDb); return code; -#endif +#endif } int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) { @@ -1654,9 +1739,9 @@ static int32_t mndBalanceVgroupBetweenDnode(SMnode *pMnode, STrans *pTrans, SDno } static int32_t mndBalanceVgroup(SMnode *pMnode, SRpcMsg *pReq, SArray *pArray) { - int32_t code = -1; - int32_t numOfVgroups = 0; - STrans *pTrans = NULL; + int32_t code = -1; + int32_t numOfVgroups = 0; + STrans *pTrans = NULL; SHashObj *pBalancedVgroups = NULL; pBalancedVgroups = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); @@ -1721,7 +1806,7 @@ static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; int32_t code = -1; SArray *pArray = NULL; - void *pIter = NULL; + void *pIter = NULL; int64_t curMs = taosGetTimestampMs(); SBalanceVgroupReq req = {0}; @@ -1766,7 +1851,7 @@ _OVER: taosArrayDestroy(pArray); return code; -#endif +#endif } bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; } \ No newline at end of file diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 499ca635dc..1c29470da3 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -128,7 +128,7 @@ bool tsdbNextDataBlock(STsdbReader *pReader); void tsdbRetrieveDataBlockInfo(STsdbReader *pReader, SDataBlockInfo *pDataBlockInfo); int32_t tsdbRetrieveDataBlockStatisInfo(STsdbReader *pReader, SColumnDataAgg ***pBlockStatis, bool *allHave); SArray *tsdbRetrieveDataBlock(STsdbReader *pTsdbReadHandle, SArray *pColumnIdList); -void tsdbResetReadHandle(STsdbReader *pReader, SQueryTableDataCond *pCond, int32_t tWinIdx); +int32_t tsdbReaderReset(STsdbReader *pReader, SQueryTableDataCond *pCond, int32_t tWinIdx); int32_t tsdbGetFileBlocksDistInfo(STsdbReader *pReader, STableBlockDistInfo *pTableBlockInfo); int64_t tsdbGetNumOfRowsInMemTable(STsdbReader *pHandle); diff --git a/source/dnode/vnode/src/sma/smaCommit.c b/source/dnode/vnode/src/sma/smaCommit.c index 30299e8792..6e75176136 100644 --- a/source/dnode/vnode/src/sma/smaCommit.c +++ b/source/dnode/vnode/src/sma/smaCommit.c @@ -83,8 +83,8 @@ int32_t smaBegin(SSma *pSma) { /** * @brief pre-commit for rollup sma. * 1) set trigger stat of rsma timer TASK_TRIGGER_STAT_PAUSED. - * 2) perform persist task for qTaskInfo - * 3) wait all triggered fetch tasks finished + * 2) wait all triggered fetch tasks finished + * 3) perform persist task for qTaskInfo * * @param pSma * @return int32_t @@ -102,10 +102,7 @@ static int32_t tdProcessRSmaPreCommitImpl(SSma *pSma) { // step 1: set persistence task paused atomic_store_8(RSMA_TRIGGER_STAT(pRSmaStat), TASK_TRIGGER_STAT_PAUSED); - // step 2: perform persist task for qTaskInfo - tdRSmaPersistExecImpl(pRSmaStat); - - // step 3: wait all triggered fetch tasks finished + // step 2: wait all triggered fetch tasks finished int32_t nLoops = 0; while (1) { if (T_REF_VAL_GET(pStat) == 0) { @@ -121,6 +118,9 @@ static int32_t tdProcessRSmaPreCommitImpl(SSma *pSma) { } } + // step 3: perform persist task for qTaskInfo + tdRSmaPersistExecImpl(pRSmaStat); + smaDebug("vgId:%d, rsma pre commit succeess", SMA_VID(pSma)); return TSDB_CODE_SUCCESS; diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index 9899440833..4e1b2db44a 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -915,9 +915,9 @@ static int32_t tdRSmaQTaskInfoItemRestore(SSma *pSma, const SRSmaQTaskInfoItem * return TSDB_CODE_SUCCESS; } - if (pItem->type == 1) { + if (pItem->type == TSDB_RETENTION_L1) { qTaskInfo = pRSmaInfo->items[0].taskInfo; - } else if (pItem->type == 2) { + } else if (pItem->type == TSDB_RETENTION_L2) { qTaskInfo = pRSmaInfo->items[1].taskInfo; } else { ASSERT(0); @@ -1233,7 +1233,6 @@ static void tdRSmaPersistTask(SRSmaStat *pRSmaStat) { } else { smaWarn("vgId:%d, persist task in abnormal stat %" PRIi8, SMA_VID(pRSmaStat->pSma), atomic_load_8(RSMA_TRIGGER_STAT(pRSmaStat))); - ASSERT(0); } atomic_store_8(RSMA_RUNNING_STAT(pRSmaStat), 0); taosReleaseRef(smaMgmt.smaRef, pRSmaStat->refId); diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 2460c5090f..d83f482ca8 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -16,17 +16,22 @@ #include "tsdb.h" #define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC) +typedef struct { + STbDataIter *iter; + int32_t index; + bool hasVal; +} SIterInfo; + typedef struct STableBlockScanInfo { uint64_t uid; TSKEY lastKey; SBlockIdx blockIdx; SArray* pBlockList; // block data index list - bool iterInit; // whether to initialize the in-memory skip list iterator or not - STbDataIter* iter; // mem buffer skip list iterator - STbDataIter* iiter; // imem buffer skip list iterator + SIterInfo iter; // mem buffer skip list iterator + SIterInfo iiter; // imem buffer skip list iterator SArray* delSkyline; // delete info for this table - bool memHasVal; - bool imemHasVal; + int32_t fileDelIndex; + bool iterInit; // whether to initialize the in-memory skip list iterator or not } STableBlockScanInfo; typedef struct SBlockOrderWrapper { @@ -112,14 +117,14 @@ struct STsdbReader { char* idStr; // query info handle, for debug purpose int32_t type; // query type: 1. retrieve all data blocks, 2. retrieve direct prev|next rows SBlockLoadSuppInfo suppInfo; - SArray* prev; // previous row which is before than time window - SArray* next; // next row which is after the query time window + SIOCostSummary cost; STSchema* pSchema; - - SDataFReader* pFileReader; - SVersionRange verRange; + SDataFReader* pFileReader; + SVersionRange verRange; #if 0 + SArray* prev; // previous row which is before than time window + SArray* next; // next row which is after the query time window SFileBlockInfo* pDataBlockInfo; SDataCols* pDataCols; // in order to hold current file data block int32_t allocSize; // allocated data block size @@ -136,19 +141,19 @@ struct STsdbReader { static SFileDataBlockInfo* getCurrentBlockInfo(SDataBlockIter* pBlockIter); static int buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t endKey, int32_t capacity, STsdbReader* pReader); -static TSDBROW* getValidRow(STbDataIter* pIter, bool* hasVal, STsdbReader* pReader); +static TSDBROW* getValidRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pReader); static int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader, SRowMerger* pMerger); -static int32_t doMergeRowsInBuf(STbDataIter* pIter, bool* hasVal, int64_t ts, SRowMerger* pMerger, - STsdbReader* pReader); +static int32_t doMergeRowsInBuf(SIterInfo *pIter, int64_t ts, SArray* pDelList, SRowMerger* pMerger, STsdbReader* pReader); static int32_t doAppendOneRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow); static void setComposedBlockFlag(STsdbReader* pReader, bool composed); static void updateSchema(TSDBROW* pRow, uint64_t uid, STsdbReader* pReader); +static bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey); -static void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, STbDataIter* dIter, bool* hasVal, STSRow** pTSRow, - STsdbReader* pReader); +static void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo *pIter, SArray* pDelList, STSRow** pTSRow, STsdbReader* pReader); static void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STSRow** pTSRow); +static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STbData* pMemTbData, STbData* piMemTbData); static int32_t setColumnIdSlotList(STsdbReader* pReader, SSDataBlock* pBlock) { SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo; @@ -372,7 +377,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, STsd pReader->suid = pCond->suid; pReader->order = pCond->order; pReader->capacity = 4096; - pReader->idStr = strdup(idstr); + pReader->idStr = (idstr != NULL)? strdup(idstr):NULL; pReader->verRange = (SVersionRange) {.minVer = pCond->startVersion, .maxVer = 10000}; pReader->type = pCond->type; pReader->window = updateQueryTimeWindow(pVnode->pTsdb, pCond->twindows); @@ -1708,7 +1713,7 @@ static bool fileBlockShouldLoad(STsdbReader* pReader, SFileDataBlockInfo* pFBloc } static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, int64_t endKey) { - if (!(pBlockScanInfo->imemHasVal || pBlockScanInfo->memHasVal)) { + if (!(pBlockScanInfo->iiter.hasVal || pBlockScanInfo->iter.hasVal)) { return TSDB_CODE_SUCCESS; } @@ -1728,13 +1733,14 @@ static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo* } static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, TSDBROW* pRow, - STSRow* pTSRow, STbDataIter* pIter, bool* hasVal, int64_t key) { + STSRow* pTSRow, SIterInfo* pIter, int64_t key) { SRowMerger merge = {0}; SBlockData* pBlockData = &pReader->status.fileBlockData; SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo; TSDBKEY k = TSDBROW_KEY(pRow); TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex); + SArray* pDelList = pBlockScanInfo->delSkyline; // ascending order traverse if (ASCENDING_TRAVERSE(pReader->order)) { @@ -1744,19 +1750,19 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge); tRowMergerGetRow(&merge, &pTSRow); } else if (k.ts < key) { // k.ts < key - doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, hasVal, &pTSRow, pReader); + doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader); } else { // k.ts == key, ascending order: file block ----> imem rows -----> mem rows tRowMergerInit(&merge, &fRow, pReader->pSchema); doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge); tRowMerge(&merge, pRow); - doMergeRowsInBuf(pIter, hasVal, k.ts, &merge, pReader); + doMergeRowsInBuf(pIter, k.ts, pBlockScanInfo->delSkyline, &merge, pReader); tRowMergerGetRow(&merge, &pTSRow); } } else { // descending order scan if (key < k.ts) { - doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, hasVal, &pTSRow, pReader); + doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader); } else if (k.ts < key) { tRowMergerInit(&merge, &fRow, pReader->pSchema); @@ -1766,7 +1772,7 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* updateSchema(pRow, pBlockScanInfo->uid, pReader); tRowMergerInit(&merge, pRow, pReader->pSchema); - doMergeRowsInBuf(pIter, hasVal, k.ts, &merge, pReader); + doMergeRowsInBuf(pIter, k.ts, pBlockScanInfo->delSkyline, &merge, pReader); tRowMerge(&merge, &fRow); doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge); @@ -1786,9 +1792,10 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo; SBlockData* pBlockData = &pReader->status.fileBlockData; + SArray* pDelList = pBlockScanInfo->delSkyline; - TSDBROW* pRow = getValidRow(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, pReader); - TSDBROW* piRow = getValidRow(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, pReader); + TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pDelList, pReader); + TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pDelList, pReader); ASSERT(pRow != NULL && piRow != NULL); int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex]; @@ -1808,12 +1815,12 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* if (ik.ts == key) { tRowMerge(&merge, piRow); - doMergeRowsInBuf(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, key, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iiter, key, pBlockScanInfo->delSkyline, &merge, pReader); } if (k.ts == key) { tRowMerge(&merge, pRow); - doMergeRowsInBuf(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, key, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iter, key, pBlockScanInfo->delSkyline, &merge, pReader); } tRowMergerGetRow(&merge, &pTSRow); @@ -1825,7 +1832,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* // [3] ik.ts < key <= k.ts // [4] ik.ts < k.ts <= key if (ik.ts < k.ts) { - doMergeMultiRows(piRow, uid, pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, &pTSRow, pReader); + doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader); doAppendOneRow(pReader->pResBlock, pReader, pTSRow); return TSDB_CODE_SUCCESS; } @@ -1833,7 +1840,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* // [5] k.ts < key <= ik.ts // [6] k.ts < ik.ts <= key if (k.ts < ik.ts) { - doMergeMultiRows(pRow, uid, pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, &pTSRow, pReader); + doMergeMultiRows(pRow, uid, &pBlockScanInfo->iter, pDelList, &pTSRow, pReader); doAppendOneRow(pReader->pResBlock, pReader, pTSRow); return TSDB_CODE_SUCCESS; } @@ -1853,11 +1860,11 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* updateSchema(pRow, uid, pReader); tRowMergerInit(&merge, pRow, pReader->pSchema); - doMergeRowsInBuf(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, key, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iter, key, pBlockScanInfo->delSkyline, &merge, pReader); if (ik.ts == k.ts) { tRowMerge(&merge, piRow); - doMergeRowsInBuf(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, key, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iiter, key, pBlockScanInfo->delSkyline, &merge, pReader); } if (k.ts == key) { @@ -1875,7 +1882,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* // [3] ik.ts > k.ts >= Key // [4] ik.ts > key >= k.ts if (ik.ts > key) { - doMergeMultiRows(piRow, uid, pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, &pTSRow, pReader); + doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader); doAppendOneRow(pReader->pResBlock, pReader, pTSRow); return TSDB_CODE_SUCCESS; } @@ -1894,7 +1901,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* //[7] key = ik.ts > k.ts if (key == ik.ts) { - doMergeMultiRows(piRow, uid, pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, &pTSRow, pReader); + doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader); TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex); tRowMerge(&merge, &fRow); @@ -1909,7 +1916,8 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo* ASSERT(0); } -static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDumpInfo, STsdbReader* pReader) { +static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDumpInfo, STableBlockScanInfo* pBlockScanInfo, + STsdbReader* pReader) { // check for version and time range int64_t ver = pBlockData->aVersion[pDumpInfo->rowIndex]; if (ver > pReader->verRange.maxVer || ver < pReader->verRange.minVer) { @@ -1921,6 +1929,11 @@ static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDum return false; } + TSDBKEY k = {.ts = ts, .version = ver}; + if (hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->fileDelIndex, &k)) { + return false; + } + return true; } @@ -1934,22 +1947,20 @@ static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanI STSRow* pTSRow = NULL; int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex]; - TSDBROW* pRow = getValidRow(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, pReader); - TSDBROW* piRow = getValidRow(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, pReader); + TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader); + TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader); - if (pBlockScanInfo->memHasVal && pBlockScanInfo->imemHasVal) { + if (pBlockScanInfo->iter.hasVal && pBlockScanInfo->iiter.hasVal) { return doMergeThreeLevelRows(pReader, pBlockScanInfo); } else { // imem + file - if (pBlockScanInfo->imemHasVal) { - return doMergeBufAndFileRows(pReader, pBlockScanInfo, piRow, pTSRow, pBlockScanInfo->iiter, - &pBlockScanInfo->imemHasVal, key); + if (pBlockScanInfo->iiter.hasVal) { + return doMergeBufAndFileRows(pReader, pBlockScanInfo, piRow, pTSRow, &pBlockScanInfo->iiter, key); } // mem + file - if (pBlockScanInfo->memHasVal) { - return doMergeBufAndFileRows(pReader, pBlockScanInfo, pRow, pTSRow, pBlockScanInfo->iter, - &pBlockScanInfo->memHasVal, key); + if (pBlockScanInfo->iter.hasVal) { + return doMergeBufAndFileRows(pReader, pBlockScanInfo, pRow, pTSRow, &pBlockScanInfo->iter,key); } // imem & mem are all empty, only file exist @@ -1973,7 +1984,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader, STableBlockScanInfo* while (1) { // todo check the validate of row in file block { - if (!isValidFileBlockRow(pBlockData, pDumpInfo, pReader)) { + if (!isValidFileBlockRow(pBlockData, pDumpInfo, pBlockScanInfo, pReader)) { pDumpInfo->rowIndex += step; SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(&pReader->status.blockIter); @@ -2018,7 +2029,7 @@ static int32_t buildComposedDataBlock(STsdbReader* pReader, STableBlockScanInfo* void setComposedBlockFlag(STsdbReader* pReader, bool composed) { pReader->status.composedDataBlock = composed; } -static int32_t initMemIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader) { +static int32_t initMemDataIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader) { if (pBlockScanInfo->iterInit) { return TSDB_CODE_SUCCESS; } @@ -2038,9 +2049,9 @@ static int32_t initMemIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* if (pReader->pTsdb->mem != NULL) { tsdbGetTbDataFromMemTable(pReader->pTsdb->mem, pReader->suid, pBlockScanInfo->uid, &d); if (d != NULL) { - code = tsdbTbDataIterCreate(d, &startKey, backward, &pBlockScanInfo->iter); + code = tsdbTbDataIterCreate(d, &startKey, backward, &pBlockScanInfo->iter.iter); if (code == TSDB_CODE_SUCCESS) { - pBlockScanInfo->memHasVal = (tsdbTbDataIterGet(pBlockScanInfo->iter) != NULL); + pBlockScanInfo->iter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iter.iter) != NULL); tsdbDebug("%p uid:%" PRId64 ", check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64 "-%" PRId64 " %s", @@ -2059,9 +2070,9 @@ static int32_t initMemIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* if (pReader->pTsdb->imem != NULL) { tsdbGetTbDataFromMemTable(pReader->pTsdb->imem, pReader->suid, pBlockScanInfo->uid, &di); if (di != NULL) { - code = tsdbTbDataIterCreate(di, &startKey, backward, &pBlockScanInfo->iiter); + code = tsdbTbDataIterCreate(di, &startKey, backward, &pBlockScanInfo->iiter.iter); if (code == TSDB_CODE_SUCCESS) { - pBlockScanInfo->imemHasVal = (tsdbTbDataIterGet(pBlockScanInfo->iiter) != NULL); + pBlockScanInfo->iiter.hasVal = (tsdbTbDataIterGet(pBlockScanInfo->iiter.iter) != NULL); tsdbDebug("%p uid:%" PRId64 ", check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64 "-%" PRId64 " %s", @@ -2076,18 +2087,22 @@ static int32_t initMemIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* tsdbDebug("%p uid:%" PRId64 ", no data in imem, %s", pReader, pBlockScanInfo->uid, pReader->idStr); } + initDelSkylineIterator(pBlockScanInfo, pReader, d, di); + pBlockScanInfo->iterInit = true; return TSDB_CODE_SUCCESS; } -static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader) { +int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STbData* pMemTbData, STbData* piMemTbData) { if (pBlockScanInfo->delSkyline != NULL) { return TSDB_CODE_SUCCESS; } -#if 0 + int32_t code = 0; STsdb* pTsdb = pReader->pTsdb; + SArray* pDelData = taosArrayInit(4, sizeof(SDelData)); + SDelFile *pDelFile = tsdbFSStateGetDelFile(pTsdb->fs->cState); if (pDelFile) { SDelFReader* pDelFReader = NULL; @@ -2101,27 +2116,51 @@ static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdb goto _err; } - SDelFile* pDelFileR = pReader->pTsdb->fs->nState->pDelFile; - if (pDelFileR) { - code = tsdbDelFReaderOpen(&pDelFReader, pDelFileR, pTsdb, NULL); - if (code) { - goto _err; - } - - code = tsdbReadDelIdx(pDelFReader, aDelIdx, NULL); - if (code) { - goto _err; - } + code = tsdbReadDelIdx(pDelFReader, aDelIdx, NULL); + if (code) { + goto _err; } - code = tsdbBuildDeleteSkyline(pBlockScanInfo->delSkyline, 0, (int32_t)(nDelData - 1), aSkyline); + SDelIdx idx = {.suid = pReader->suid, .uid = pBlockScanInfo->uid}; + SDelIdx* pIdx = taosArraySearch(aDelIdx, &idx, tCmprDelIdx, TD_EQ); + + code = tsdbReadDelData(pDelFReader, pIdx, pDelData, NULL); + if (code != TSDB_CODE_SUCCESS) { + goto _err; + } } - _err: + SDelData* p = NULL; + if (pMemTbData != NULL) { + p = pMemTbData->pHead; + while (p) { + taosArrayPush(pDelData, p); + p = p->pNext; + } + } + + if (piMemTbData != NULL) { + p = piMemTbData->pHead; + while (p) { + taosArrayPush(pDelData, p); + p = p->pNext; + } + } + + if (taosArrayGetSize(pDelData) > 0) { + pBlockScanInfo->delSkyline = taosArrayInit(4, sizeof(TSDBKEY)); + code = tsdbBuildDeleteSkyline(pDelData, 0, (int32_t)(taosArrayGetSize(pDelData) - 1), pBlockScanInfo->delSkyline); + } + + taosArrayDestroy(pDelData); + pBlockScanInfo->iter.index = ASCENDING_TRAVERSE(pReader->order)? 0:taosArrayGetSize(pBlockScanInfo->delSkyline) - 1; + pBlockScanInfo->iiter.index = pBlockScanInfo->iter.index; + pBlockScanInfo->fileDelIndex = pBlockScanInfo->iter.index; return code; -#endif - return 0; +_err: + taosArrayDestroy(pDelData); + return code; } static TSDBKEY getCurrentKeyInBuf(SDataBlockIter* pBlockIter, STsdbReader* pReader) { @@ -2130,13 +2169,13 @@ static TSDBKEY getCurrentKeyInBuf(SDataBlockIter* pBlockIter, STsdbReader* pRead SFileDataBlockInfo* pFBlock = getCurrentBlockInfo(pBlockIter); STableBlockScanInfo* pScanInfo = taosHashGet(pReader->status.pTableMap, &pFBlock->uid, sizeof(pFBlock->uid)); - initMemIterator(pScanInfo, pReader); - TSDBROW* pRow = getValidRow(pScanInfo->iter, &pScanInfo->memHasVal, pReader); + initMemDataIterator(pScanInfo, pReader); + TSDBROW* pRow = getValidRow(&pScanInfo->iter, pScanInfo->delSkyline, pReader); if (pRow != NULL) { key = TSDBROW_KEY(pRow); } - pRow = getValidRow(pScanInfo->iiter, &pScanInfo->imemHasVal, pReader); + pRow = getValidRow(&pScanInfo->iiter, pScanInfo->delSkyline, pReader); if (pRow != NULL) { TSDBKEY k = TSDBROW_KEY(pRow); if (key.ts > k.ts) { @@ -2230,7 +2269,7 @@ static int32_t buildBlockFromBufferSequentially(STsdbReader* pReader) { } STableBlockScanInfo* pBlockScanInfo = pStatus->pTableIter; - initMemIterator(pBlockScanInfo, pReader); + initMemDataIterator(pBlockScanInfo, pReader); int64_t endKey = (ASCENDING_TRAVERSE(pReader->order)) ? INT64_MAX : INT64_MIN; int32_t code = buildDataBlockFromBuf(pReader, pBlockScanInfo, endKey); @@ -2369,51 +2408,89 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) { // taosArrayPush(pTsdbReadHandle->pTableCheckInfo, &info); // } -TSDBROW* getValidRow(STbDataIter* pIter, bool* hasVal, STsdbReader* pReader) { - if (!(*hasVal)) { +bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey) { + ASSERT(pKey != NULL); + if (pDelList == NULL) { + return false; + } + + if (*index >= taosArrayGetSize(pDelList) - 1) { + TSDBKEY* last = taosArrayGetLast(pDelList); + if (pKey->ts > last->ts) { + return false; + } else if (pKey->ts == last->ts) { + size_t size = taosArrayGetSize(pDelList); + TSDBKEY* prev = taosArrayGet(pDelList, size - 2); + if (prev->version >= pKey->version) { + return true; + } else { + return false; + } + } else { + ASSERT(0); + } + } else { + TSDBKEY* pCurrent = taosArrayGet(pDelList, *index); + TSDBKEY* pNext = taosArrayGet(pDelList, (*index) + 1); + + if (pCurrent->ts <= pKey->ts && pNext->ts >= pKey->ts && pCurrent->version >= pKey->version) { + return true; + } else { + while (pNext->ts < pKey->ts && (*index) < taosArrayGetSize(pDelList) - 1) { + (*index) += 1; + } + + return false; + } + } +} + +TSDBROW* getValidRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pReader) { + if (!pIter->hasVal) { return NULL; } - TSDBROW* pRow = tsdbTbDataIterGet(pIter); + TSDBROW* pRow = tsdbTbDataIterGet(pIter->iter); TSDBKEY key = TSDBROW_KEY(pRow); if (outOfTimeWindow(key.ts, &pReader->window)) { - *hasVal = false; + pIter->hasVal = false; return NULL; } - if (key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer) { + // it is a valid data version + if ((key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer) && (!hasBeenDropped(pDelList, &pIter->index, &key))) { return pRow; } while (1) { - *hasVal = tsdbTbDataIterNext(pIter); - if (!(*hasVal)) { + pIter->hasVal = tsdbTbDataIterNext(pIter->iter); + if (!pIter->hasVal) { return NULL; } - pRow = tsdbTbDataIterGet(pIter); + pRow = tsdbTbDataIterGet(pIter->iter); key = TSDBROW_KEY(pRow); if (outOfTimeWindow(key.ts, &pReader->window)) { - *hasVal = false; + pIter->hasVal = false; return NULL; } - if (key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer) { + if (key.version <= pReader->verRange.maxVer && key.version >= pReader->verRange.minVer && (!hasBeenDropped(pDelList, &pIter->index, &key))) { return pRow; } } } -int32_t doMergeRowsInBuf(STbDataIter* pIter, bool* hasVal, int64_t ts, SRowMerger* pMerger, STsdbReader* pReader) { +int32_t doMergeRowsInBuf(SIterInfo *pIter, int64_t ts, SArray* pDelList, SRowMerger* pMerger, STsdbReader* pReader) { while (1) { - *hasVal = tsdbTbDataIterNext(pIter); - if (!(*hasVal)) { + pIter->hasVal = tsdbTbDataIterNext(pIter->iter); + if (!pIter->hasVal) { break; } // data exists but not valid - TSDBROW* pRow = getValidRow(pIter, hasVal, pReader); + TSDBROW* pRow = getValidRow(pIter, pDelList, pReader); if (pRow == NULL) { break; } @@ -2539,15 +2616,14 @@ void updateSchema(TSDBROW* pRow, uint64_t uid, STsdbReader* pReader) { } } -void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, STbDataIter* dIter, bool* hasVal, STSRow** pTSRow, - STsdbReader* pReader) { +void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo *pIter, SArray* pDelList, STSRow** pTSRow, STsdbReader* pReader) { SRowMerger merge = {0}; TSDBKEY k = TSDBROW_KEY(pRow); updateSchema(pRow, uid, pReader); tRowMergerInit(&merge, pRow, pReader->pSchema); - doMergeRowsInBuf(dIter, hasVal, k.ts, &merge, pReader); + doMergeRowsInBuf(pIter, k.ts, pDelList, &merge, pReader); tRowMergerGetRow(&merge, pTSRow); } @@ -2562,18 +2638,18 @@ void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlo updateSchema(piRow, pBlockScanInfo->uid, pReader); tRowMergerInit(&merge, piRow, pReader->pSchema); - doMergeRowsInBuf(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, ik.ts, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iiter, ik.ts, pBlockScanInfo->delSkyline, &merge, pReader); tRowMerge(&merge, pRow); - doMergeRowsInBuf(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, k.ts, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iter, k.ts, pBlockScanInfo->delSkyline, &merge, pReader); } else { updateSchema(pRow, pBlockScanInfo->uid, pReader); tRowMergerInit(&merge, pRow, pReader->pSchema); - doMergeRowsInBuf(pBlockScanInfo->iiter, &pBlockScanInfo->memHasVal, ik.ts, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iter, k.ts, pBlockScanInfo->delSkyline, &merge, pReader); tRowMerge(&merge, piRow); - doMergeRowsInBuf(pBlockScanInfo->iter, &pBlockScanInfo->imemHasVal, k.ts, &merge, pReader); + doMergeRowsInBuf(&pBlockScanInfo->iiter, k.ts, pBlockScanInfo->delSkyline, &merge, pReader); } tRowMergerGetRow(&merge, pTSRow); @@ -2581,33 +2657,34 @@ void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlo int32_t tsdbGetNextRowInMem(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STSRow** pTSRow, int64_t endKey) { - TSDBROW* pRow = getValidRow(pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, pReader); - TSDBROW* piRow = getValidRow(pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, pReader); + TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader); + TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader); + SArray* pDelList = pBlockScanInfo->delSkyline; // todo refactor bool asc = ASCENDING_TRAVERSE(pReader->order); - if (pBlockScanInfo->memHasVal) { + if (pBlockScanInfo->iter.hasVal) { TSDBKEY k = TSDBROW_KEY(pRow); if ((k.ts >= endKey && asc) || (k.ts <= endKey && !asc)) { pRow = NULL; } } - if (pBlockScanInfo->imemHasVal) { + if (pBlockScanInfo->iiter.hasVal) { TSDBKEY k = TSDBROW_KEY(piRow); if ((k.ts >= endKey && asc) || (k.ts <= endKey && !asc)) { piRow = NULL; } } - if (pBlockScanInfo->memHasVal && pBlockScanInfo->imemHasVal && pRow != NULL && piRow != NULL) { + if (pBlockScanInfo->iter.hasVal && pBlockScanInfo->iiter.hasVal && pRow != NULL && piRow != NULL) { TSDBKEY k = TSDBROW_KEY(pRow); TSDBKEY ik = TSDBROW_KEY(piRow); if (ik.ts < k.ts) { // ik.ts < k.ts - doMergeMultiRows(piRow, pBlockScanInfo->uid, pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, pTSRow, pReader); + doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader); } else if (k.ts < ik.ts) { - doMergeMultiRows(pRow, pBlockScanInfo->uid, pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, pTSRow, pReader); + doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader); } else { // ik.ts == k.ts doMergeMemIMemRows(pRow, piRow, pBlockScanInfo, pReader, pTSRow); } @@ -2615,13 +2692,13 @@ int32_t tsdbGetNextRowInMem(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pR return TSDB_CODE_SUCCESS; } - if (pBlockScanInfo->memHasVal && pRow != NULL) { - doMergeMultiRows(pRow, pBlockScanInfo->uid, pBlockScanInfo->iter, &pBlockScanInfo->memHasVal, pTSRow, pReader); + if (pBlockScanInfo->iter.hasVal && pRow != NULL) { + doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader); return TSDB_CODE_SUCCESS; } - if (pBlockScanInfo->imemHasVal && piRow != NULL) { - doMergeMultiRows(piRow, pBlockScanInfo->uid, pBlockScanInfo->iiter, &pBlockScanInfo->imemHasVal, pTSRow, pReader); + if (pBlockScanInfo->iiter.hasVal && piRow != NULL) { + doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader); return TSDB_CODE_SUCCESS; } @@ -2686,7 +2763,7 @@ int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t e doAppendOneRow(pBlock, pReader, pTSRow); // no data in buffer, return immediately - if (!(pBlockScanInfo->memHasVal || pBlockScanInfo->imemHasVal)) { + if (!(pBlockScanInfo->iter.hasVal || pBlockScanInfo->iiter.hasVal)) { break; } @@ -2699,12 +2776,13 @@ int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t e return TSDB_CODE_SUCCESS; } +// todo refactor, use arraylist instead int32_t tsdbSetTableId(STsdbReader* pReader, int64_t uid) { - // if (pReader->pTableCheckInfo) taosArrayDestroy(pReader->pTableCheckInfo); - // pReader->pTableCheckInfo = createCheckInfoFromUid(pReader, uid); - // if (pReader->pTableCheckInfo == NULL) { - // return TSDB_CODE_TDB_OUT_OF_MEMORY; - // } + ASSERT(pReader != NULL); + taosHashClear(pReader->status.pTableMap); + + STableBlockScanInfo info = {.lastKey = 0, .uid = uid}; + taosHashPut(pReader->status.pTableMap, &info.uid, sizeof(uint64_t), &info, sizeof(info)); return TDB_CODE_SUCCESS; } @@ -3165,40 +3243,46 @@ SArray* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) { return pReader->pResBlock->pDataBlock; } -void tsdbResetReadHandle(STsdbReader* pReader, SQueryTableDataCond* pCond, int32_t tWinIdx) { - // if (isEmptyQueryTimeWindow(pReader)) { - // if (pCond->order != pReader->order) { - // pReader->order = pCond->order; - // TSWAP(pReader->window.skey, pReader->window.ekey); - // } +int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond, int32_t tWinIdx) { + if (isEmptyQueryTimeWindow(&pReader->window)) { + return TSDB_CODE_SUCCESS; + } - // return; - // } + setQueryTimewindow(pReader, pCond, tWinIdx); - // pReader->order = pCond->order; - // setQueryTimewindow(pReader, pCond, tWinIdx); - // pReader->type = TSDB_QUERY_TYPE_ALL; - // pReader->cur.fid = -1; - // pReader->cur.win = TSWINDOW_INITIALIZER; - // pReader->checkFiles = true; - // pReader->activeIndex = 0; // current active table index - // pReader->locateStart = false; - // pReader->loadExternalRow = pCond->loadExternalRows; + pReader->order = pCond->order; + pReader->type = BLOCK_LOAD_OFFSET_ORDER; + pReader->status.loadFromFile = true; + pReader->status.pTableIter = NULL; - // if (ASCENDING_TRAVERSE(pCond->order)) { - // assert(pReader->window.skey <= pReader->window.ekey); - // } else { - // assert(pReader->window.skey >= pReader->window.ekey); - // } + pReader->window = updateQueryTimeWindow(pReader->pTsdb, &pCond->twindows[tWinIdx]); - // // allocate buffer in order to load data blocks from file - // memset(pReader->suppInfo.pstatis, 0, sizeof(SColumnDataAgg)); - // memset(pReader->suppInfo.plist, 0, POINTER_BYTES); + // allocate buffer in order to load data blocks from file + memset(pReader->suppInfo.pstatis, 0, sizeof(SColumnDataAgg)); + memset(pReader->suppInfo.plist, 0, POINTER_BYTES); - // tsdbInitDataBlockLoadInfo(&pReader->dataBlockLoadInfo); - // tsdbInitCompBlockLoadInfo(&pReader->compBlockLoadInfo); + // todo set the correct numOfTables + int32_t numOfTables = 1; + SDataBlockIter* pBlockIter = &pReader->status.blockIter; - // resetCheckInfo(pReader); + STsdbFSState* pFState = pReader->pTsdb->fs->cState; + initFilesetIterator(&pReader->status.fileIter, pFState, pReader->order, pReader->idStr); + resetDataBlockIterator(&pReader->status.blockIter, pReader->order); + + int32_t code = 0; + // no data in files, let's try buffer in memory + if (pReader->status.fileIter.numOfFiles == 0) { + pReader->status.loadFromFile = false; + } else { + code = initForFirstBlockInFile(pReader, pBlockIter); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + ASSERT(0); + tsdbDebug("%p reset tsdbreader in query %s", pReader, numOfTables, pReader->idStr); + return code; } int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTableBlockInfo) { diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c index ce94c0ecb7..efd0eec0b0 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c +++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c @@ -345,8 +345,14 @@ int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData ASSERT(pHdr->suid == pDelIdx->suid); ASSERT(pHdr->uid == pDelIdx->uid); n += sizeof(*pHdr); + taosArrayClear(aDelData); while (n < size - sizeof(TSCKSUM)) { n += tGetDelData(*ppBuf + n, pDelData); + + if (taosArrayPush(aDelData, pDelData) == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } } ASSERT(n == size - sizeof(TSCKSUM)); diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c index 6eb7329487..293e8896ac 100644 --- a/source/dnode/vnode/src/tsdb/tsdbUtil.c +++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c @@ -229,15 +229,15 @@ int32_t tCmprBlockIdx(void const *lhs, void const *rhs) { SBlockIdx *lBlockIdx = *(SBlockIdx **)lhs; SBlockIdx *rBlockIdx = *(SBlockIdx **)rhs; - if (lBlockIdx->suid < lBlockIdx->suid) { + if (lBlockIdx->suid < rBlockIdx->suid) { return -1; - } else if (lBlockIdx->suid > lBlockIdx->suid) { + } else if (lBlockIdx->suid > rBlockIdx->suid) { return 1; } - if (lBlockIdx->uid < lBlockIdx->uid) { + if (lBlockIdx->uid < rBlockIdx->uid) { return -1; - } else if (lBlockIdx->uid > lBlockIdx->uid) { + } else if (lBlockIdx->uid > rBlockIdx->uid) { return 1; } @@ -385,15 +385,15 @@ int32_t tCmprDelIdx(void const *lhs, void const *rhs) { SDelIdx *lDelIdx = *(SDelIdx **)lhs; SDelIdx *rDelIdx = *(SDelIdx **)rhs; - if (lDelIdx->suid < lDelIdx->suid) { + if (lDelIdx->suid < rDelIdx->suid) { return -1; - } else if (lDelIdx->suid > lDelIdx->suid) { + } else if (lDelIdx->suid > rDelIdx->suid) { return 1; } - if (lDelIdx->uid < lDelIdx->uid) { + if (lDelIdx->uid < rDelIdx->uid) { return -1; - } else if (lDelIdx->uid > lDelIdx->uid) { + } else if (lDelIdx->uid > rDelIdx->uid) { return 1; } diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index 80ba80e61a..0445eda7af 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -256,70 +256,133 @@ int32_t vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { SRpcMsg *pRpcMsg = pMsg; - if (pRpcMsg->msgType == TDMT_SYNC_TIMEOUT) { - SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + // ToDo: ugly! use function pointer + // use different strategy + if (syncNodeStrategy(pSyncNode) == SYNC_STRATEGY_NO_SNAPSHOT) { + if (pRpcMsg->msgType == TDMT_SYNC_TIMEOUT) { + SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnTimeoutCb(pSyncNode, pSyncMsg); + syncTimeoutDestroy(pSyncMsg); - ret = syncNodeOnTimeoutCb(pSyncNode, pSyncMsg); - syncTimeoutDestroy(pSyncMsg); + } else if (pRpcMsg->msgType == TDMT_SYNC_PING) { + SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnPingCb(pSyncNode, pSyncMsg); + syncPingDestroy(pSyncMsg); - } else if (pRpcMsg->msgType == TDMT_SYNC_PING) { - SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + } else if (pRpcMsg->msgType == TDMT_SYNC_PING_REPLY) { + SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnPingReplyCb(pSyncNode, pSyncMsg); + syncPingReplyDestroy(pSyncMsg); - ret = syncNodeOnPingCb(pSyncNode, pSyncMsg); - syncPingDestroy(pSyncMsg); + } else if (pRpcMsg->msgType == TDMT_SYNC_CLIENT_REQUEST) { + SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnClientRequestCb(pSyncNode, pSyncMsg, NULL); + syncClientRequestDestroy(pSyncMsg); - } else if (pRpcMsg->msgType == TDMT_SYNC_PING_REPLY) { - SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE) { + SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnRequestVoteCb(pSyncNode, pSyncMsg); + syncRequestVoteDestroy(pSyncMsg); - ret = syncNodeOnPingReplyCb(pSyncNode, pSyncMsg); - syncPingReplyDestroy(pSyncMsg); + } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE_REPLY) { + SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnRequestVoteReplyCb(pSyncNode, pSyncMsg); + syncRequestVoteReplyDestroy(pSyncMsg); - } else if (pRpcMsg->msgType == TDMT_SYNC_CLIENT_REQUEST) { - SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES) { + SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnAppendEntriesCb(pSyncNode, pSyncMsg); + syncAppendEntriesDestroy(pSyncMsg); - ret = syncNodeOnClientRequestCb(pSyncNode, pSyncMsg, NULL); - syncClientRequestDestroy(pSyncMsg); + } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES_REPLY) { + SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnAppendEntriesReplyCb(pSyncNode, pSyncMsg); + syncAppendEntriesReplyDestroy(pSyncMsg); - } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE) { - SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + } else if (pRpcMsg->msgType == TDMT_SYNC_SET_VNODE_STANDBY) { + ret = vnodeSetStandBy(pVnode); + if (ret != 0 && terrno != 0) ret = terrno; + SRpcMsg rsp = {.code = ret, .info = pMsg->info}; + tmsgSendRsp(&rsp); + } else { + vError("==vnodeProcessSyncReq== error msg type:%d", pRpcMsg->msgType); + ret = -1; + } - ret = syncNodeOnRequestVoteCb(pSyncNode, pSyncMsg); - syncRequestVoteDestroy(pSyncMsg); - - } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE_REPLY) { - SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); - - ret = syncNodeOnRequestVoteReplyCb(pSyncNode, pSyncMsg); - syncRequestVoteReplyDestroy(pSyncMsg); - - } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES) { - SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); - - ret = syncNodeOnAppendEntriesCb(pSyncNode, pSyncMsg); - syncAppendEntriesDestroy(pSyncMsg); - - } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES_REPLY) { - SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); - - ret = syncNodeOnAppendEntriesReplyCb(pSyncNode, pSyncMsg); - syncAppendEntriesReplyDestroy(pSyncMsg); - - } else if (pRpcMsg->msgType == TDMT_SYNC_SET_VNODE_STANDBY) { - ret = vnodeSetStandBy(pVnode); - if (ret != 0 && terrno != 0) ret = terrno; - SRpcMsg rsp = {.code = ret, .info = pMsg->info}; - tmsgSendRsp(&rsp); } else { - vError("==vnodeProcessSyncReq== error msg type:%d", pRpcMsg->msgType); - ret = -1; + // use wal first strategy + + if (pRpcMsg->msgType == TDMT_SYNC_TIMEOUT) { + SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnTimeoutCb(pSyncNode, pSyncMsg); + syncTimeoutDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_PING) { + SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnPingCb(pSyncNode, pSyncMsg); + syncPingDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_PING_REPLY) { + SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnPingReplyCb(pSyncNode, pSyncMsg); + syncPingReplyDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_CLIENT_REQUEST) { + SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnClientRequestCb(pSyncNode, pSyncMsg, NULL); + syncClientRequestDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_CLIENT_REQUEST_BATCH) { + SyncClientRequestBatch *pSyncMsg = syncClientRequestBatchFromRpcMsg(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnClientRequestBatchCb(pSyncNode, pSyncMsg); + syncClientRequestBatchDestroyDeep(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE) { + SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnRequestVoteCb(pSyncNode, pSyncMsg); + syncRequestVoteDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE_REPLY) { + SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnRequestVoteReplyCb(pSyncNode, pSyncMsg); + syncRequestVoteReplyDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES_BATCH) { + SyncAppendEntriesBatch *pSyncMsg = syncAppendEntriesBatchFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnAppendEntriesSnapshot2Cb(pSyncNode, pSyncMsg); + syncAppendEntriesBatchDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES_REPLY) { + SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg); + ASSERT(pSyncMsg != NULL); + ret = syncNodeOnAppendEntriesReplySnapshot2Cb(pSyncNode, pSyncMsg); + syncAppendEntriesReplyDestroy(pSyncMsg); + + } else if (pRpcMsg->msgType == TDMT_SYNC_SET_VNODE_STANDBY) { + ret = vnodeSetStandBy(pVnode); + if (ret != 0 && terrno != 0) ret = terrno; + SRpcMsg rsp = {.code = ret, .info = pMsg->info}; + tmsgSendRsp(&rsp); + } else { + vError("==vnodeProcessSyncReq== error msg type:%d", pRpcMsg->msgType); + ret = -1; + } } syncNodeRelease(pSyncNode); @@ -415,7 +478,7 @@ static int32_t vnodeSnapshotStopRead(struct SSyncFSM *pFsm, void *pReader) { ret static int32_t vnodeSnapshotDoRead(struct SSyncFSM *pFsm, void *pReader, void **ppBuf, int32_t *len) { return 0; } -static int32_t vnodeSnapshotStartWrite(struct SSyncFSM *pFsm, void **ppWriter) { return 0; } +static int32_t vnodeSnapshotStartWrite(struct SSyncFSM *pFsm, void *pParam, void **ppWriter) { return 0; } static int32_t vnodeSnapshotStopWrite(struct SSyncFSM *pFsm, void *pWriter, bool isApply) { return 0; } @@ -442,7 +505,8 @@ static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) { int32_t vnodeSyncOpen(SVnode *pVnode, char *path) { SSyncInfo syncInfo = { - .snapshotEnable = false, + .snapshotStrategy = SYNC_STRATEGY_NO_SNAPSHOT, + .batchSize = 10, .vgId = pVnode->config.vgId, .isStandBy = pVnode->config.standby, .syncCfg = pVnode->config.syncCfg, diff --git a/source/libs/command/inc/commandInt.h b/source/libs/command/inc/commandInt.h index 06e9af7569..6aca581f45 100644 --- a/source/libs/command/inc/commandInt.h +++ b/source/libs/command/inc/commandInt.h @@ -29,13 +29,17 @@ extern "C" { #define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s" #define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s" #define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s" +#define EXPLAIN_DISTBLK_SCAN_FORMAT "Block Dist Scan on %s" +#define EXPLAIN_LASTROW_SCAN_FORMAT "Last Row Scan on %s" #define EXPLAIN_PROJECTION_FORMAT "Projection" #define EXPLAIN_JOIN_FORMAT "%s" #define EXPLAIN_AGG_FORMAT "Aggragate" #define EXPLAIN_INDEF_ROWS_FORMAT "Indefinite Rows Function" #define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1" #define EXPLAIN_SORT_FORMAT "Sort" +#define EXPLAIN_GROUP_SORT_FORMAT "Group Sort" #define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s" +#define EXPLAIN_MERGE_INTERVAL_FORMAT "Merge Interval on Column %s" #define EXPLAIN_FILL_FORMAT "Fill" #define EXPLAIN_SESSION_FORMAT "Session" #define EXPLAIN_STATE_WINDOW_FORMAT "StateWindow on Column %s" @@ -62,10 +66,12 @@ extern "C" { #define EXPLAIN_COST_FORMAT "cost=%.2f..%.2f" #define EXPLAIN_ROWS_FORMAT "rows=%" PRIu64 #define EXPLAIN_COLUMNS_FORMAT "columns=%d" +#define EXPLAIN_PSEUDO_COLUMNS_FORMAT "pseudo_columns=%d" #define EXPLAIN_WIDTH_FORMAT "width=%d" #define EXPLAIN_TABLE_SCAN_FORMAT "order=[asc|%d desc|%d]" #define EXPLAIN_GROUPS_FORMAT "groups=%d" #define EXPLAIN_WIDTH_FORMAT "width=%d" +#define EXPLAIN_INTERVAL_VALUE_FORMAT "interval=%" PRId64 "%c" #define EXPLAIN_FUNCTIONS_FORMAT "functions=%d" #define EXPLAIN_EXECINFO_FORMAT "cost=%.3f..%.3f rows=%" PRIu64 #define EXPLAIN_MODE_FORMAT "mode=%s" diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index 7af36a0842..fde53b7064 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -199,6 +199,31 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo pPhysiChildren = mergePhysiNode->scan.node.pChildren; break; } + case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: { + SBlockDistScanPhysiNode *distPhysiNode = (SBlockDistScanPhysiNode *)pNode; + pPhysiChildren = distPhysiNode->node.pChildren; + break; + } + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: { + SLastRowScanPhysiNode *lastRowPhysiNode = (SLastRowScanPhysiNode *)pNode; + pPhysiChildren = lastRowPhysiNode->node.pChildren; + break; + } + case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: { + SGroupSortPhysiNode *groupSortPhysiNode = (SGroupSortPhysiNode *)pNode; + pPhysiChildren = groupSortPhysiNode->node.pChildren; + break; + } + case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: { + SMergeIntervalPhysiNode *mergeIntPhysiNode = (SMergeIntervalPhysiNode *)pNode; + pPhysiChildren = mergeIntPhysiNode->window.node.pChildren; + break; + } + case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: { + SInterpFuncPhysiNode *interpPhysiNode = (SInterpFuncPhysiNode *)pNode; + pPhysiChildren = interpPhysiNode->node.pChildren; + break; + } default: qError("not supported physical node type %d", pNode->type); QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR); @@ -378,6 +403,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i } EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + if (pTagScanNode->pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->pScanPseudoCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); @@ -415,6 +444,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + if (pTblScanNode->scan.pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTblScanNode->scan.pScanPseudoCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_TABLE_SCAN_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]); @@ -516,6 +549,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i } EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + if (pSTblScanNode->scan.pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pSTblScanNode->scan.pScanPseudoCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); @@ -1131,6 +1168,258 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i } break; } + case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: { + SBlockDistScanPhysiNode *pDistScanNode = (SBlockDistScanPhysiNode *)pNode; + EXPLAIN_ROW_NEW(level, EXPLAIN_DISTBLK_SCAN_FORMAT, pDistScanNode->tableName.tname); + EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); + if (pResNode->pExecInfo) { + QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pDistScanNode->pScanCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + if (pDistScanNode->pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pDistScanNode->pScanPseudoCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + if (verbose) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, + nodesGetOutputNumFromSlotList(pDistScanNode->node.pOutputDataBlockDesc->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDistScanNode->node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + + if (pDistScanNode->node.pConditions) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); + QRY_ERR_RET(nodesNodeToSQL(pDistScanNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, + TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + } + break; + } + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: { + SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode; + EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->tableName.tname); + EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); + if (pResNode->pExecInfo) { + QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->pScanCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + if (pLastRowNode->pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->pScanPseudoCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + if (verbose) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, + nodesGetOutputNumFromSlotList(pLastRowNode->node.pOutputDataBlockDesc->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + + if (pLastRowNode->node.pConditions) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); + QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, + TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + } + break; + } + case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: { + SGroupSortPhysiNode *pSortNode = (SGroupSortPhysiNode *)pNode; + EXPLAIN_ROW_NEW(level, EXPLAIN_GROUP_SORT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); + if (pResNode->pExecInfo) { + QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + + SDataBlockDescNode *pDescNode = pSortNode->node.pOutputDataBlockDesc; + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pDescNode->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pDescNode->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + if (EXPLAIN_MODE_ANALYZE == ctx->mode) { + // sort key + EXPLAIN_ROW_NEW(level + 1, "Sort Key: "); + if (pResNode->pExecInfo) { + for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) { + SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pSortNode->pSortKeys, i); + EXPLAIN_ROW_APPEND("%s ", nodesGetNameFromColumnNode(ptn->pExpr)); + } + } + + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + // sort method + EXPLAIN_ROW_NEW(level + 1, "Sort Method: "); + + int32_t nodeNum = taosArrayGetSize(pResNode->pExecInfo); + SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0); + SSortExecInfo *pExecInfo = (SSortExecInfo *)execInfo->verboseInfo; + EXPLAIN_ROW_APPEND("%s", pExecInfo->sortMethod == SORT_QSORT_T ? "quicksort" : "merge sort"); + if (pExecInfo->sortBuffer > 1024 * 1024) { + EXPLAIN_ROW_APPEND(" Buffers:%.2f Mb", pExecInfo->sortBuffer / (1024 * 1024.0)); + } else if (pExecInfo->sortBuffer > 1024) { + EXPLAIN_ROW_APPEND(" Buffers:%.2f Kb", pExecInfo->sortBuffer / (1024.0)); + } else { + EXPLAIN_ROW_APPEND(" Buffers:%d b", pExecInfo->sortBuffer); + } + + EXPLAIN_ROW_APPEND(" loops:%d", pExecInfo->loops); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + } + + if (verbose) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, + nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + + if (pSortNode->node.pConditions) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); + QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, + TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + } + break; + } + case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: { + SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode; + EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk)); + EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); + if (pResNode->pExecInfo) { + QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length); + EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + if (verbose) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, + nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + uint8_t precision = getIntervalPrecision(pIntNode); + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, + INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision), + pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision), + INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), + pIntNode->slidingUnit); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + + if (pIntNode->window.node.pConditions) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); + QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, + TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + } + break; + } + case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: { + SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode; + EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); + if (pResNode->pExecInfo) { + QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + if (pInterpNode->pFuncs) { + EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pInterpNode->pFuncs->length); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + + EXPLAIN_ROW_APPEND(EXPLAIN_MODE_FORMAT, nodesGetFillModeString(pInterpNode->fillMode)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + + EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); + + if (verbose) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, + nodesGetOutputNumFromSlotList(pInterpNode->node.pOutputDataBlockDesc->pSlots)); + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pInterpNode->node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + if (pInterpNode->pFillValues) { + SNodeListNode *pValues = (SNodeListNode *)pInterpNode->pFillValues; + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_VALUE_FORMAT); + SNode *tNode = NULL; + int32_t i = 0; + FOREACH(tNode, pValues->pNodeList) { + if (i) { + EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); + } + SValueNode *tValue = (SValueNode *)tNode; + char *value = nodesGetStrValueFromNode(tValue); + EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, value); + taosMemoryFree(value); + ++i; + } + + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_INTERVAL_VALUE_FORMAT, pInterpNode->interval, pInterpNode->intervalUnit); + EXPLAIN_ROW_END(); + + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pInterpNode->timeRange.skey, pInterpNode->timeRange.ekey); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + + if (pInterpNode->node.pConditions) { + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); + QRY_ERR_RET(nodesNodeToSQL(pInterpNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, + TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + } + } + break; + } default: qError("not supported physical node type %d", pNode->type); return TSDB_CODE_QRY_APP_ERROR; diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 8f61a67658..84dd87b9e7 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -151,10 +151,6 @@ typedef struct SExecTaskInfo { jmp_buf env; // jump to this position when error happens. EOPTR_EXEC_MODEL execModel; // operator execution model [batch model|stream model] struct SOperatorInfo* pRoot; - - /* XXXXXXXXXXXXXXXXXXXX */ - SReadHandle* pHandle; - /* XXXXXXXXXXXXXXXXXXXX */ } SExecTaskInfo; enum { diff --git a/source/libs/executor/src/executorMain.c b/source/libs/executor/src/executorMain.c index 1a5dd00120..007c61afc3 100644 --- a/source/libs/executor/src/executorMain.c +++ b/source/libs/executor/src/executorMain.c @@ -139,29 +139,8 @@ int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t* useconds) { qDebug("%s execTask is launched", GET_TASKID(pTaskInfo)); int64_t st = taosGetTimestampUs(); - /* XXXXXXXXXXXXXXXXXXXX */ - if (pTaskInfo->pHandle->deleteQuery) { - static int32_t first = 1; - if (first) { - *pRes = createDataBlock(); - int64_t rows = 33; - SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_BIGINT, 8, 1); - blockDataAppendColInfo(*pRes, &infoData); - blockDataEnsureCapacity(*pRes, 1); - (*pRes)->info.rows = 1; - SColumnInfoData* pCol1 = taosArrayGet((*pRes)->pDataBlock, 0); - colDataAppend(pCol1, 0, (char*)&rows, false); - first = 0; - } else { - *pRes = NULL; - } - } else { - /* XXXXXXXXXXXXXXXXXXXX */ - *pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot); - /* XXXXXXXXXXXXXXXXXXXX */ - } - /* XXXXXXXXXXXXXXXXXXXX */ + *pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot); uint64_t el = (taosGetTimestampUs() - st); pTaskInfo->cost.elapsedTime += el; diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 9742ec720f..c30d047c47 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -13,8 +13,6 @@ * along with this program. If not, see . */ -#include -#include #include "filter.h" #include "function.h" #include "functionMgt.h" @@ -2845,11 +2843,18 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scan int32_t doPrepareScan(SOperatorInfo* pOperator, uint64_t uid, int64_t ts) { int32_t type = pOperator->operatorType; + + pOperator->status = OP_OPENED; + if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { SStreamBlockScanInfo* pScanInfo = pOperator->info; pScanInfo->blockType = STREAM_INPUT__DATA_SCAN; + pScanInfo->pSnapshotReadOp->status = OP_OPENED; + STableScanInfo* pInfo = pScanInfo->pSnapshotReadOp->info; + ASSERT(pInfo->scanMode == TABLE_SCAN__TABLE_ORDER); + if (uid == 0) { pInfo->noTable = 1; return TSDB_CODE_SUCCESS; @@ -2863,14 +2868,6 @@ int32_t doPrepareScan(SOperatorInfo* pOperator, uint64_t uid, int64_t ts) { pInfo->noTable = 0; if (pInfo->lastStatus.uid != uid || pInfo->lastStatus.ts != ts) { - tsdbSetTableId(pInfo->dataReader, uid); - int64_t oldSkey = pInfo->cond.twindows[0].skey; - pInfo->cond.twindows[0].skey = ts + 1; - tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0); - pInfo->cond.twindows[0].skey = oldSkey; - pInfo->scanTimes = 0; - pInfo->curTWinIdx = 0; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; int32_t tableSz = taosArrayGetSize(pTaskInfo->tableqinfoList.pTableList); @@ -2882,8 +2879,17 @@ int32_t doPrepareScan(SOperatorInfo* pOperator, uint64_t uid, int64_t ts) { pInfo->currentTable = i; } } - // TODO after processing drop, + // TODO after processing drop, found can be false ASSERT(found); + + tsdbSetTableId(pInfo->dataReader, uid); + int64_t oldSkey = pInfo->cond.twindows[0].skey; + pInfo->cond.twindows[0].skey = ts + 1; + tsdbReaderReset(pInfo->dataReader, &pInfo->cond, 0); + pInfo->cond.twindows[0].skey = oldSkey; + pInfo->scanTimes = 0; + pInfo->curTWinIdx = 0; + qDebug("tsdb reader offset seek to uid %ld ts %ld, table cur set to %d , all table num %d", uid, ts, pInfo->currentTable, tableSz); } @@ -4763,10 +4769,7 @@ int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SRead (*pTaskInfo)->pRoot = createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoList, pPlan->user); - - /* XXXXXXXXXXXXXXXXXXXX */ - (*pTaskInfo)->pHandle = pHandle; - /* XXXXXXXXXXXXXXXXXXXX */ + if (NULL == (*pTaskInfo)->pRoot) { code = (*pTaskInfo)->code; goto _complete; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index a1ea712bbf..916c8939c7 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -440,7 +440,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) { } pTableScanInfo->curTWinIdx += 1; if (pTableScanInfo->curTWinIdx < pTableScanInfo->cond.numOfTWindows) { - tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, pTableScanInfo->curTWinIdx); + tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, pTableScanInfo->curTWinIdx); } } @@ -455,7 +455,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) { qDebug("%s qrange:%" PRId64 "-%" PRId64, GET_TASKID(pTaskInfo), pWin->skey, pWin->ekey); } // do prepare for the next round table scan operation - tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); + tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); pTableScanInfo->curTWinIdx = 0; } } @@ -464,7 +464,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) { if (pTableScanInfo->scanTimes < total) { if (pTableScanInfo->cond.order == TSDB_ORDER_ASC) { prepareForDescendingScan(pTableScanInfo, pTableScanInfo->pCtx, 0); - tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); + tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); pTableScanInfo->curTWinIdx = 0; } @@ -482,7 +482,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) { } pTableScanInfo->curTWinIdx += 1; if (pTableScanInfo->curTWinIdx < pTableScanInfo->cond.numOfTWindows) { - tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, pTableScanInfo->curTWinIdx); + tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, pTableScanInfo->curTWinIdx); } } @@ -498,7 +498,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) { STimeWindow* pWin = &pTableScanInfo->cond.twindows[i]; qDebug("%s qrange:%" PRId64 "-%" PRId64, GET_TASKID(pTaskInfo), pWin->skey, pWin->ekey); } - tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); + tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); pTableScanInfo->curTWinIdx = 0; } } @@ -526,7 +526,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) { } STableKeyInfo* pTableInfo = taosArrayGet(pTaskInfo->tableqinfoList.pTableList, pInfo->currentTable); tsdbSetTableId(pInfo->dataReader, pTableInfo->uid); - tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0); + tsdbReaderReset(pInfo->dataReader, &pInfo->cond, 0); pInfo->scanTimes = 0; pInfo->curTWinIdx = 0; } @@ -560,7 +560,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) { SArray* tableList = taosArrayGetP(pTaskInfo->tableqinfoList.pGroupList, pInfo->currentGroupId); // tsdbSetTableList(pInfo->dataReader, tableList); - tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0); + tsdbReaderReset(pInfo->dataReader, &pInfo->cond, 0); pInfo->curTWinIdx = 0; pInfo->scanTimes = 0; @@ -859,7 +859,7 @@ static bool prepareDataScan(SStreamBlockScanInfo* pInfo, SSDataBlock* pSDB, int3 STableScanInfo* pTableScanInfo = pInfo->pSnapshotReadOp->info; pTableScanInfo->cond.twindows[0] = win; pTableScanInfo->curTWinIdx = 0; - // tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); + // tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0); // if (!pTableScanInfo->dataReader) { // return false; // } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index f706225ebd..c1b89a5b91 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -18,6 +18,7 @@ #include "querynodes.h" #include "scalar.h" #include "taoserror.h" +#include "cJSON.h" static int32_t buildFuncErrMsg(char* pErrBuf, int32_t len, int32_t errCode, const char* pFormat, ...) { va_list vArgList; @@ -796,6 +797,165 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le return TSDB_CODE_SUCCESS; } +typedef enum { UNKNOWN_BIN = 0, USER_INPUT_BIN, LINEAR_BIN, LOG_BIN } EHistoBinType; + +static int8_t validateHistogramBinType(char* binTypeStr) { + int8_t binType; + if (strcasecmp(binTypeStr, "user_input") == 0) { + binType = USER_INPUT_BIN; + } else if (strcasecmp(binTypeStr, "linear_bin") == 0) { + binType = LINEAR_BIN; + } else if (strcasecmp(binTypeStr, "log_bin") == 0) { + binType = LOG_BIN; + } else { + binType = UNKNOWN_BIN; + } + + return binType; +} + +static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* errMsg, int32_t msgLen) { + const char *msg1 = "HISTOGRAM function requires four parameters"; + const char *msg3 = "HISTOGRAM function invalid format for binDesc parameter"; + const char *msg4 = "HISTOGRAM function binDesc parameter \"count\" should be in range [1, 1000]"; + const char *msg5 = "HISTOGRAM function bin/parameter should be in range [-DBL_MAX, DBL_MAX]"; + const char *msg6 = "HISTOGRAM function binDesc parameter \"width\" cannot be 0"; + const char *msg7 = "HISTOGRAM function binDesc parameter \"start\" cannot be 0 with \"log_bin\" type"; + const char *msg8 = "HISTOGRAM function binDesc parameter \"factor\" cannot be negative or equal to 0/1"; + + cJSON* binDesc = cJSON_Parse(binDescStr); + int32_t numOfBins; + double* intervals; + if (cJSON_IsObject(binDesc)) { /* linaer/log bins */ + int32_t numOfParams = cJSON_GetArraySize(binDesc); + int32_t startIndex; + if (numOfParams != 4) { + snprintf(errMsg, msgLen, "%s", msg1); + return false; + } + + cJSON* start = cJSON_GetObjectItem(binDesc, "start"); + cJSON* factor = cJSON_GetObjectItem(binDesc, "factor"); + cJSON* width = cJSON_GetObjectItem(binDesc, "width"); + cJSON* count = cJSON_GetObjectItem(binDesc, "count"); + cJSON* infinity = cJSON_GetObjectItem(binDesc, "infinity"); + + if (!cJSON_IsNumber(start) || !cJSON_IsNumber(count) || !cJSON_IsBool(infinity)) { + snprintf(errMsg, msgLen, "%s", msg3); + return false; + } + + if (count->valueint <= 0 || count->valueint > 1000) { // limit count to 1000 + snprintf(errMsg, msgLen, "%s", msg4); + return false; + } + + if (isinf(start->valuedouble) || (width != NULL && isinf(width->valuedouble)) || + (factor != NULL && isinf(factor->valuedouble)) || (count != NULL && isinf(count->valuedouble))) { + snprintf(errMsg, msgLen, "%s", msg5); + return false; + } + + int32_t counter = (int32_t)count->valueint; + if (infinity->valueint == false) { + startIndex = 0; + numOfBins = counter + 1; + } else { + startIndex = 1; + numOfBins = counter + 3; + } + + intervals = taosMemoryCalloc(numOfBins, sizeof(double)); + if (cJSON_IsNumber(width) && factor == NULL && binType == LINEAR_BIN) { + // linear bin process + if (width->valuedouble == 0) { + snprintf(errMsg, msgLen, "%s", msg6); + taosMemoryFree(intervals); + return false; + } + for (int i = 0; i < counter + 1; ++i) { + intervals[startIndex] = start->valuedouble + i * width->valuedouble; + if (isinf(intervals[startIndex])) { + snprintf(errMsg, msgLen, "%s", msg5); + taosMemoryFree(intervals); + return false; + } + startIndex++; + } + } else if (cJSON_IsNumber(factor) && width == NULL && binType == LOG_BIN) { + // log bin process + if (start->valuedouble == 0) { + snprintf(errMsg, msgLen, "%s", msg7); + taosMemoryFree(intervals); + return false; + } + if (factor->valuedouble < 0 || factor->valuedouble == 0 || factor->valuedouble == 1) { + snprintf(errMsg, msgLen, "%s", msg8); + taosMemoryFree(intervals); + return false; + } + for (int i = 0; i < counter + 1; ++i) { + intervals[startIndex] = start->valuedouble * pow(factor->valuedouble, i * 1.0); + if (isinf(intervals[startIndex])) { + snprintf(errMsg, msgLen, "%s", msg5); + taosMemoryFree(intervals); + return false; + } + startIndex++; + } + } else { + snprintf(errMsg, msgLen, "%s", msg3); + taosMemoryFree(intervals); + return false; + } + + if (infinity->valueint == true) { + intervals[0] = -INFINITY; + intervals[numOfBins - 1] = INFINITY; + // in case of desc bin orders, -inf/inf should be swapped + ASSERT(numOfBins >= 4); + if (intervals[1] > intervals[numOfBins - 2]) { + TSWAP(intervals[0], intervals[numOfBins - 1]); + } + } + } else if (cJSON_IsArray(binDesc)) { /* user input bins */ + if (binType != USER_INPUT_BIN) { + snprintf(errMsg, msgLen, "%s", msg3); + return false; + } + numOfBins = cJSON_GetArraySize(binDesc); + intervals = taosMemoryCalloc(numOfBins, sizeof(double)); + cJSON* bin = binDesc->child; + if (bin == NULL) { + snprintf(errMsg, msgLen, "%s", msg3); + taosMemoryFree(intervals); + return false; + } + int i = 0; + while (bin) { + intervals[i] = bin->valuedouble; + if (!cJSON_IsNumber(bin)) { + snprintf(errMsg, msgLen, "%s", msg3); + taosMemoryFree(intervals); + return false; + } + if (i != 0 && intervals[i] <= intervals[i - 1]) { + snprintf(errMsg, msgLen, "%s", msg3); + taosMemoryFree(intervals); + return false; + } + bin = bin->next; + i++; + } + } else { + snprintf(errMsg, msgLen, "%s", msg3); + return false; + } + + taosMemoryFree(intervals); + return true; +} + static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList); if (4 != numOfParams) { @@ -814,6 +974,8 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } + int8_t binType; + char* binDesc; for (int32_t i = 1; i < numOfParams; ++i) { SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i); if (QUERY_NODE_VALUE != nodeType(pParamNode)) { @@ -824,6 +986,23 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l pValue->notReserved = true; + if (i == 1) { + binType = validateHistogramBinType(varDataVal(pValue->datum.p)); + if (binType == UNKNOWN_BIN) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "HISTOGRAM function binType parameter should be " + "\"user_input\", \"log_bin\" or \"linear_bin\""); + } + } + + if (i == 2) { + char errMsg[128] = {0}; + binDesc = varDataVal(pValue->datum.p); + if (!validateHistogramBinDesc(binDesc, binType, errMsg, (int32_t)sizeof(errMsg))) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, errMsg); + } + } + if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "HISTOGRAM function normalized parameter should be 0/1"); @@ -853,6 +1032,8 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32 return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } + int8_t binType; + char* binDesc; for (int32_t i = 1; i < numOfParams; ++i) { SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i); if (QUERY_NODE_VALUE != nodeType(pParamNode)) { @@ -863,6 +1044,23 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32 pValue->notReserved = true; + if (i == 1) { + binType = validateHistogramBinType(varDataVal(pValue->datum.p)); + if (binType == UNKNOWN_BIN) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "HISTOGRAM function binType parameter should be " + "\"user_input\", \"log_bin\" or \"linear_bin\""); + } + } + + if (i == 2) { + char errMsg[128] = {0}; + binDesc = varDataVal(pValue->datum.p); + if (!validateHistogramBinDesc(binDesc, binType, errMsg, (int32_t)sizeof(errMsg))) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, errMsg); + } + } + if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "HISTOGRAM function normalized parameter should be 0/1"); @@ -2105,7 +2303,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "histogram", .type = FUNCTION_TYPE_HISTOGRAM, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_FORBID_FILL_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC, .translateFunc = translateHistogram, .getEnvFunc = getHistogramFuncEnv, .initFunc = histogramFunctionSetup, diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 7ad7612e7e..262adc5d6f 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -260,7 +260,7 @@ bool fmIsSameInOutType(int32_t funcId) { } static int32_t getFuncInfo(SFunctionNode* pFunc) { - char msg[64] = {0}; + char msg[128] = {0}; return fmGetFuncInfo(pFunc, msg, sizeof(msg)); } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 842e4e8c51..890cad82ef 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -19,8 +19,8 @@ #include "querynodes.h" #include "taos.h" #include "taoserror.h" -#include "thash.h" #include "tdatablock.h" +#include "thash.h" static SNode* makeNode(ENodeType type, size_t size) { SNode* p = taosMemoryCalloc(1, size); @@ -1501,13 +1501,18 @@ typedef struct SCollectFuncsCxt { int32_t errCode; FFuncClassifier classifier; SNodeList* pFuncs; + SHashObj* pAliasName; } SCollectFuncsCxt; static EDealRes collectFuncs(SNode* pNode, void* pContext) { SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext; if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId) && !(((SExprNode*)pNode)->orderAlias)) { - pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode)); + SExprNode* pExpr = (SExprNode*)pNode; + if (NULL == taosHashGet(pCxt->pAliasName, pExpr->aliasName, strlen(pExpr->aliasName))) { + pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode)); + taosHashPut(pCxt->pAliasName, pExpr->aliasName, strlen(pExpr->aliasName), &pExpr, POINTER_BYTES); + } return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR); } return DEAL_RES_CONTINUE; @@ -1519,23 +1524,27 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifi } SCollectFuncsCxt cxt = { - .errCode = TSDB_CODE_SUCCESS, .classifier = classifier, .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs)}; + .errCode = TSDB_CODE_SUCCESS, + .classifier = classifier, + .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs), + .pAliasName = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, false)}; if (NULL == cxt.pFuncs) { return TSDB_CODE_OUT_OF_MEMORY; } *pFuncs = NULL; nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt); - if (TSDB_CODE_SUCCESS != cxt.errCode) { - nodesDestroyList(cxt.pFuncs); - return cxt.errCode; - } - if (LIST_LENGTH(cxt.pFuncs) > 0) { - *pFuncs = cxt.pFuncs; + if (TSDB_CODE_SUCCESS == cxt.errCode) { + if (LIST_LENGTH(cxt.pFuncs) > 0) { + *pFuncs = cxt.pFuncs; + } else { + nodesDestroyList(cxt.pFuncs); + } } else { nodesDestroyList(cxt.pFuncs); } + taosHashCleanup(cxt.pAliasName); - return TSDB_CODE_SUCCESS; + return cxt.errCode; } typedef struct SCollectSpecialNodesCxt { diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index c58e1d5dc0..4ef10ab86b 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -155,6 +155,7 @@ SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_ SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName, SToken* pNewColName); SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken* pTagName, SNode* pVal); +SNode* setAlterSuperTableType(SNode* pStmt); SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName); SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type); SNode* createShowStmtWithCond(SAstCreateContext* pCxt, ENodeType type, SNode* pDbName, SNode* pTbName, diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h index e829c9266f..896e2bc239 100644 --- a/source/libs/parser/inc/parUtil.h +++ b/source/libs/parser/inc/parUtil.h @@ -53,6 +53,7 @@ typedef struct SParseMetaCache { } SParseMetaCache; int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...); +int32_t generateSyntaxErrMsgExt(SMsgBuf* pBuf, int32_t errCode, const char* pFormat, ...); int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg); int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 7c4fa53536..c033b2c436 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -233,7 +233,7 @@ cmd ::= DROP TABLE multi_drop_clause(A). cmd ::= DROP STABLE exists_opt(A) full_table_name(B). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B); } cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; } -cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = A; } +cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = setAlterSuperTableType(A); } alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); } alter_table_clause(A) ::= @@ -260,7 +260,7 @@ multi_create_clause(A) ::= multi_create_clause(B) create_subtable_clause(C). create_subtable_clause(A) ::= not_exists_opt(B) full_table_name(C) USING full_table_name(D) - specific_tags_opt(E) TAGS NK_LP literal_list(F) NK_RP table_options(G). { A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); } + specific_tags_opt(E) TAGS NK_LP expression_list(F) NK_RP table_options(G). { A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); } %type multi_drop_clause { SNodeList* } %destructor multi_drop_clause { nodesDestroyList($$); } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 5580865bf5..23ba2fbc29 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1138,6 +1138,11 @@ SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken return createAlterTableStmtFinalize(pRealTable, pStmt); } +SNode* setAlterSuperTableType(SNode* pStmt) { + setNodeType(pStmt, QUERY_NODE_ALTER_SUPER_TABLE_STMT); + return pStmt; +} + SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) { CHECK_PARSER_STATUS(pCxt); if (!checkDbName(pCxt, pDbName, false)) { diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 99046a7223..3ec1c2b589 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -251,6 +251,10 @@ static int32_t collectMetaKeyFromAlterTable(SCollectMetaKeyCxt* pCxt, SAlterTabl return code; } +static int32_t collectMetaKeyFromAlterStable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) { + return reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache); +} + static int32_t collectMetaKeyFromUseDatabase(SCollectMetaKeyCxt* pCxt, SUseDatabaseStmt* pStmt) { return reserveDbVgVersionInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); } @@ -489,6 +493,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromDropTable(pCxt, (SDropTableStmt*)pStmt); case QUERY_NODE_ALTER_TABLE_STMT: return collectMetaKeyFromAlterTable(pCxt, (SAlterTableStmt*)pStmt); + case QUERY_NODE_ALTER_SUPER_TABLE_STMT: + return collectMetaKeyFromAlterStable(pCxt, (SAlterTableStmt*)pStmt); case QUERY_NODE_USE_DATABASE_STMT: return collectMetaKeyFromUseDatabase(pCxt, (SUseDatabaseStmt*)pStmt); case QUERY_NODE_CREATE_INDEX_STMT: diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index a76640d0b5..a286531588 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -48,6 +48,12 @@ pSql += sToken.n; \ } while (TK_NK_SPACE == sToken.type) +typedef struct SInsertParseBaseContext { + SParseContext* pComCxt; + char* pSql; + SMsgBuf msg; +} SInsertParseBaseContext; + typedef struct SInsertParseContext { SParseContext* pComCxt; // input char* pSql; // input @@ -1105,6 +1111,32 @@ static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName* return taosHashPut(pHash, pName, len, &pBackup, POINTER_BYTES); } +static int32_t skipParentheses(SInsertParseSyntaxCxt* pCxt) { + SToken sToken; + int32_t expectRightParenthesis = 1; + while (1) { + NEXT_TOKEN(pCxt->pSql, sToken); + if (TK_NK_LP == sToken.type) { + ++expectRightParenthesis; + } else if (TK_NK_RP == sToken.type && 0 == --expectRightParenthesis) { + break; + } + if (0 == sToken.n) { + return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL); + } + } + return TSDB_CODE_SUCCESS; +} + +static int32_t skipBoundColumns(SInsertParseSyntaxCxt* pCxt) { return skipParentheses(pCxt); } + +static int32_t ignoreBoundColumns(SInsertParseContext* pCxt) { + SInsertParseSyntaxCxt cxt = {.pComCxt = pCxt->pComCxt, .pSql = pCxt->pSql, .msg = pCxt->msg, .pMetaCache = NULL}; + int32_t code = skipBoundColumns(&cxt); + pCxt->pSql = cxt.pSql; + return code; +} + static int32_t skipUsingClause(SInsertParseSyntaxCxt* pCxt); // pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) @@ -1453,12 +1485,29 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { tNameGetFullDbName(&name, dbFName); CHECK_CODE(taosHashPut(pCxt->pDbFNameHashObj, dbFName, strlen(dbFName), dbFName, sizeof(dbFName))); + bool existedUsing = false; // USING clause + if (TK_USING == sToken.type) { + existedUsing = true; + CHECK_CODE(parseUsingClause(pCxt, &name, tbFName)); + NEXT_TOKEN(pCxt->pSql, sToken); + autoCreateTbl = true; + } + + char* pBoundColsStart = NULL; + if (TK_NK_LP == sToken.type) { + // pSql -> field1_name, ...) + pBoundColsStart = pCxt->pSql; + CHECK_CODE(ignoreBoundColumns(pCxt)); + // CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta))); + NEXT_TOKEN(pCxt->pSql, sToken); + } + if (TK_USING == sToken.type) { CHECK_CODE(parseUsingClause(pCxt, &name, tbFName)); NEXT_TOKEN(pCxt->pSql, sToken); autoCreateTbl = true; - } else { + } else if (!existedUsing) { CHECK_CODE(getTableMeta(pCxt, &name, dbFName)); } @@ -1467,10 +1516,11 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { sizeof(SSubmitBlk), getTableInfo(pCxt->pTableMeta).rowSize, pCxt->pTableMeta, &dataBuf, NULL, &pCxt->createTblReq)); - if (TK_NK_LP == sToken.type) { - // pSql -> field1_name, ...) + if (NULL != pBoundColsStart) { + char* pCurrPos = pCxt->pSql; + pCxt->pSql = pBoundColsStart; CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta))); - NEXT_TOKEN(pCxt->pSql, sToken); + pCxt->pSql = pCurrPos; } if (TK_VALUES == sToken.type) { @@ -1610,25 +1660,6 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery, SParseMetaCache return code; } -static int32_t skipParentheses(SInsertParseSyntaxCxt* pCxt) { - SToken sToken; - int32_t expectRightParenthesis = 1; - while (1) { - NEXT_TOKEN(pCxt->pSql, sToken); - if (TK_NK_LP == sToken.type) { - ++expectRightParenthesis; - } else if (TK_NK_RP == sToken.type && 0 == --expectRightParenthesis) { - break; - } - if (0 == sToken.n) { - return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL); - } - } - return TSDB_CODE_SUCCESS; -} - -static int32_t skipBoundColumns(SInsertParseSyntaxCxt* pCxt) { return skipParentheses(pCxt); } - // pSql -> (field1_value, ...) [(field1_value2, ...) ...] static int32_t skipValuesClause(SInsertParseSyntaxCxt* pCxt) { int32_t numOfRows = 0; @@ -1717,8 +1748,25 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) { SToken tbnameToken = sToken; NEXT_TOKEN(pCxt->pSql, sToken); + bool existedUsing = false; // USING clause if (TK_USING == sToken.type) { + existedUsing = true; + CHECK_CODE(collectAutoCreateTableMetaKey(pCxt, &tbnameToken)); + NEXT_TOKEN(pCxt->pSql, sToken); + CHECK_CODE(collectTableMetaKey(pCxt, &sToken)); + CHECK_CODE(skipUsingClause(pCxt)); + NEXT_TOKEN(pCxt->pSql, sToken); + } + + if (TK_NK_LP == sToken.type) { + // pSql -> field1_name, ...) + CHECK_CODE(skipBoundColumns(pCxt)); + NEXT_TOKEN(pCxt->pSql, sToken); + } + + if (TK_USING == sToken.type && !existedUsing) { + existedUsing = true; CHECK_CODE(collectAutoCreateTableMetaKey(pCxt, &tbnameToken)); NEXT_TOKEN(pCxt->pSql, sToken); CHECK_CODE(collectTableMetaKey(pCxt, &sToken)); @@ -1728,12 +1776,6 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) { CHECK_CODE(collectTableMetaKey(pCxt, &tbnameToken)); } - if (TK_NK_LP == sToken.type) { - // pSql -> field1_name, ...) - CHECK_CODE(skipBoundColumns(pCxt)); - NEXT_TOKEN(pCxt->pSql, sToken); - } - if (TK_VALUES == sToken.type) { // pSql -> (field1_value, ...) [(field1_value2, ...) ...] CHECK_CODE(skipValuesClause(pCxt)); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index fde33b71ff..5706d031cf 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -121,8 +121,8 @@ static int32_t getTableMetaImpl(STranslateContext* pCxt, const SName* pName, STa } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogGetTableMeta error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, - pName->tname); + parserError("0x%" PRIx64 " catalogGetTableMeta error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId, + tstrerror(code), pName->dbname, pName->tname); } return code; } @@ -150,8 +150,8 @@ static int32_t getTableCfg(STranslateContext* pCxt, const SName* pName, STableCf } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, - pName->tname); + parserError("0x%" PRIx64 " catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s", + pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname); } return code; } @@ -173,8 +173,8 @@ static int32_t refreshGetTableMeta(STranslateContext* pCxt, const char* pDbName, code = catalogRefreshGetTableMeta(pParCxt->pCatalog, &conn, &name, pMeta, false); } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogRefreshGetTableMeta error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pDbName, - pTableName); + parserError("0x%" PRIx64 " catalogRefreshGetTableMeta error, code:%s, dbName:%s, tbName:%s", + pCxt->pParseCxt->requestId, tstrerror(code), pDbName, pTableName); } return code; } @@ -196,7 +196,8 @@ static int32_t getDBVgInfoImpl(STranslateContext* pCxt, const SName* pName, SArr } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogGetDBVgInfo error, code:%s, dbFName:%s", tstrerror(code), fullDbName); + parserError("0x%" PRIx64 " catalogGetDBVgInfo error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId, + tstrerror(code), fullDbName); } return code; } @@ -227,8 +228,8 @@ static int32_t getTableHashVgroupImpl(STranslateContext* pCxt, const SName* pNam } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogGetTableHashVgroup error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, - pName->tname); + parserError("0x%" PRIx64 " catalogGetTableHashVgroup error, code:%s, dbName:%s, tbName:%s", + pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname); } return code; } @@ -251,7 +252,8 @@ static int32_t getDBVgVersion(STranslateContext* pCxt, const char* pDbFName, int } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogGetDBVgVersion error, code:%s, dbFName:%s", tstrerror(code), pDbFName); + parserError("0x%" PRIx64 " catalogGetDBVgVersion error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId, + tstrerror(code), pDbFName); } return code; } @@ -276,7 +278,8 @@ static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo } } if (TSDB_CODE_SUCCESS != code) { - parserError("catalogGetDBCfg error, code:%s, dbFName:%s", tstrerror(code), dbFname); + parserError("0x%" PRIx64 " catalogGetDBCfg error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId, tstrerror(code), + dbFname); } return code; } @@ -303,6 +306,10 @@ static int32_t getUdfInfo(STranslateContext* pCxt, SFunctionNode* pFunc) { pFunc->udfBufSize = funcInfo.bufSize; tFreeSFuncInfo(&funcInfo); } + if (TSDB_CODE_SUCCESS != code) { + parserError("0x%" PRIx64 " catalogGetUdfInfo error, code:%s, funcName:%s", pCxt->pParseCxt->requestId, + tstrerror(code), pFunc->functionName); + } return code; } @@ -323,7 +330,8 @@ static int32_t getTableIndex(STranslateContext* pCxt, const SName* pName, SArray code = catalogGetTableIndex(pParCxt->pCatalog, &conn, pName, pIndexes); } if (TSDB_CODE_SUCCESS != code) { - parserError("getTableIndex error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, pName->tname); + parserError("0x%" PRIx64 " getTableIndex error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId, + tstrerror(code), pName->dbname, pName->tname); } return code; } @@ -341,7 +349,7 @@ static int32_t getDnodeList(STranslateContext* pCxt, SArray** pDnodes) { code = catalogGetDnodeList(pParCxt->pCatalog, &conn, pDnodes); } if (TSDB_CODE_SUCCESS != code) { - parserError("getDnodeList error, code:%s", tstrerror(code)); + parserError("0x%" PRIx64 " getDnodeList error, code:%s", pCxt->pParseCxt->requestId, tstrerror(code)); } return code; } @@ -707,7 +715,7 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p } static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) { - if (isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + if (NULL == pCxt->pCurrStmt || isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName); } @@ -776,12 +784,144 @@ static int32_t parseBoolFromValueNode(STranslateContext* pCxt, SValueNode* pVal) } } -static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt) { - uint8_t precision = getPrecisionFromCurrStmt(pCxt->pCurrStmt, targetDt.precision); - pVal->node.resType.precision = precision; +static EDealRes translateDurationValue(STranslateContext* pCxt, SValueNode* pVal) { + if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, + pVal->node.resType.precision) != TSDB_CODE_SUCCESS) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int64_t*)&pVal->typeData = pVal->datum.i; + return DEAL_RES_CONTINUE; +} + +static EDealRes translateNormalValue(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt, bool strict) { + int32_t code = TSDB_CODE_SUCCESS; + switch (targetDt.type) { + case TSDB_DATA_TYPE_BOOL: + if (TSDB_CODE_SUCCESS != parseBoolFromValueNode(pCxt, pVal)) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(bool*)&pVal->typeData = pVal->datum.b; + break; + case TSDB_DATA_TYPE_TINYINT: { + code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_TINYINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int8_t*)&pVal->typeData = pVal->datum.i; + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_SMALLINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int16_t*)&pVal->typeData = pVal->datum.i; + break; + } + case TSDB_DATA_TYPE_INT: { + code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_INT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int32_t*)&pVal->typeData = pVal->datum.i; + break; + } + case TSDB_DATA_TYPE_BIGINT: { + code = toInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.i); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_BIGINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int64_t*)&pVal->typeData = pVal->datum.i; + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_UTINYINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(uint8_t*)&pVal->typeData = pVal->datum.u; + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_USMALLINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(uint16_t*)&pVal->typeData = pVal->datum.u; + break; + } + case TSDB_DATA_TYPE_UINT: { + code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_UINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(uint32_t*)&pVal->typeData = pVal->datum.u; + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + code = toUInteger(pVal->literal, strlen(pVal->literal), 10, &pVal->datum.u); + if (strict && (TSDB_CODE_SUCCESS != code || !IS_VALID_UBIGINT(pVal->datum.i))) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(uint64_t*)&pVal->typeData = pVal->datum.u; + break; + } + case TSDB_DATA_TYPE_FLOAT: { + pVal->datum.d = taosStr2Double(pVal->literal, NULL); + *(float*)&pVal->typeData = pVal->datum.d; + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + pVal->datum.d = taosStr2Double(pVal->literal, NULL); + *(double*)&pVal->typeData = pVal->datum.d; + break; + } + case TSDB_DATA_TYPE_VARCHAR: + case TSDB_DATA_TYPE_VARBINARY: { + pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1); + if (NULL == pVal->datum.p) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); + } + int32_t len = TMIN(targetDt.bytes - VARSTR_HEADER_SIZE, pVal->node.resType.bytes); + varDataSetLen(pVal->datum.p, len); + strncpy(varDataVal(pVal->datum.p), pVal->literal, len); + break; + } + case TSDB_DATA_TYPE_TIMESTAMP: { + if (TSDB_CODE_SUCCESS != parseTimeFromValueNode(pCxt, pVal)) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + *(int64_t*)&pVal->typeData = pVal->datum.i; + break; + } + case TSDB_DATA_TYPE_NCHAR: { + pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1); + if (NULL == pVal->datum.p) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); + } + + int32_t len = 0; + if (!taosMbsToUcs4(pVal->literal, strlen(pVal->literal), (TdUcs4*)varDataVal(pVal->datum.p), + targetDt.bytes - VARSTR_HEADER_SIZE, &len)) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } + varDataSetLen(pVal->datum.p, len); + break; + } + case TSDB_DATA_TYPE_DECIMAL: + case TSDB_DATA_TYPE_BLOB: + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + default: + break; + } + return DEAL_RES_CONTINUE; +} + +static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt, bool strict) { if (pVal->placeholderNo > 0 || pVal->isNull) { return DEAL_RES_CONTINUE; } + if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) { // TODO // pVal->node.resType = targetDt; @@ -789,114 +929,18 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD pVal->isNull = true; return DEAL_RES_CONTINUE; } - if (pVal->isDuration) { - if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, precision) != - TSDB_CODE_SUCCESS) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); - } - *(int64_t*)&pVal->typeData = pVal->datum.i; - } else { - switch (targetDt.type) { - case TSDB_DATA_TYPE_NULL: - break; - case TSDB_DATA_TYPE_BOOL: - if (TSDB_CODE_SUCCESS != parseBoolFromValueNode(pCxt, pVal)) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); - } - *(bool*)&pVal->typeData = pVal->datum.b; - break; - case TSDB_DATA_TYPE_TINYINT: { - pVal->datum.i = taosStr2Int64(pVal->literal, NULL, 10); - *(int8_t*)&pVal->typeData = pVal->datum.i; - break; - } - case TSDB_DATA_TYPE_SMALLINT: { - pVal->datum.i = taosStr2Int64(pVal->literal, NULL, 10); - *(int16_t*)&pVal->typeData = pVal->datum.i; - break; - } - case TSDB_DATA_TYPE_INT: { - pVal->datum.i = taosStr2Int64(pVal->literal, NULL, 10); - *(int32_t*)&pVal->typeData = pVal->datum.i; - break; - } - case TSDB_DATA_TYPE_BIGINT: { - pVal->datum.i = taosStr2Int64(pVal->literal, NULL, 10); - *(int64_t*)&pVal->typeData = pVal->datum.i; - break; - } - case TSDB_DATA_TYPE_UTINYINT: { - pVal->datum.u = taosStr2UInt64(pVal->literal, NULL, 10); - *(uint8_t*)&pVal->typeData = pVal->datum.u; - break; - } - case TSDB_DATA_TYPE_USMALLINT: { - pVal->datum.u = taosStr2UInt64(pVal->literal, NULL, 10); - *(uint16_t*)&pVal->typeData = pVal->datum.u; - break; - } - case TSDB_DATA_TYPE_UINT: { - pVal->datum.u = taosStr2UInt64(pVal->literal, NULL, 10); - *(uint32_t*)&pVal->typeData = pVal->datum.u; - break; - } - case TSDB_DATA_TYPE_UBIGINT: { - pVal->datum.u = taosStr2UInt64(pVal->literal, NULL, 10); - *(uint64_t*)&pVal->typeData = pVal->datum.u; - break; - } - case TSDB_DATA_TYPE_FLOAT: { - pVal->datum.d = taosStr2Double(pVal->literal, NULL); - *(float*)&pVal->typeData = pVal->datum.d; - break; - } - case TSDB_DATA_TYPE_DOUBLE: { - pVal->datum.d = taosStr2Double(pVal->literal, NULL); - *(double*)&pVal->typeData = pVal->datum.d; - break; - } - case TSDB_DATA_TYPE_VARCHAR: - case TSDB_DATA_TYPE_VARBINARY: { - pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1); - if (NULL == pVal->datum.p) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); - } - int32_t len = TMIN(targetDt.bytes - VARSTR_HEADER_SIZE, pVal->node.resType.bytes); - varDataSetLen(pVal->datum.p, len); - strncpy(varDataVal(pVal->datum.p), pVal->literal, len); - break; - } - case TSDB_DATA_TYPE_TIMESTAMP: { - if (TSDB_CODE_SUCCESS != parseTimeFromValueNode(pCxt, pVal)) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); - } - *(int64_t*)&pVal->typeData = pVal->datum.i; - break; - } - case TSDB_DATA_TYPE_NCHAR: { - pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1); - if (NULL == pVal->datum.p) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); - } - int32_t len = 0; - if (!taosMbsToUcs4(pVal->literal, strlen(pVal->literal), (TdUcs4*)varDataVal(pVal->datum.p), - targetDt.bytes - VARSTR_HEADER_SIZE, &len)) { - return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); - } - varDataSetLen(pVal->datum.p, len); - break; - } - case TSDB_DATA_TYPE_DECIMAL: - case TSDB_DATA_TYPE_BLOB: - return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); - default: - break; - } + pVal->node.resType.precision = getPrecisionFromCurrStmt(pCxt->pCurrStmt, targetDt.precision); + + EDealRes res = DEAL_RES_CONTINUE; + if (pVal->isDuration) { + res = translateDurationValue(pCxt, pVal); + } else { + res = translateNormalValue(pCxt, pVal, targetDt, strict); } pVal->node.resType = targetDt; pVal->translate = true; - return DEAL_RES_CONTINUE; + return res; } static int32_t calcTypeBytes(SDataType dt) { @@ -912,7 +956,7 @@ static int32_t calcTypeBytes(SDataType dt) { static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { SDataType dt = pVal->node.resType; dt.bytes = calcTypeBytes(dt); - return translateValueImpl(pCxt, pVal, dt); + return translateValueImpl(pCxt, pVal, dt, false); } static bool isMultiResFunc(SNode* pNode) { @@ -1248,6 +1292,22 @@ static int32_t translateForbidGroupByFunc(STranslateContext* pCxt, SFunctionNode return TSDB_CODE_SUCCESS; } +static int32_t translateRepeatScanFunc(STranslateContext* pCxt, SFunctionNode* pFunc) { + if (!fmIsRepeatScanFunc(pFunc->funcId)) { + return TSDB_CODE_SUCCESS; + } + if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + SNode* pTable = ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable; + if (QUERY_NODE_REAL_TABLE == nodeType(pTable) && + (TSDB_CHILD_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType || + TSDB_NORMAL_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType)) { + return TSDB_CODE_SUCCESS; + } + } + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE, + "%s is only supported in single table query", pFunc->functionName); +} + static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) { if (NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt)) { SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt; @@ -1370,6 +1430,9 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p if (TSDB_CODE_SUCCESS == code) { code = translateForbidGroupByFunc(pCxt, pFunc); } + if (TSDB_CODE_SUCCESS == code) { + code = translateRepeatScanFunc(pCxt, pFunc); + } if (TSDB_CODE_SUCCESS == code) { setFuncClassification(pCxt->pCurrStmt, pFunc); } @@ -2760,6 +2823,7 @@ static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelet } static int32_t translateDelete(STranslateContext* pCxt, SDeleteStmt* pDelete) { + pCxt->pCurrStmt = (SNode*)pDelete; int32_t code = translateFrom(pCxt, pDelete->pFromTable); if (TSDB_CODE_SUCCESS == code) { code = translateDeleteWhere(pCxt, pDelete); @@ -3110,6 +3174,7 @@ static void buildAlterDbReq(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt, pReq->buffer = pStmt->pOptions->buffer; pReq->pageSize = -1; pReq->pages = pStmt->pOptions->pages; + pReq->lastRowMem = -1; pReq->daysPerFile = -1; pReq->daysToKeep0 = pStmt->pOptions->keep[0]; pReq->daysToKeep1 = pStmt->pOptions->keep[1]; @@ -3187,13 +3252,30 @@ static bool validRollupFunc(const char* pFunc) { return false; } -static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs) { +static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs, bool createStable, + SDbCfgInfo* pDbCfg) { if (NULL == pFuncs) { + if (NULL != pDbCfg->pRetensions) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, + "To create a super table in a database with the retensions parameter configured, " + "the 'ROLLUP' option must be present"); + } return TSDB_CODE_SUCCESS; } - if (1 != LIST_LENGTH(pFuncs) || !validRollupFunc(((SFunctionNode*)nodesListGetNode(pFuncs, 0))->functionName)) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROLLUP_OPTION); + if (!createStable || NULL == pDbCfg->pRetensions) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, + "Invalid option rollup: Only supported for create super table in databases " + "configured with the 'RETENTIONS' option"); + } + if (1 != LIST_LENGTH(pFuncs)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROLLUP_OPTION, + "Invalid option rollup: only one function is allowed"); + } + const char* pFunc = ((SFunctionNode*)nodesListGetNode(pFuncs, 0))->functionName; + if (!validRollupFunc(pFunc)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROLLUP_OPTION, + "Invalid option rollup: %s function is not supported", pFunc); } return TSDB_CODE_SUCCESS; } @@ -3219,8 +3301,8 @@ static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SN code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); } if (TSDB_CODE_SUCCESS == code) { - 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)) { + if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_BINARY_LEN) || + (TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_NCHAR_LEN)) { code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); } } @@ -3241,11 +3323,11 @@ static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SN return code; } -static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SNodeList* pCols) { +static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, int32_t ntags, SNodeList* pCols) { int32_t ncols = LIST_LENGTH(pCols); if (ncols < TSDB_MIN_COLUMNS) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMNS_NUM); - } else if (ncols > TSDB_MAX_COLUMNS) { + } else if (ncols + ntags > TSDB_MAX_COLUMNS) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS); } @@ -3301,7 +3383,7 @@ static int32_t checkTableSchema(STranslateContext* pCxt, SCreateTableStmt* pStmt int32_t code = checkTableTagsSchema(pCxt, pHash, pStmt->pTags); if (TSDB_CODE_SUCCESS == code) { - code = checkTableColsSchema(pCxt, pHash, pStmt->pCols); + code = checkTableColsSchema(pCxt, pHash, LIST_LENGTH(pStmt->pTags), pStmt->pCols); } taosHashCleanup(pHash); @@ -3330,11 +3412,18 @@ static int32_t getTableMaxDelayOption(STranslateContext* pCxt, SValueNode* pVal, pMaxDelay); } -static int32_t checkTableMaxDelayOption(STranslateContext* pCxt, STableOptions* pOptions) { +static int32_t checkTableMaxDelayOption(STranslateContext* pCxt, STableOptions* pOptions, bool createStable, + SDbCfgInfo* pDbCfg) { if (NULL == pOptions->pMaxDelay) { return TSDB_CODE_SUCCESS; } + if (!createStable || NULL == pDbCfg->pRetensions) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, + "Invalid option maxdelay: Only supported for create super table in databases " + "configured with the 'RETENTIONS' option"); + } + if (LIST_LENGTH(pOptions->pMaxDelay) > 2) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, "maxdelay"); } @@ -3353,11 +3442,18 @@ static int32_t getTableWatermarkOption(STranslateContext* pCxt, SValueNode* pVal pMaxDelay); } -static int32_t checkTableWatermarkOption(STranslateContext* pCxt, STableOptions* pOptions) { +static int32_t checkTableWatermarkOption(STranslateContext* pCxt, STableOptions* pOptions, bool createStable, + SDbCfgInfo* pDbCfg) { if (NULL == pOptions->pWatermark) { return TSDB_CODE_SUCCESS; } + if (!createStable || NULL == pDbCfg->pRetensions) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, + "Invalid option watermark: Only supported for create super table in databases " + "configured with the 'RETENTIONS' option"); + } + if (LIST_LENGTH(pOptions->pWatermark) > 2) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TABLE_OPTION, "watermark"); } @@ -3371,13 +3467,20 @@ static int32_t checkTableWatermarkOption(STranslateContext* pCxt, STableOptions* return code; } -static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) { - int32_t code = checkTableMaxDelayOption(pCxt, pStmt->pOptions); - if (TSDB_CODE_SUCCESS == code) { - code = checkTableWatermarkOption(pCxt, pStmt->pOptions); +static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt, bool createStable) { + int32_t code = TSDB_CODE_SUCCESS; + SDbCfgInfo dbCfg = {0}; + if (createStable) { + code = getDBCfg(pCxt, pStmt->dbName, &dbCfg); } if (TSDB_CODE_SUCCESS == code) { - code = checkTableRollupOption(pCxt, pStmt->pOptions->pRollupFuncs); + code = checkTableMaxDelayOption(pCxt, pStmt->pOptions, createStable, &dbCfg); + } + if (TSDB_CODE_SUCCESS == code) { + code = checkTableWatermarkOption(pCxt, pStmt->pOptions, createStable, &dbCfg); + } + if (TSDB_CODE_SUCCESS == code) { + code = checkTableRollupOption(pCxt, pStmt->pOptions->pRollupFuncs, createStable, &dbCfg); } if (TSDB_CODE_SUCCESS == code) { code = checkTableSmaOption(pCxt, pStmt); @@ -3656,7 +3759,7 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) { SMCreateStbReq createReq = {0}; - int32_t code = checkCreateTable(pCxt, pStmt); + int32_t code = checkCreateTable(pCxt, pStmt, true); if (TSDB_CODE_SUCCESS == code) { code = buildCreateStbReq(pCxt, pStmt, &createReq); } @@ -3743,12 +3846,24 @@ static int32_t buildAlterSuperTableReq(STranslateContext* pCxt, SAlterTableStmt* return TSDB_CODE_SUCCESS; } -static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) { +static SSchema* getColSchema(STableMeta* pTableMeta, const char* pColName) { int32_t numOfFields = getNumOfTags(pTableMeta) + getNumOfColumns(pTableMeta); for (int32_t i = 0; i < numOfFields; ++i) { - SSchema* pTagSchema = pTableMeta->schema + i; - if (0 == strcmp(pTagName, pTagSchema->name)) { - return pTagSchema; + SSchema* pSchema = pTableMeta->schema + i; + if (0 == strcmp(pColName, pSchema->name)) { + return pSchema; + } + } + return NULL; +} + +static SSchema* getTagSchema(STableMeta* pTableMeta, const char* pTagName) { + int32_t numOfTags = getNumOfTags(pTableMeta); + SSchema* pTagsSchema = getTableTagSchema(pTableMeta); + for (int32_t i = 0; i < numOfTags; ++i) { + SSchema* pSchema = pTagsSchema + i; + if (0 == strcmp(pTagName, pSchema->name)) { + return pSchema; } } return NULL; @@ -3756,22 +3871,48 @@ static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) { static int32_t checkAlterSuperTable(STranslateContext* pCxt, SAlterTableStmt* pStmt) { if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType || TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME == pStmt->alterType) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, + "Set tag value only available for child table"); + } + + if (pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_OPTIONS && -1 != pStmt->pOptions->ttl) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); } + + if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); + } + + if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON); + } + + STableMeta* pTableMeta = NULL; + int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + SSchema* pTagsSchema = getTableTagSchema(pTableMeta); + if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON && + (pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG || + pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); + } + if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType || TSDB_ALTER_TABLE_UPDATE_TAG_BYTES == pStmt->alterType) { - STableMeta* pTableMeta = NULL; - int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta); - if (TSDB_CODE_SUCCESS == code) { - SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); - if (NULL == pSchema) { - code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); - } else if (!IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type != pStmt->dataType.type || - pSchema->bytes >= calcTypeBytes(pStmt->dataType)) { - code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL); - } + if (TSDB_SUPER_TABLE != pTableMeta->tableType) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, "Table is not super table"); + } + + SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); + if (NULL == pSchema) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); + } else if (!IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type != pStmt->dataType.type || + pSchema->bytes >= calcTypeBytes(pStmt->dataType)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL); } - return code; } return TSDB_CODE_SUCCESS; } @@ -4198,6 +4339,39 @@ static void getSourceDatabase(SNode* pStmt, int32_t acctId, char* pDbFName) { tNameGetFullDbName(&name, pDbFName); } +static int32_t addWstartTsToCreateStreamQuery(SNode* pStmt) { + SSelectStmt* pSelect = (SSelectStmt*)pStmt; + SNode* pProj = nodesListGetNode(pSelect->pProjectionList, 0); + if (NULL == pSelect->pWindow || + (QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp("_wstartts", ((SFunctionNode*)pProj)->functionName))) { + return TSDB_CODE_SUCCESS; + } + SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); + if (NULL == pFunc) { + return TSDB_CODE_OUT_OF_MEMORY; + } + strcpy(pFunc->functionName, "_wstartts"); + strcpy(pFunc->node.aliasName, pFunc->functionName); + int32_t code = nodesListPushFront(pSelect->pProjectionList, (SNode*)pFunc); + if (TSDB_CODE_SUCCESS != code) { + nodesDestroyNode((SNode*)pFunc); + } + return code; +} + +static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SNode* pStmt, SCMCreateStreamReq* pReq) { + pCxt->createStream = true; + int32_t code = addWstartTsToCreateStreamQuery(pStmt); + if (TSDB_CODE_SUCCESS == code) { + code = translateQuery(pCxt, pStmt); + } + if (TSDB_CODE_SUCCESS == code) { + getSourceDatabase(pStmt, pCxt->pParseCxt->acctId, pReq->sourceDB); + code = nodesNodeToString(pStmt, false, &pReq->ast, NULL); + } + return code; +} + static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) { pReq->igExists = pStmt->ignoreExists; @@ -4211,13 +4385,7 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt* tNameExtractFullName(&name, pReq->targetStbFullName); } - pCxt->createStream = true; - int32_t code = translateQuery(pCxt, pStmt->pQuery); - if (TSDB_CODE_SUCCESS == code) { - getSourceDatabase(pStmt->pQuery, pCxt->pParseCxt->acctId, pReq->sourceDB); - code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL); - } - + int32_t code = buildCreateStreamQuery(pCxt, pStmt->pQuery, pReq); if (TSDB_CODE_SUCCESS == code) { pReq->sql = strdup(pCxt->pParseCxt->pSql); if (NULL == pReq->sql) { @@ -4455,6 +4623,7 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { code = translateDropSuperTable(pCxt, (SDropSuperTableStmt*)pNode); break; case QUERY_NODE_ALTER_TABLE_STMT: + case QUERY_NODE_ALTER_SUPER_TABLE_STMT: code = translateAlterSuperTable(pCxt, (SAlterTableStmt*)pNode); break; case QUERY_NODE_CREATE_USER_STMT: @@ -5165,7 +5334,7 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt* static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) { SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot; - int32_t code = checkCreateTable(pCxt, pStmt); + int32_t code = checkCreateTable(pCxt, pStmt, false); SVgroupInfo info = {0}; if (TSDB_CODE_SUCCESS == code) { code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info); @@ -5222,30 +5391,62 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S } } -static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* pFunc, SValueNode** pVal) { - int32_t code = getFuncInfo(pCxt, pFunc); - if (TSDB_CODE_SUCCESS == code) { - code = scalarCalculateConstants((SNode*)pFunc, (SNode**)pVal); - } - return code; -} - static SDataType schemaToDataType(uint8_t precision, SSchema* pSchema) { SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = precision, .scale = 0}; return dt; } -static int32_t translateTagVal(STranslateContext* pCxt, uint8_t precision, SSchema* pSchema, SNode* pNode, - SValueNode** pVal) { - if (QUERY_NODE_FUNCTION == nodeType(pNode)) { - return createValueFromFunction(pCxt, (SFunctionNode*)pNode, pVal); - } else if (QUERY_NODE_VALUE == nodeType(pNode)) { - return (DEAL_RES_ERROR == translateValueImpl(pCxt, (SValueNode*)pNode, schemaToDataType(precision, pSchema)) - ? pCxt->errCode - : TSDB_CODE_SUCCESS); +static int32_t createCastFuncForTag(STranslateContext* pCxt, SNode* pNode, SDataType dt, SNode** pCast) { + SNode* pExpr = nodesCloneNode(pNode); + if (NULL == pExpr) { + return TSDB_CODE_OUT_OF_MEMORY; + } + int32_t code = translateExpr(pCxt, &pExpr); + if (TSDB_CODE_SUCCESS == code) { + code = createCastFunc(pCxt, pExpr, dt, pCast); + } + if (TSDB_CODE_SUCCESS != code) { + nodesDestroyNode(pExpr); + } + return code; +} + +static int32_t createTagValFromExpr(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) { + SNode* pCast = NULL; + int32_t code = createCastFuncForTag(pCxt, pNode, targetDt, &pCast); + SNode* pNew = NULL; + if (TSDB_CODE_SUCCESS == code) { + code = scalarCalculateConstants(pCast, &pNew); + } + if (TSDB_CODE_SUCCESS == code) { + pCast = pNew; + if (QUERY_NODE_VALUE != nodeType(pCast)) { + code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName); + } + } + + if (TSDB_CODE_SUCCESS == code) { + *pVal = (SValueNode*)pCast; } else { - // return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName); - return TSDB_CODE_FAILED; + nodesDestroyNode(pCast); + } + return code; +} + +static int32_t createTagValFromVal(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) { + *pVal = (SValueNode*)nodesCloneNode(pNode); + if (NULL == *pVal) { + return TSDB_CODE_OUT_OF_MEMORY; + } + return DEAL_RES_ERROR == translateValueImpl(pCxt, *pVal, targetDt, true) ? pCxt->errCode : TSDB_CODE_SUCCESS; +} + +static int32_t createTagVal(STranslateContext* pCxt, uint8_t precision, SSchema* pSchema, SNode* pNode, + SValueNode** pVal) { + if (QUERY_NODE_VALUE == nodeType(pNode)) { + return createTagValFromVal(pCxt, schemaToDataType(precision, pSchema), pNode, pVal); + } else { + return createTagValFromExpr(pCxt, schemaToDataType(precision, pSchema), pNode, pVal); } } @@ -5285,56 +5486,45 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla if (NULL == pTagArray) { return TSDB_CODE_OUT_OF_MEMORY; } - int32_t code = TSDB_CODE_SUCCESS; - SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta); - SNode * pTag = NULL, *pNode = NULL; - bool isJson = false; + + int32_t code = TSDB_CODE_SUCCESS; + + bool isJson = false; + SNodeList* pVals = NULL; + SNode * pTag = NULL, *pNode = NULL; FORBOTH(pTag, pStmt->pSpecificTags, pNode, pStmt->pValsOfTags) { SColumnNode* pCol = (SColumnNode*)pTag; - SSchema* pSchema = NULL; - for (int32_t i = 0; i < numOfTags; ++i) { - if (0 == strcmp(pCol->colName, pTagSchema[i].name)) { - pSchema = pTagSchema + i; - break; - } - } + SSchema* pSchema = getTagSchema(pSuperTableMeta, pCol->colName); if (NULL == pSchema) { code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, pCol->colName); - goto end; } SValueNode* pVal = NULL; - code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal); - if (TSDB_CODE_SUCCESS != code) { - goto end; + if (TSDB_CODE_SUCCESS == code) { + code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal); } - - if (NULL == pVal) { - pVal = (SValueNode*)pNode; - } else { - REPLACE_LIST2_NODE(pVal); - } - - if (pSchema->type == TSDB_DATA_TYPE_JSON) { - isJson = true; - code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag); - } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) { - code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray); - } - } - - if (!isJson) code = tTagNew(pTagArray, 1, false, ppTag); - -end: - if (isJson) { - for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) { - STagVal* p = (STagVal*)taosArrayGet(pTagArray, i); - if (IS_VAR_DATA_TYPE(p->type)) { - taosMemoryFree(p->pData); + if (TSDB_CODE_SUCCESS == code) { + if (pSchema->type == TSDB_DATA_TYPE_JSON) { + isJson = true; + code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag); + } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) { + code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray); } } + if (TSDB_CODE_SUCCESS == code) { + code = nodesListMakeAppend(&pVals, (SNode*)pVal); + } + if (TSDB_CODE_SUCCESS != code) { + break; + } } + + if (TSDB_CODE_SUCCESS == code && !isJson) { + code = tTagNew(pTagArray, 1, false, ppTag); + } + + nodesDestroyList(pVals); taosArrayDestroy(pTagArray); - return TSDB_CODE_SUCCESS; + return code; } static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta, @@ -5343,64 +5533,52 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED); } - SSchema* pTagSchemas = getTableTagSchema(pSuperTableMeta); - SNode* pNode; - int32_t code = TSDB_CODE_SUCCESS; - int32_t index = 0; - SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal)); - if (!pTagArray) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_TSC_OUT_OF_MEMORY); + SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal)); + if (NULL == pTagArray) { + return TSDB_CODE_OUT_OF_MEMORY; } - bool isJson = false; + int32_t code = TSDB_CODE_SUCCESS; + + bool isJson = false; + int32_t index = 0; + SSchema* pTagSchemas = getTableTagSchema(pSuperTableMeta); + SNodeList* pVals = NULL; + SNode* pNode; FOREACH(pNode, pStmt->pValsOfTags) { SValueNode* pVal = NULL; SSchema* pTagSchema = pTagSchemas + index; - code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal); + code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal); + if (TSDB_CODE_SUCCESS == code) { + if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { + isJson = true; + code = buildJsonTagVal(pCxt, pTagSchema, pVal, pTagArray, ppTag); + } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) { + char* tmpVal = nodesGetValueFromNode(pVal); + STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + if (IS_VAR_DATA_TYPE(pTagSchema->type)) { + val.pData = varDataVal(tmpVal); + val.nData = varDataLen(tmpVal); + } else { + memcpy(&val.i64, tmpVal, pTagSchema->bytes); + } + taosArrayPush(pTagArray, &val); + } + } + if (TSDB_CODE_SUCCESS == code) { + code = nodesListMakeAppend(&pVals, (SNode*)pVal); + } if (TSDB_CODE_SUCCESS != code) { - goto end; - } - if (NULL == pVal) { - pVal = (SValueNode*)pNode; - } else { - REPLACE_NODE(pVal); - } - if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { - if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { - code = buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal); - goto end; - } - - isJson = true; - code = parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf); - if (code != TSDB_CODE_SUCCESS) { - goto end; - } - } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) { - char* tmpVal = nodesGetValueFromNode(pVal); - STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - if (IS_VAR_DATA_TYPE(pTagSchema->type)) { - val.pData = varDataVal(tmpVal); - val.nData = varDataLen(tmpVal); - } else { - memcpy(&val.i64, tmpVal, pTagSchema->bytes); - } - taosArrayPush(pTagArray, &val); + break; } ++index; } - if (!isJson) code = tTagNew(pTagArray, 1, false, ppTag); -end: - if (isJson) { - for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) { - STagVal* p = (STagVal*)taosArrayGet(pTagArray, i); - if (IS_VAR_DATA_TYPE(p->type)) { - taosMemoryFree(p->pData); - } - } + if (TSDB_CODE_SUCCESS == code && !isJson) { + code = tTagNew(pTagArray, 1, false, ppTag); } + nodesDestroyList(pVals); taosArrayDestroy(pTagArray); return code; } @@ -5644,7 +5822,7 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS } SDataType targetDt = schemaToDataType(pTableMeta->tableInfo.precision, pSchema); - if (DEAL_RES_ERROR == translateValueImpl(pCxt, pStmt->pVal, targetDt)) { + if (DEAL_RES_ERROR == translateValueImpl(pCxt, pStmt->pVal, targetDt, true)) { return pCxt->errCode; } @@ -5898,15 +6076,6 @@ static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* p } if (TSDB_SUPER_TABLE == pTableMeta->tableType) { - SSchema* pTagsSchema = getTableTagSchema(pTableMeta); - if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON && - (pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG || - pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); - } - if (pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_OPTIONS && -1 != pStmt->pOptions->ttl) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); - } return TSDB_CODE_SUCCESS; } else if (TSDB_CHILD_TABLE != pTableMeta->tableType && TSDB_NORMAL_TABLE != pTableMeta->tableType) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); @@ -5929,10 +6098,6 @@ static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* p static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) { SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot; - if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); - } - if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON); } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 168e51a2bb..69917ad7f9 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -215,13 +215,21 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) { return errCode; } +int32_t generateSyntaxErrMsgExt(SMsgBuf* pBuf, int32_t errCode, const char* pFormat, ...) { + va_list vArgList; + va_start(vArgList, pFormat); + vsnprintf(pBuf->buf, pBuf->len, pFormat, vArgList); + va_end(vArgList); + return errCode; +} + int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) { strncpy(pBuf->buf, msg, pBuf->len); return TSDB_CODE_TSC_INVALID_OPERATION; } int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) { - if(pBuf == NULL) return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; + if (pBuf == NULL) return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; const char* msgFormat1 = "syntax error near \'%s\'"; const char* msgFormat2 = "syntax error near \'%s\' (%s)"; const char* msgFormat3 = "%s"; diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index b50a26e829..fcf4d69a66 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -216,638 +216,596 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2612) +#define YY_ACTTAB_COUNT (2401) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 425, 69, 426, 1479, 433, 1679, 426, 1479, 1749, 1780, - /* 10 */ 1570, 318, 39, 37, 115, 1749, 555, 521, 335, 1746, - /* 20 */ 327, 1746, 1242, 1574, 330, 374, 1746, 1676, 40, 38, - /* 30 */ 36, 35, 34, 1317, 101, 1240, 1568, 100, 99, 98, - /* 40 */ 97, 96, 95, 94, 93, 92, 1742, 1748, 1742, 1748, - /* 50 */ 1625, 1626, 1762, 1742, 1748, 520, 1312, 573, 61, 573, - /* 60 */ 14, 1007, 151, 1006, 573, 1905, 1248, 569, 990, 39, - /* 70 */ 37, 1380, 1444, 1750, 491, 1618, 461, 327, 157, 1242, - /* 80 */ 1780, 1509, 1902, 1, 1746, 569, 528, 489, 552, 487, - /* 90 */ 1317, 1008, 1240, 1732, 84, 551, 110, 109, 108, 107, - /* 100 */ 106, 105, 104, 103, 102, 652, 211, 120, 994, 995, - /* 110 */ 532, 1742, 1748, 1312, 119, 1571, 569, 14, 442, 1319, - /* 120 */ 1320, 1793, 573, 1248, 87, 1763, 554, 1765, 1766, 550, - /* 130 */ 42, 573, 507, 60, 1839, 73, 1905, 60, 300, 1835, - /* 140 */ 2, 522, 339, 477, 476, 1624, 1626, 655, 475, 1904, - /* 150 */ 1905, 116, 472, 1902, 117, 471, 470, 469, 528, 1384, - /* 160 */ 58, 263, 652, 159, 1243, 1266, 1241, 1902, 530, 153, - /* 170 */ 1847, 1848, 1905, 1852, 493, 149, 1319, 1320, 1556, 43, - /* 180 */ 645, 641, 637, 633, 261, 157, 119, 1720, 1442, 1902, - /* 190 */ 1246, 1247, 517, 1295, 1296, 1298, 1299, 1300, 1301, 1302, - /* 200 */ 547, 571, 1310, 1311, 1313, 1314, 1315, 1316, 1318, 1321, - /* 210 */ 85, 33, 32, 255, 1905, 40, 38, 36, 35, 34, - /* 220 */ 204, 1243, 160, 1241, 11, 10, 117, 157, 1631, 30, - /* 230 */ 241, 1902, 33, 32, 353, 332, 40, 38, 36, 35, - /* 240 */ 34, 154, 1847, 1848, 1629, 1852, 566, 1246, 1247, 344, - /* 250 */ 1295, 1296, 1298, 1299, 1300, 1301, 1302, 547, 571, 1310, - /* 260 */ 1311, 1313, 1314, 1315, 1316, 1318, 1321, 39, 37, 160, - /* 270 */ 523, 518, 160, 605, 331, 327, 160, 1242, 213, 71, - /* 280 */ 306, 1267, 138, 559, 301, 1557, 570, 1411, 1317, 1905, - /* 290 */ 1240, 1581, 129, 128, 602, 601, 600, 111, 570, 1215, - /* 300 */ 424, 206, 157, 428, 463, 1905, 1902, 1353, 1280, 162, - /* 310 */ 1905, 1312, 246, 247, 1579, 14, 1339, 140, 158, 1456, - /* 320 */ 570, 1248, 1902, 1903, 39, 37, 1579, 1902, 477, 476, - /* 330 */ 380, 567, 327, 475, 1242, 1506, 116, 472, 2, 1297, - /* 340 */ 471, 470, 469, 1267, 442, 1317, 60, 1240, 1579, 1098, + /* 0 */ 31, 256, 84, 425, 544, 426, 1479, 141, 1442, 1780, + /* 10 */ 1749, 1536, 40, 38, 1570, 117, 433, 537, 426, 1479, + /* 20 */ 334, 1746, 1242, 1571, 374, 1746, 41, 39, 37, 36, + /* 30 */ 35, 547, 120, 1317, 101, 1240, 380, 100, 99, 98, + /* 40 */ 97, 96, 95, 94, 93, 92, 1267, 1742, 1748, 323, + /* 50 */ 1267, 1742, 1748, 549, 69, 536, 1312, 1762, 507, 565, + /* 60 */ 14, 1268, 61, 565, 1377, 1905, 1248, 115, 344, 40, + /* 70 */ 38, 1380, 118, 298, 544, 520, 1574, 334, 157, 1242, + /* 80 */ 1467, 442, 1902, 1, 547, 1780, 162, 246, 1847, 543, + /* 90 */ 1317, 542, 1240, 572, 1905, 430, 11, 10, 1732, 1905, + /* 100 */ 571, 1264, 120, 1579, 1466, 652, 547, 159, 211, 1905, + /* 110 */ 1762, 1902, 157, 1312, 549, 1557, 1902, 14, 1269, 1319, + /* 120 */ 1320, 1732, 157, 1248, 339, 1793, 1902, 1624, 1626, 87, + /* 130 */ 1763, 574, 1765, 1766, 570, 60, 565, 73, 1780, 1839, + /* 140 */ 2, 60, 118, 301, 1835, 1732, 572, 43, 216, 1140, + /* 150 */ 1141, 1732, 520, 571, 1905, 1905, 546, 153, 1847, 1848, + /* 160 */ 491, 1852, 652, 111, 1243, 1631, 1241, 1904, 159, 44, + /* 170 */ 463, 1902, 1902, 489, 442, 487, 1319, 1320, 1793, 1353, + /* 180 */ 1579, 1630, 142, 1763, 574, 1765, 1766, 570, 1444, 565, + /* 190 */ 1246, 1247, 248, 1295, 1296, 1298, 1299, 1300, 1301, 1302, + /* 200 */ 567, 563, 1310, 1311, 1313, 1314, 1315, 1316, 1318, 1321, + /* 210 */ 1223, 1224, 110, 109, 108, 107, 106, 105, 104, 103, + /* 220 */ 102, 1243, 160, 1241, 1625, 1626, 550, 1919, 1401, 1905, + /* 230 */ 60, 1485, 34, 33, 60, 83, 41, 39, 37, 36, + /* 240 */ 35, 58, 158, 311, 493, 80, 1902, 1246, 1247, 228, + /* 250 */ 1295, 1296, 1298, 1299, 1300, 1301, 1302, 567, 563, 1310, + /* 260 */ 1311, 1313, 1314, 1315, 1316, 1318, 1321, 40, 38, 530, + /* 270 */ 1399, 1400, 1402, 1403, 160, 334, 140, 1242, 1456, 647, + /* 280 */ 160, 1465, 1750, 1376, 302, 1905, 160, 1007, 1317, 1006, + /* 290 */ 1240, 1266, 312, 1746, 310, 309, 69, 465, 157, 34, + /* 300 */ 33, 467, 1902, 41, 39, 37, 36, 35, 1280, 1509, + /* 310 */ 373, 1312, 372, 1905, 151, 14, 1339, 1008, 1575, 1742, + /* 320 */ 1748, 1248, 1732, 466, 40, 38, 1903, 1618, 477, 476, + /* 330 */ 1902, 565, 334, 475, 1242, 1506, 116, 472, 2, 553, + /* 340 */ 471, 470, 469, 474, 473, 1317, 1675, 1240, 295, 1098, /* 350 */ 596, 595, 594, 1102, 593, 1104, 1105, 592, 1107, 589, - /* 360 */ 652, 1113, 586, 1115, 1116, 583, 580, 298, 1312, 337, - /* 370 */ 1340, 1669, 69, 306, 1319, 1320, 559, 138, 1248, 1467, - /* 380 */ 1140, 1141, 169, 33, 32, 1631, 1581, 40, 38, 36, - /* 390 */ 35, 34, 338, 1345, 1575, 8, 534, 629, 628, 627, - /* 400 */ 342, 1629, 626, 625, 624, 121, 619, 618, 617, 616, - /* 410 */ 615, 614, 613, 612, 131, 608, 340, 652, 22, 1243, - /* 420 */ 1732, 1241, 33, 32, 138, 1266, 40, 38, 36, 35, - /* 430 */ 34, 1319, 1320, 1581, 29, 325, 1334, 1335, 1336, 1337, - /* 440 */ 1338, 1342, 1343, 1344, 432, 1246, 1247, 428, 1295, 1296, - /* 450 */ 1298, 1299, 1300, 1301, 1302, 547, 571, 1310, 1311, 1313, - /* 460 */ 1314, 1315, 1316, 1318, 1321, 33, 32, 607, 570, 40, - /* 470 */ 38, 36, 35, 34, 1327, 1265, 1243, 78, 1241, 111, - /* 480 */ 1266, 36, 35, 34, 1242, 160, 468, 33, 32, 474, - /* 490 */ 473, 40, 38, 36, 35, 34, 1579, 1240, 1572, 1466, - /* 500 */ 141, 528, 1246, 1247, 1536, 1295, 1296, 1298, 1299, 1300, - /* 510 */ 1301, 1302, 547, 571, 1310, 1311, 1313, 1314, 1315, 1316, - /* 520 */ 1318, 1321, 39, 37, 1322, 60, 413, 605, 1248, 119, - /* 530 */ 327, 1445, 1242, 1465, 160, 1007, 1464, 1006, 430, 301, - /* 540 */ 1732, 1391, 1555, 1317, 1264, 1240, 129, 128, 602, 601, - /* 550 */ 600, 532, 101, 528, 1401, 100, 99, 98, 97, 96, - /* 560 */ 95, 94, 93, 92, 570, 1008, 1312, 652, 1268, 117, - /* 570 */ 1437, 1339, 171, 170, 1732, 378, 1248, 1732, 599, 39, - /* 580 */ 37, 119, 1266, 570, 231, 1847, 527, 327, 526, 1242, - /* 590 */ 1854, 1905, 1579, 9, 379, 514, 1399, 1400, 1402, 1403, - /* 600 */ 1317, 607, 1240, 532, 159, 373, 1762, 372, 1902, 365, - /* 610 */ 1463, 1579, 33, 32, 1851, 652, 40, 38, 36, 35, - /* 620 */ 34, 117, 1752, 1312, 1675, 1340, 1243, 295, 1241, 1319, - /* 630 */ 1320, 367, 363, 1248, 1780, 570, 231, 1847, 527, 1248, - /* 640 */ 526, 1631, 552, 1905, 167, 610, 383, 1732, 1345, 551, - /* 650 */ 9, 1732, 1246, 1247, 1297, 26, 157, 1630, 1436, 1754, - /* 660 */ 1902, 33, 32, 1579, 160, 40, 38, 36, 35, 34, - /* 670 */ 67, 1060, 652, 66, 1243, 1793, 1241, 7, 142, 1763, - /* 680 */ 554, 1765, 1766, 550, 1485, 573, 1319, 1320, 1554, 29, - /* 690 */ 325, 1334, 1335, 1336, 1337, 1338, 1342, 1343, 1344, 233, - /* 700 */ 1246, 1247, 1062, 1295, 1296, 1298, 1299, 1300, 1301, 1302, - /* 710 */ 547, 571, 1310, 1311, 1313, 1314, 1315, 1316, 1318, 1321, - /* 720 */ 33, 32, 533, 1919, 40, 38, 36, 35, 34, 1854, - /* 730 */ 1854, 1243, 647, 1241, 28, 623, 621, 536, 555, 1674, - /* 740 */ 33, 32, 295, 311, 40, 38, 36, 35, 34, 1677, - /* 750 */ 138, 1269, 528, 1850, 1849, 137, 1297, 1246, 1247, 1582, - /* 760 */ 1295, 1296, 1298, 1299, 1300, 1301, 1302, 547, 571, 1310, - /* 770 */ 1311, 1313, 1314, 1315, 1316, 1318, 1321, 39, 37, 297, - /* 780 */ 119, 1264, 1564, 605, 611, 327, 1551, 1242, 406, 1762, - /* 790 */ 1341, 418, 312, 1462, 310, 309, 1280, 465, 1317, 1377, - /* 800 */ 1240, 467, 129, 128, 602, 601, 600, 1566, 391, 500, - /* 810 */ 419, 603, 393, 1346, 1622, 1461, 570, 1780, 245, 1460, - /* 820 */ 117, 1312, 1537, 466, 1562, 552, 482, 398, 207, 570, - /* 830 */ 1732, 1248, 551, 1459, 1732, 155, 1847, 1848, 1458, 1852, - /* 840 */ 399, 492, 546, 384, 1579, 33, 32, 1457, 2, 40, - /* 850 */ 38, 36, 35, 34, 27, 203, 1732, 1579, 1793, 1373, - /* 860 */ 1732, 89, 1763, 554, 1765, 1766, 550, 1455, 573, 485, - /* 870 */ 652, 1839, 598, 479, 1732, 1838, 1835, 539, 202, 1732, - /* 880 */ 1223, 1224, 214, 417, 1319, 1320, 412, 411, 410, 409, + /* 360 */ 652, 1113, 586, 1115, 1116, 583, 580, 605, 1312, 160, + /* 370 */ 1340, 477, 476, 160, 1319, 1320, 475, 1464, 1248, 116, + /* 380 */ 472, 623, 621, 471, 470, 469, 129, 128, 602, 601, + /* 390 */ 600, 424, 556, 1345, 428, 8, 538, 629, 628, 627, + /* 400 */ 342, 1854, 626, 625, 624, 121, 619, 618, 617, 616, + /* 410 */ 615, 614, 613, 612, 131, 608, 321, 652, 1732, 1243, + /* 420 */ 204, 1241, 34, 33, 138, 1851, 41, 39, 37, 36, + /* 430 */ 35, 1319, 1320, 1581, 30, 332, 1334, 1335, 1336, 1337, + /* 440 */ 1338, 1342, 1343, 1344, 990, 1246, 1247, 1437, 1295, 1296, + /* 450 */ 1298, 1299, 1300, 1301, 1302, 567, 563, 1310, 1311, 1313, + /* 460 */ 1314, 1315, 1316, 1318, 1321, 34, 33, 467, 544, 41, + /* 470 */ 39, 37, 36, 35, 1631, 1854, 1243, 551, 1241, 71, + /* 480 */ 300, 322, 607, 510, 994, 995, 1463, 34, 33, 466, + /* 490 */ 1629, 41, 39, 37, 36, 35, 120, 1462, 1411, 1850, + /* 500 */ 23, 432, 1246, 1247, 428, 1295, 1296, 1298, 1299, 1300, + /* 510 */ 1301, 1302, 567, 563, 1310, 1311, 1313, 1314, 1315, 1316, + /* 520 */ 1318, 1321, 40, 38, 1322, 482, 365, 1732, 655, 544, + /* 530 */ 334, 1265, 1242, 337, 160, 1436, 118, 554, 1732, 302, + /* 540 */ 492, 138, 263, 1317, 1007, 1240, 1006, 520, 367, 363, + /* 550 */ 1581, 154, 1847, 1848, 203, 1852, 149, 120, 378, 461, + /* 560 */ 1720, 645, 641, 637, 633, 261, 1312, 533, 485, 167, + /* 570 */ 603, 1339, 479, 1622, 1008, 1579, 1248, 202, 549, 40, + /* 580 */ 38, 1762, 1266, 217, 218, 1461, 1854, 334, 508, 1242, + /* 590 */ 520, 85, 557, 9, 226, 67, 320, 118, 66, 1676, + /* 600 */ 1317, 111, 1240, 55, 1631, 1555, 54, 353, 468, 1780, + /* 610 */ 1849, 338, 246, 1847, 543, 652, 542, 572, 1579, 1905, + /* 620 */ 1629, 1060, 1732, 1312, 571, 1340, 1732, 517, 27, 1319, + /* 630 */ 1320, 1384, 157, 1248, 34, 33, 1902, 1266, 41, 39, + /* 640 */ 37, 36, 35, 1679, 300, 539, 534, 510, 1345, 1793, + /* 650 */ 9, 520, 1062, 88, 1763, 574, 1765, 1766, 570, 213, + /* 660 */ 565, 1460, 379, 1839, 607, 994, 995, 327, 1835, 1918, + /* 670 */ 1669, 1327, 652, 1674, 1243, 295, 1241, 1266, 1873, 1579, + /* 680 */ 1215, 169, 206, 37, 36, 35, 1319, 1320, 1556, 30, + /* 690 */ 332, 1334, 1335, 1336, 1337, 1338, 1342, 1343, 1344, 1459, + /* 700 */ 1246, 1247, 1732, 1295, 1296, 1298, 1299, 1300, 1301, 1302, + /* 710 */ 567, 563, 1310, 1311, 1313, 1314, 1315, 1316, 1318, 1321, + /* 720 */ 1445, 34, 33, 508, 1248, 41, 39, 37, 36, 35, + /* 730 */ 1341, 1243, 604, 1241, 1677, 1622, 268, 610, 77, 1609, + /* 740 */ 1732, 101, 7, 1458, 100, 99, 98, 97, 96, 95, + /* 750 */ 94, 93, 92, 1346, 1455, 1454, 1297, 1246, 1247, 1572, + /* 760 */ 1295, 1296, 1298, 1299, 1300, 1301, 1302, 567, 563, 1310, + /* 770 */ 1311, 1313, 1314, 1315, 1316, 1318, 1321, 40, 38, 297, + /* 780 */ 611, 1264, 1551, 605, 1732, 334, 599, 1242, 406, 1762, + /* 790 */ 520, 418, 1859, 1373, 28, 1732, 1732, 1391, 1317, 413, + /* 800 */ 1240, 383, 129, 128, 602, 601, 600, 340, 391, 520, + /* 810 */ 419, 1297, 393, 1453, 138, 138, 520, 1780, 1579, 1452, + /* 820 */ 398, 1312, 520, 1582, 1581, 572, 1451, 399, 29, 1568, + /* 830 */ 1732, 1248, 571, 441, 34, 33, 1496, 1579, 41, 39, + /* 840 */ 37, 36, 35, 384, 1579, 171, 170, 1457, 2, 1564, + /* 850 */ 1579, 1297, 500, 210, 1732, 45, 4, 1793, 478, 1566, + /* 860 */ 1732, 89, 1763, 574, 1765, 1766, 570, 1732, 565, 1450, + /* 870 */ 652, 1839, 1251, 34, 33, 1838, 1835, 41, 39, 37, + /* 880 */ 36, 35, 72, 417, 1319, 1320, 412, 411, 410, 409, /* 890 */ 408, 405, 404, 403, 402, 401, 397, 396, 395, 394, - /* 900 */ 388, 387, 386, 385, 55, 382, 381, 54, 1732, 236, - /* 910 */ 1454, 570, 570, 139, 570, 570, 604, 460, 274, 1622, - /* 920 */ 994, 995, 441, 1576, 544, 1708, 501, 195, 467, 1243, - /* 930 */ 193, 1241, 272, 57, 268, 537, 56, 1609, 197, 1579, - /* 940 */ 1579, 196, 1579, 1579, 1859, 1373, 1453, 494, 1762, 515, - /* 950 */ 466, 1732, 173, 421, 1452, 1246, 1247, 1451, 1295, 1296, - /* 960 */ 1298, 1299, 1300, 1301, 1302, 547, 571, 1310, 1311, 1313, - /* 970 */ 1314, 1315, 1316, 1318, 1321, 570, 1780, 570, 60, 570, - /* 980 */ 1251, 570, 44, 4, 552, 1450, 505, 1732, 568, 1732, - /* 990 */ 257, 551, 341, 1496, 1250, 1732, 622, 1449, 1732, 199, - /* 1000 */ 1448, 1447, 198, 1579, 50, 1579, 532, 1579, 201, 1579, - /* 1010 */ 1491, 200, 52, 504, 210, 478, 86, 1793, 1376, 218, - /* 1020 */ 87, 1763, 554, 1765, 1766, 550, 1732, 573, 1489, 41, - /* 1030 */ 1839, 41, 480, 1762, 300, 1835, 225, 368, 1732, 11, - /* 1040 */ 10, 1732, 1732, 72, 41, 1398, 1905, 1439, 1440, 243, - /* 1050 */ 483, 64, 63, 377, 1331, 123, 166, 126, 127, 157, - /* 1060 */ 220, 1780, 371, 1902, 1032, 1781, 343, 1480, 1619, 531, - /* 1070 */ 1347, 529, 1303, 50, 1732, 296, 551, 540, 361, 1869, - /* 1080 */ 359, 355, 351, 163, 346, 1191, 578, 126, 1762, 127, - /* 1090 */ 248, 112, 230, 126, 83, 1033, 562, 3, 254, 1091, - /* 1100 */ 1264, 235, 1793, 238, 80, 88, 1763, 554, 1765, 1766, - /* 1110 */ 550, 1254, 573, 5, 267, 1839, 1780, 160, 240, 320, - /* 1120 */ 1835, 152, 345, 348, 531, 1253, 352, 1119, 1123, 1732, - /* 1130 */ 1130, 551, 1128, 156, 130, 307, 1060, 308, 400, 1207, - /* 1140 */ 264, 1865, 1671, 1762, 168, 407, 415, 414, 416, 420, - /* 1150 */ 422, 1270, 423, 1273, 431, 434, 176, 1793, 178, 435, - /* 1160 */ 88, 1763, 554, 1765, 1766, 550, 1272, 573, 436, 1274, - /* 1170 */ 1839, 1780, 437, 181, 320, 1835, 152, 183, 439, 552, - /* 1180 */ 1271, 185, 440, 68, 1732, 188, 551, 443, 462, 91, - /* 1190 */ 464, 1569, 192, 299, 1565, 194, 1866, 1713, 132, 265, - /* 1200 */ 133, 496, 1567, 1563, 134, 1762, 135, 205, 495, 208, - /* 1210 */ 502, 506, 1793, 1269, 317, 88, 1763, 554, 1765, 1766, - /* 1220 */ 550, 212, 573, 499, 1870, 1839, 511, 516, 1880, 320, - /* 1230 */ 1835, 1918, 558, 1780, 216, 513, 319, 525, 6, 219, - /* 1240 */ 1873, 552, 334, 333, 1879, 519, 1732, 512, 551, 509, - /* 1250 */ 510, 226, 1256, 1373, 1861, 224, 229, 227, 146, 228, - /* 1260 */ 118, 1268, 1855, 1317, 541, 1249, 538, 18, 321, 556, - /* 1270 */ 124, 557, 234, 1762, 1793, 1712, 1681, 88, 1763, 554, - /* 1280 */ 1765, 1766, 550, 125, 573, 563, 1312, 1839, 560, 329, - /* 1290 */ 564, 320, 1835, 1918, 565, 1820, 1248, 1901, 266, 250, - /* 1300 */ 252, 1780, 1896, 77, 535, 79, 237, 1921, 1580, 552, - /* 1310 */ 648, 269, 542, 239, 1732, 576, 551, 1623, 260, 1552, - /* 1320 */ 649, 651, 51, 271, 273, 1726, 1725, 290, 62, 292, - /* 1330 */ 1724, 145, 291, 347, 1721, 574, 349, 350, 1235, 1236, - /* 1340 */ 1762, 164, 1793, 190, 1719, 88, 1763, 554, 1765, 1766, - /* 1350 */ 550, 354, 573, 356, 357, 1839, 358, 144, 1718, 320, - /* 1360 */ 1835, 1918, 459, 455, 451, 447, 189, 360, 1780, 1717, - /* 1370 */ 1858, 362, 1716, 364, 1715, 366, 552, 1698, 165, 369, - /* 1380 */ 370, 1732, 1692, 551, 1210, 1209, 1691, 375, 376, 1690, - /* 1390 */ 1689, 1179, 70, 1664, 1257, 187, 1252, 65, 532, 1663, - /* 1400 */ 1662, 1661, 1660, 1659, 1658, 1657, 389, 1656, 390, 1793, - /* 1410 */ 392, 1655, 281, 1763, 554, 1765, 1766, 550, 1762, 573, - /* 1420 */ 1260, 1654, 1653, 1652, 1651, 1650, 1649, 1648, 1647, 1646, - /* 1430 */ 1645, 571, 1310, 1311, 1313, 1314, 1315, 1316, 1905, 1644, - /* 1440 */ 1643, 1642, 1641, 1640, 1639, 1638, 1780, 1637, 122, 1636, - /* 1450 */ 1635, 159, 1634, 1181, 552, 1902, 1633, 186, 179, 1732, - /* 1460 */ 184, 551, 1632, 1510, 438, 172, 1508, 1476, 997, 996, - /* 1470 */ 1475, 1706, 1762, 113, 174, 1700, 532, 175, 150, 427, - /* 1480 */ 1688, 1687, 429, 177, 182, 114, 1673, 1793, 1558, 1507, - /* 1490 */ 281, 1763, 554, 1765, 1766, 550, 180, 573, 1505, 1762, - /* 1500 */ 1780, 1503, 1501, 444, 446, 445, 449, 448, 552, 1026, - /* 1510 */ 1499, 452, 450, 1732, 456, 551, 1905, 454, 1488, 1487, - /* 1520 */ 1472, 453, 1560, 458, 1559, 1134, 1133, 1780, 191, 157, - /* 1530 */ 457, 1059, 1058, 1902, 1057, 549, 1497, 620, 1056, 1492, - /* 1540 */ 1732, 1793, 551, 49, 89, 1763, 554, 1765, 1766, 550, - /* 1550 */ 622, 573, 1053, 1762, 1839, 313, 1052, 314, 543, 1835, - /* 1560 */ 1051, 481, 1490, 315, 484, 1471, 486, 1470, 1793, 488, - /* 1570 */ 1469, 288, 1763, 554, 1765, 1766, 550, 548, 573, 545, - /* 1580 */ 1811, 1780, 490, 90, 1705, 1217, 1699, 136, 497, 552, - /* 1590 */ 1686, 1684, 1685, 1683, 1732, 1682, 551, 41, 23, 47, - /* 1600 */ 1413, 15, 16, 1762, 53, 45, 215, 222, 10, 209, - /* 1610 */ 217, 498, 1397, 143, 223, 316, 1390, 1752, 25, 232, - /* 1620 */ 221, 24, 1793, 74, 46, 89, 1763, 554, 1765, 1766, - /* 1630 */ 550, 1780, 573, 1370, 147, 1839, 1369, 1430, 503, 552, - /* 1640 */ 1836, 17, 13, 1425, 1732, 1419, 551, 1424, 322, 1429, - /* 1650 */ 1428, 323, 19, 1762, 1288, 1680, 1305, 31, 508, 1332, - /* 1660 */ 1304, 12, 20, 148, 161, 21, 1227, 242, 244, 1762, - /* 1670 */ 1672, 1395, 1793, 251, 553, 289, 1763, 554, 1765, 1766, - /* 1680 */ 550, 1780, 573, 249, 75, 76, 1796, 80, 1751, 552, - /* 1690 */ 256, 561, 253, 572, 1732, 1307, 551, 1780, 1258, 575, - /* 1700 */ 577, 336, 48, 581, 1120, 552, 1117, 579, 582, 584, - /* 1710 */ 1732, 1114, 551, 585, 587, 1108, 588, 1097, 590, 1106, - /* 1720 */ 591, 597, 1793, 1129, 81, 284, 1763, 554, 1765, 1766, - /* 1730 */ 550, 82, 573, 1762, 59, 1112, 1111, 258, 1793, 1125, - /* 1740 */ 606, 142, 1763, 554, 1765, 1766, 550, 1024, 573, 1762, - /* 1750 */ 1110, 1048, 1109, 1066, 609, 259, 1046, 1045, 1044, 1043, - /* 1760 */ 1042, 1780, 1041, 524, 1040, 1039, 1063, 1061, 1036, 552, - /* 1770 */ 1035, 1034, 1031, 1030, 1732, 1504, 551, 1780, 1029, 630, - /* 1780 */ 632, 631, 1502, 634, 636, 549, 1920, 1500, 324, 635, - /* 1790 */ 1732, 638, 551, 639, 640, 1498, 642, 643, 644, 1762, - /* 1800 */ 1486, 646, 1793, 987, 1468, 289, 1763, 554, 1765, 1766, - /* 1810 */ 550, 262, 573, 650, 653, 1762, 1244, 1443, 1793, 270, - /* 1820 */ 1443, 288, 1763, 554, 1765, 1766, 550, 1780, 573, 654, - /* 1830 */ 1812, 1443, 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, - /* 1840 */ 1732, 1443, 551, 1780, 1443, 1443, 1443, 1443, 1443, 1443, - /* 1850 */ 1443, 552, 1443, 1443, 326, 1443, 1732, 1443, 551, 1443, - /* 1860 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, - /* 1870 */ 328, 289, 1763, 554, 1765, 1766, 550, 1443, 573, 1762, - /* 1880 */ 1443, 1443, 1443, 1443, 1793, 1443, 1443, 289, 1763, 554, - /* 1890 */ 1765, 1766, 550, 1443, 573, 1443, 1762, 1443, 1443, 1443, - /* 1900 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1780, 1443, 1443, - /* 1910 */ 1443, 1443, 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, - /* 1920 */ 1732, 1443, 551, 1443, 1780, 1443, 1443, 1443, 1443, 1443, - /* 1930 */ 1443, 1443, 552, 1443, 1443, 1443, 1443, 1732, 1762, 551, - /* 1940 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, - /* 1950 */ 1443, 275, 1763, 554, 1765, 1766, 550, 1443, 573, 1443, - /* 1960 */ 1443, 1443, 1762, 1443, 1443, 1793, 1780, 1443, 276, 1763, - /* 1970 */ 554, 1765, 1766, 550, 552, 573, 1443, 1443, 1443, 1732, - /* 1980 */ 1443, 551, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 1990 */ 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 552, 1443, - /* 2000 */ 1443, 1443, 1443, 1732, 1443, 551, 1443, 1793, 1443, 1443, - /* 2010 */ 277, 1763, 554, 1765, 1766, 550, 1443, 573, 1762, 1443, - /* 2020 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2030 */ 1443, 1793, 1443, 1443, 283, 1763, 554, 1765, 1766, 550, - /* 2040 */ 1443, 573, 1762, 1443, 1443, 1443, 1780, 1443, 1443, 1443, - /* 2050 */ 1443, 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, 1732, - /* 2060 */ 1443, 551, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2070 */ 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 552, 1443, - /* 2080 */ 1443, 1443, 1443, 1732, 1762, 551, 1443, 1793, 1443, 1443, - /* 2090 */ 285, 1763, 554, 1765, 1766, 550, 1443, 573, 1443, 1443, - /* 2100 */ 1762, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2110 */ 1443, 1793, 1780, 1443, 278, 1763, 554, 1765, 1766, 550, - /* 2120 */ 552, 573, 1443, 1443, 1443, 1732, 1443, 551, 1780, 1443, - /* 2130 */ 1443, 1443, 1443, 1443, 1443, 1443, 552, 1443, 1443, 1443, - /* 2140 */ 1443, 1732, 1443, 551, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2150 */ 1443, 1443, 1443, 1793, 1443, 1443, 286, 1763, 554, 1765, - /* 2160 */ 1766, 550, 1443, 573, 1762, 1443, 1443, 1443, 1443, 1793, - /* 2170 */ 1443, 1443, 279, 1763, 554, 1765, 1766, 550, 1443, 573, - /* 2180 */ 1443, 1762, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2190 */ 1443, 1443, 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2200 */ 552, 1443, 1443, 1443, 1443, 1732, 1443, 551, 1443, 1780, - /* 2210 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 552, 1443, 1443, - /* 2220 */ 1443, 1443, 1732, 1762, 551, 1443, 1443, 1443, 1443, 1443, - /* 2230 */ 1443, 1443, 1443, 1793, 1443, 1443, 287, 1763, 554, 1765, - /* 2240 */ 1766, 550, 1443, 573, 1443, 1443, 1443, 1762, 1443, 1443, - /* 2250 */ 1793, 1780, 1443, 280, 1763, 554, 1765, 1766, 550, 552, - /* 2260 */ 573, 1443, 1443, 1443, 1732, 1443, 551, 1443, 1443, 1443, - /* 2270 */ 1443, 1443, 1443, 1443, 1443, 1780, 1443, 1443, 1443, 1443, - /* 2280 */ 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, 1732, 1443, - /* 2290 */ 551, 1443, 1793, 1443, 1443, 293, 1763, 554, 1765, 1766, - /* 2300 */ 550, 1443, 573, 1762, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2310 */ 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, 1443, 294, - /* 2320 */ 1763, 554, 1765, 1766, 550, 1443, 573, 1762, 1443, 1443, - /* 2330 */ 1443, 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 552, - /* 2340 */ 1443, 1443, 1443, 1443, 1732, 1443, 551, 1443, 1443, 1443, - /* 2350 */ 1443, 1443, 1443, 1443, 1443, 1780, 1443, 1443, 1443, 1443, - /* 2360 */ 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, 1732, 1762, - /* 2370 */ 551, 1443, 1793, 1443, 1443, 1774, 1763, 554, 1765, 1766, - /* 2380 */ 550, 1443, 573, 1443, 1443, 1762, 1443, 1443, 1443, 1443, - /* 2390 */ 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1780, 1443, 1773, - /* 2400 */ 1763, 554, 1765, 1766, 550, 552, 573, 1443, 1443, 1443, - /* 2410 */ 1732, 1443, 551, 1780, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2420 */ 1443, 552, 1443, 1443, 1443, 1443, 1732, 1443, 551, 1443, - /* 2430 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, - /* 2440 */ 1443, 1772, 1763, 554, 1765, 1766, 550, 1443, 573, 1762, - /* 2450 */ 1443, 1443, 1443, 1443, 1793, 1443, 1443, 304, 1763, 554, - /* 2460 */ 1765, 1766, 550, 1443, 573, 1443, 1762, 1443, 1443, 1443, - /* 2470 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1780, 1443, 1443, - /* 2480 */ 1443, 1443, 1443, 1443, 1443, 552, 1443, 1443, 1443, 1443, - /* 2490 */ 1732, 1443, 551, 1443, 1780, 1443, 1443, 1443, 1443, 1443, - /* 2500 */ 1443, 1443, 552, 1443, 1443, 1443, 1443, 1732, 1762, 551, - /* 2510 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, - /* 2520 */ 1443, 303, 1763, 554, 1765, 1766, 550, 1443, 573, 1443, - /* 2530 */ 1443, 1443, 1762, 1443, 1443, 1793, 1780, 1443, 305, 1763, - /* 2540 */ 554, 1765, 1766, 550, 552, 573, 1443, 1443, 1443, 1732, - /* 2550 */ 1443, 551, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2560 */ 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 552, 1443, - /* 2570 */ 1443, 1443, 1443, 1732, 1443, 551, 1443, 1793, 1443, 1443, - /* 2580 */ 302, 1763, 554, 1765, 1766, 550, 1443, 573, 1443, 1443, - /* 2590 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - /* 2600 */ 1443, 1793, 1443, 1443, 282, 1763, 554, 1765, 1766, 550, - /* 2610 */ 1443, 573, + /* 900 */ 388, 387, 386, 385, 1449, 382, 381, 1762, 195, 197, + /* 910 */ 1732, 193, 196, 139, 520, 34, 33, 1491, 274, 41, + /* 920 */ 39, 37, 36, 35, 1373, 1576, 1562, 199, 1537, 1243, + /* 930 */ 198, 1241, 272, 57, 201, 1780, 56, 200, 207, 480, + /* 940 */ 52, 504, 1579, 548, 566, 1732, 561, 1448, 1732, 1762, + /* 950 */ 571, 598, 173, 421, 251, 1246, 1247, 1447, 1295, 1296, + /* 960 */ 1298, 1299, 1300, 1301, 1302, 567, 563, 1310, 1311, 1313, + /* 970 */ 1314, 1315, 1316, 1318, 1321, 1793, 520, 1780, 60, 88, + /* 980 */ 1763, 574, 1765, 1766, 570, 572, 565, 1708, 1732, 1839, + /* 990 */ 1732, 1489, 571, 327, 1835, 152, 1032, 1250, 1732, 11, + /* 1000 */ 10, 531, 622, 1254, 1579, 460, 549, 156, 42, 520, + /* 1010 */ 494, 1439, 1440, 483, 1781, 1865, 86, 1793, 1762, 190, + /* 1020 */ 501, 87, 1763, 574, 1765, 1766, 570, 1033, 565, 1752, + /* 1030 */ 1480, 1839, 1554, 144, 240, 301, 1835, 1579, 459, 455, + /* 1040 */ 451, 447, 189, 368, 520, 1619, 1780, 1905, 215, 1191, + /* 1050 */ 343, 64, 63, 377, 548, 505, 166, 545, 137, 1732, + /* 1060 */ 157, 571, 371, 1869, 1902, 250, 1754, 123, 70, 126, + /* 1070 */ 127, 187, 1579, 42, 520, 296, 1331, 50, 361, 245, + /* 1080 */ 359, 355, 351, 163, 346, 518, 1793, 520, 1762, 219, + /* 1090 */ 88, 1763, 574, 1765, 1766, 570, 232, 565, 519, 253, + /* 1100 */ 1839, 255, 1579, 42, 327, 1835, 152, 1242, 513, 3, + /* 1110 */ 225, 1091, 42, 5, 267, 1579, 1780, 160, 1398, 1264, + /* 1120 */ 1240, 345, 348, 352, 572, 307, 1866, 605, 1253, 1732, + /* 1130 */ 1060, 571, 578, 186, 179, 1207, 184, 235, 308, 264, + /* 1140 */ 438, 1762, 400, 520, 1347, 1671, 129, 128, 602, 601, + /* 1150 */ 600, 1248, 126, 1303, 257, 520, 1793, 168, 407, 177, + /* 1160 */ 88, 1763, 574, 1765, 1766, 570, 341, 565, 415, 1780, + /* 1170 */ 1839, 1579, 544, 1119, 327, 1835, 1918, 572, 325, 324, + /* 1180 */ 127, 1270, 1732, 1579, 571, 1896, 414, 420, 1256, 416, + /* 1190 */ 652, 422, 423, 1123, 112, 126, 431, 176, 1273, 1317, + /* 1200 */ 120, 1249, 434, 435, 178, 1762, 1272, 1274, 436, 1793, + /* 1210 */ 181, 437, 439, 88, 1763, 574, 1765, 1766, 570, 183, + /* 1220 */ 565, 1130, 1312, 1839, 1271, 1762, 440, 327, 1835, 1918, + /* 1230 */ 462, 185, 1248, 1780, 68, 1128, 130, 464, 1858, 443, + /* 1240 */ 118, 572, 188, 1713, 1569, 299, 1732, 265, 571, 1243, + /* 1250 */ 205, 1241, 192, 1780, 1565, 155, 1847, 1848, 91, 1852, + /* 1260 */ 194, 572, 549, 132, 133, 1567, 1732, 208, 571, 1563, + /* 1270 */ 495, 529, 134, 1793, 135, 1246, 1247, 281, 1763, 574, + /* 1280 */ 1765, 1766, 570, 502, 565, 1762, 212, 506, 499, 496, + /* 1290 */ 317, 528, 509, 1793, 514, 221, 1712, 89, 1763, 574, + /* 1300 */ 1765, 1766, 570, 1905, 565, 124, 1681, 1839, 511, 319, + /* 1310 */ 125, 560, 1835, 1780, 515, 516, 159, 223, 266, 1269, + /* 1320 */ 1902, 572, 76, 1580, 532, 524, 1732, 1870, 571, 230, + /* 1330 */ 1257, 541, 1252, 526, 527, 525, 326, 1880, 1762, 535, + /* 1340 */ 6, 234, 549, 523, 522, 1861, 1373, 244, 1268, 119, + /* 1350 */ 558, 242, 1762, 1793, 239, 241, 1260, 281, 1763, 574, + /* 1360 */ 1765, 1766, 570, 243, 565, 328, 1780, 563, 1310, 1311, + /* 1370 */ 1313, 1314, 1315, 1316, 569, 1879, 146, 1901, 1855, 1732, + /* 1380 */ 1780, 571, 555, 1905, 19, 1820, 249, 252, 572, 1921, + /* 1390 */ 78, 576, 1552, 1732, 269, 571, 157, 1623, 260, 648, + /* 1400 */ 1902, 145, 649, 651, 51, 552, 1793, 282, 271, 254, + /* 1410 */ 289, 1763, 574, 1765, 1766, 570, 568, 565, 562, 1811, + /* 1420 */ 1793, 1762, 292, 273, 89, 1763, 574, 1765, 1766, 570, + /* 1430 */ 1726, 565, 291, 1762, 1839, 559, 1725, 62, 1724, 1836, + /* 1440 */ 347, 1721, 350, 349, 1235, 1762, 1236, 164, 354, 1780, + /* 1450 */ 1719, 356, 357, 358, 318, 1718, 360, 572, 1717, 362, + /* 1460 */ 1716, 1780, 1732, 1715, 571, 364, 521, 366, 1698, 572, + /* 1470 */ 165, 369, 370, 1780, 1732, 1210, 571, 1209, 1692, 1691, + /* 1480 */ 375, 572, 376, 1690, 1689, 1179, 1732, 1664, 571, 1793, + /* 1490 */ 1663, 1662, 65, 290, 1763, 574, 1765, 1766, 570, 1661, + /* 1500 */ 565, 1793, 1660, 1762, 1659, 290, 1763, 574, 1765, 1766, + /* 1510 */ 570, 1658, 565, 1793, 1657, 389, 390, 285, 1763, 574, + /* 1520 */ 1765, 1766, 570, 1762, 565, 1656, 392, 1655, 34, 33, + /* 1530 */ 1654, 1780, 41, 39, 37, 36, 35, 1653, 1652, 572, + /* 1540 */ 122, 1641, 1640, 1639, 1732, 1651, 571, 1650, 1649, 1648, + /* 1550 */ 1647, 1780, 1646, 1645, 1644, 540, 331, 1643, 1642, 572, + /* 1560 */ 1638, 1637, 1636, 1635, 1732, 1634, 571, 1633, 1181, 1632, + /* 1570 */ 1510, 1793, 172, 1762, 1508, 142, 1763, 574, 1765, 1766, + /* 1580 */ 570, 1476, 565, 1475, 1706, 1762, 174, 997, 1700, 996, + /* 1590 */ 113, 1793, 1688, 1687, 114, 290, 1763, 574, 1765, 1766, + /* 1600 */ 570, 1780, 565, 182, 1280, 427, 1673, 150, 175, 569, + /* 1610 */ 180, 1558, 429, 1780, 1732, 1507, 571, 1026, 333, 1505, + /* 1620 */ 1920, 572, 444, 445, 446, 1503, 1732, 449, 571, 448, + /* 1630 */ 450, 1501, 452, 453, 454, 1499, 456, 1762, 458, 1488, + /* 1640 */ 1487, 1793, 1472, 457, 1560, 289, 1763, 574, 1765, 1766, + /* 1650 */ 570, 1134, 565, 1793, 1812, 1133, 1559, 290, 1763, 574, + /* 1660 */ 1765, 1766, 570, 1762, 565, 1780, 620, 1059, 191, 49, + /* 1670 */ 335, 1058, 1057, 572, 1497, 313, 1056, 622, 1732, 1492, + /* 1680 */ 571, 1053, 1052, 1051, 314, 1490, 315, 481, 1471, 484, + /* 1690 */ 486, 1780, 1470, 488, 1469, 490, 90, 1705, 1699, 572, + /* 1700 */ 1217, 136, 497, 1686, 1732, 1793, 571, 1684, 1685, 290, + /* 1710 */ 1763, 574, 1765, 1766, 570, 1227, 565, 1683, 1762, 1682, + /* 1720 */ 1680, 1672, 222, 53, 227, 42, 15, 209, 1258, 214, + /* 1730 */ 1762, 1793, 220, 498, 74, 275, 1763, 574, 1765, 1766, + /* 1740 */ 570, 316, 565, 75, 16, 80, 1780, 48, 238, 512, + /* 1750 */ 224, 503, 24, 229, 572, 1413, 231, 237, 1780, 1732, + /* 1760 */ 233, 571, 1752, 1425, 247, 1395, 572, 26, 1397, 143, + /* 1770 */ 236, 1732, 25, 571, 1390, 1370, 79, 47, 1751, 1369, + /* 1780 */ 1762, 147, 18, 1430, 1419, 1424, 1793, 329, 1429, 1428, + /* 1790 */ 276, 1763, 574, 1765, 1766, 570, 1762, 565, 1793, 330, + /* 1800 */ 10, 20, 277, 1763, 574, 1765, 1766, 570, 1780, 565, + /* 1810 */ 1332, 1307, 1796, 564, 32, 17, 572, 1305, 148, 161, + /* 1820 */ 1304, 1732, 1288, 571, 1780, 46, 12, 21, 22, 577, + /* 1830 */ 13, 575, 572, 1120, 336, 1117, 581, 1732, 579, 571, + /* 1840 */ 582, 584, 573, 1114, 585, 587, 1108, 1106, 1793, 588, + /* 1850 */ 590, 591, 284, 1763, 574, 1765, 1766, 570, 1762, 565, + /* 1860 */ 1097, 81, 82, 1112, 1793, 597, 1129, 1111, 286, 1763, + /* 1870 */ 574, 1765, 1766, 570, 59, 565, 1110, 1762, 1109, 258, + /* 1880 */ 1125, 1024, 606, 1048, 1066, 609, 1780, 259, 1046, 1045, + /* 1890 */ 1044, 1043, 1042, 1063, 572, 1041, 1040, 1039, 1061, 1732, + /* 1900 */ 1036, 571, 1035, 1034, 1031, 1780, 1504, 1030, 1502, 1029, + /* 1910 */ 630, 631, 634, 572, 1500, 632, 638, 635, 1732, 1762, + /* 1920 */ 571, 636, 640, 1498, 642, 639, 1793, 643, 1486, 644, + /* 1930 */ 278, 1763, 574, 1765, 1766, 570, 646, 565, 987, 1468, + /* 1940 */ 262, 650, 1443, 1443, 1244, 1793, 270, 1780, 653, 287, + /* 1950 */ 1763, 574, 1765, 1766, 570, 572, 565, 654, 1443, 1443, + /* 1960 */ 1732, 1762, 571, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 1970 */ 1443, 1762, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 1980 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, 1780, + /* 1990 */ 1443, 279, 1763, 574, 1765, 1766, 570, 572, 565, 1780, + /* 2000 */ 1443, 1443, 1732, 1443, 571, 1443, 1443, 572, 1443, 1443, + /* 2010 */ 1443, 1443, 1732, 1443, 571, 1443, 1443, 1443, 1443, 1443, + /* 2020 */ 1443, 1443, 1443, 1762, 1443, 1443, 1443, 1443, 1443, 1793, + /* 2030 */ 1443, 1443, 1443, 288, 1763, 574, 1765, 1766, 570, 1793, + /* 2040 */ 565, 1443, 1443, 280, 1763, 574, 1765, 1766, 570, 1762, + /* 2050 */ 565, 1780, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 572, + /* 2060 */ 1443, 1443, 1443, 1443, 1732, 1762, 571, 1443, 1443, 1443, + /* 2070 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1780, 1443, 1443, + /* 2080 */ 1443, 1443, 1443, 1443, 1443, 572, 1443, 1443, 1443, 1443, + /* 2090 */ 1732, 1793, 571, 1780, 1443, 293, 1763, 574, 1765, 1766, + /* 2100 */ 570, 572, 565, 1443, 1443, 1443, 1732, 1443, 571, 1443, + /* 2110 */ 1443, 1443, 1443, 1443, 1443, 1762, 1443, 1793, 1443, 1443, + /* 2120 */ 1443, 294, 1763, 574, 1765, 1766, 570, 1762, 565, 1443, + /* 2130 */ 1443, 1443, 1443, 1793, 1443, 1443, 1443, 1774, 1763, 574, + /* 2140 */ 1765, 1766, 570, 1780, 565, 1443, 1443, 1443, 1443, 1443, + /* 2150 */ 1443, 572, 1443, 1443, 1443, 1780, 1732, 1443, 571, 1443, + /* 2160 */ 1443, 1443, 1443, 572, 1443, 1443, 1443, 1443, 1732, 1443, + /* 2170 */ 571, 1443, 1443, 1443, 1443, 1443, 1443, 1762, 1443, 1443, + /* 2180 */ 1443, 1443, 1443, 1793, 1443, 1443, 1443, 1773, 1763, 574, + /* 2190 */ 1765, 1766, 570, 1443, 565, 1793, 1443, 1443, 1443, 1772, + /* 2200 */ 1763, 574, 1765, 1766, 570, 1780, 565, 1443, 1443, 1443, + /* 2210 */ 1443, 1443, 1443, 572, 1443, 1443, 1443, 1443, 1732, 1762, + /* 2220 */ 571, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 2230 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 2240 */ 1443, 1443, 1443, 1443, 1443, 1793, 1443, 1780, 1443, 305, + /* 2250 */ 1763, 574, 1765, 1766, 570, 572, 565, 1443, 1443, 1443, + /* 2260 */ 1732, 1762, 571, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 2270 */ 1443, 1762, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 2280 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, 1443, 1780, + /* 2290 */ 1443, 304, 1763, 574, 1765, 1766, 570, 572, 565, 1780, + /* 2300 */ 1443, 1443, 1732, 1443, 571, 1443, 1443, 572, 1443, 1443, + /* 2310 */ 1443, 1443, 1732, 1443, 571, 1443, 1443, 1443, 1443, 1443, + /* 2320 */ 1443, 1762, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, + /* 2330 */ 1443, 1443, 1443, 306, 1763, 574, 1765, 1766, 570, 1793, + /* 2340 */ 565, 1443, 1443, 303, 1763, 574, 1765, 1766, 570, 1780, + /* 2350 */ 565, 1443, 1443, 1443, 1443, 1443, 1443, 572, 1443, 1443, + /* 2360 */ 1443, 1443, 1732, 1443, 571, 1443, 1443, 1443, 1443, 1443, + /* 2370 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + /* 2380 */ 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1793, + /* 2390 */ 1443, 1443, 1443, 283, 1763, 574, 1765, 1766, 570, 1443, + /* 2400 */ 565, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 260, 268, 262, 263, 260, 0, 262, 263, 286, 284, - /* 10 */ 286, 289, 12, 13, 281, 286, 299, 292, 289, 297, - /* 20 */ 20, 297, 22, 290, 307, 314, 297, 310, 12, 13, - /* 30 */ 14, 15, 16, 33, 21, 35, 285, 24, 25, 26, - /* 40 */ 27, 28, 29, 30, 31, 32, 324, 325, 324, 325, - /* 50 */ 298, 299, 256, 324, 325, 330, 56, 335, 4, 335, - /* 60 */ 60, 20, 283, 22, 335, 354, 66, 20, 4, 12, - /* 70 */ 13, 14, 0, 286, 21, 296, 35, 20, 367, 22, - /* 80 */ 284, 0, 371, 83, 297, 20, 264, 34, 292, 36, - /* 90 */ 33, 50, 35, 297, 266, 299, 24, 25, 26, 27, - /* 100 */ 28, 29, 30, 31, 32, 105, 56, 279, 44, 45, - /* 110 */ 314, 324, 325, 56, 292, 287, 20, 60, 59, 119, - /* 120 */ 120, 325, 335, 66, 328, 329, 330, 331, 332, 333, - /* 130 */ 83, 335, 314, 83, 338, 85, 354, 83, 342, 343, - /* 140 */ 83, 20, 295, 62, 63, 298, 299, 19, 67, 367, - /* 150 */ 354, 70, 71, 371, 332, 74, 75, 76, 264, 14, - /* 160 */ 3, 33, 105, 367, 164, 20, 166, 371, 346, 347, - /* 170 */ 348, 349, 354, 351, 314, 47, 119, 120, 0, 83, - /* 180 */ 52, 53, 54, 55, 56, 367, 292, 0, 253, 371, - /* 190 */ 190, 191, 149, 193, 194, 195, 196, 197, 198, 199, + /* 0 */ 339, 340, 266, 260, 264, 262, 263, 269, 253, 284, + /* 10 */ 286, 273, 12, 13, 286, 279, 260, 292, 262, 263, + /* 20 */ 20, 297, 22, 287, 313, 297, 12, 13, 14, 15, + /* 30 */ 16, 20, 292, 33, 21, 35, 264, 24, 25, 26, + /* 40 */ 27, 28, 29, 30, 31, 32, 20, 323, 324, 325, + /* 50 */ 20, 323, 324, 313, 268, 330, 56, 256, 313, 335, + /* 60 */ 60, 20, 4, 335, 4, 354, 66, 281, 313, 12, + /* 70 */ 13, 14, 332, 301, 264, 264, 290, 20, 367, 22, + /* 80 */ 256, 59, 371, 83, 20, 284, 275, 347, 348, 349, + /* 90 */ 33, 351, 35, 292, 354, 14, 1, 2, 297, 354, + /* 100 */ 299, 20, 292, 292, 256, 105, 20, 367, 56, 354, + /* 110 */ 256, 371, 367, 56, 313, 0, 371, 60, 20, 119, + /* 120 */ 120, 297, 367, 66, 295, 324, 371, 298, 299, 328, + /* 130 */ 329, 330, 331, 332, 333, 83, 335, 85, 284, 338, + /* 140 */ 83, 83, 332, 342, 343, 297, 292, 83, 114, 119, + /* 150 */ 120, 297, 264, 299, 354, 354, 346, 347, 348, 349, + /* 160 */ 21, 351, 105, 275, 164, 284, 166, 367, 367, 83, + /* 170 */ 282, 371, 371, 34, 59, 36, 119, 120, 324, 84, + /* 180 */ 292, 300, 328, 329, 330, 331, 332, 333, 0, 335, + /* 190 */ 190, 191, 151, 193, 194, 195, 196, 197, 198, 199, /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - /* 210 */ 82, 8, 9, 85, 354, 12, 13, 14, 15, 16, - /* 220 */ 115, 164, 222, 166, 1, 2, 332, 367, 284, 339, - /* 230 */ 340, 371, 8, 9, 47, 291, 12, 13, 14, 15, - /* 240 */ 16, 347, 348, 349, 300, 351, 118, 190, 191, 314, + /* 210 */ 176, 177, 24, 25, 26, 27, 28, 29, 30, 31, + /* 220 */ 32, 164, 222, 166, 298, 299, 372, 373, 190, 354, + /* 230 */ 83, 0, 8, 9, 83, 83, 12, 13, 14, 15, + /* 240 */ 16, 3, 367, 37, 313, 93, 371, 190, 191, 151, /* 250 */ 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - /* 260 */ 203, 204, 205, 206, 207, 208, 209, 12, 13, 222, - /* 270 */ 227, 228, 222, 95, 276, 20, 222, 22, 150, 174, - /* 280 */ 175, 20, 284, 178, 60, 0, 264, 84, 33, 354, - /* 290 */ 35, 293, 114, 115, 116, 117, 118, 275, 264, 171, - /* 300 */ 261, 173, 367, 264, 282, 354, 371, 84, 84, 275, - /* 310 */ 354, 56, 114, 115, 292, 60, 92, 255, 367, 257, - /* 320 */ 264, 66, 371, 367, 12, 13, 292, 371, 62, 63, - /* 330 */ 264, 275, 20, 67, 22, 0, 70, 71, 83, 194, - /* 340 */ 74, 75, 76, 20, 59, 33, 83, 35, 292, 96, + /* 260 */ 203, 204, 205, 206, 207, 208, 209, 12, 13, 231, + /* 270 */ 232, 233, 234, 235, 222, 20, 255, 22, 257, 48, + /* 280 */ 222, 256, 286, 223, 60, 354, 222, 20, 33, 22, + /* 290 */ 35, 20, 86, 297, 88, 89, 268, 91, 367, 8, + /* 300 */ 9, 95, 371, 12, 13, 14, 15, 16, 84, 0, + /* 310 */ 163, 56, 165, 354, 283, 60, 92, 50, 290, 323, + /* 320 */ 324, 66, 297, 117, 12, 13, 367, 296, 62, 63, + /* 330 */ 371, 335, 20, 67, 22, 0, 70, 71, 83, 43, + /* 340 */ 74, 75, 76, 270, 271, 33, 309, 35, 311, 96, /* 350 */ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - /* 360 */ 105, 108, 109, 110, 111, 112, 113, 301, 56, 276, - /* 370 */ 146, 292, 268, 175, 119, 120, 178, 284, 66, 256, - /* 380 */ 119, 120, 303, 8, 9, 284, 293, 12, 13, 14, - /* 390 */ 15, 16, 291, 169, 290, 83, 239, 62, 63, 64, - /* 400 */ 65, 300, 67, 68, 69, 70, 71, 72, 73, 74, - /* 410 */ 75, 76, 77, 78, 79, 80, 276, 105, 43, 164, - /* 420 */ 297, 166, 8, 9, 284, 20, 12, 13, 14, 15, + /* 360 */ 105, 108, 109, 110, 111, 112, 113, 95, 56, 222, + /* 370 */ 146, 62, 63, 222, 119, 120, 67, 256, 66, 70, + /* 380 */ 71, 270, 271, 74, 75, 76, 114, 115, 116, 117, + /* 390 */ 118, 261, 43, 169, 264, 83, 20, 62, 63, 64, + /* 400 */ 65, 326, 67, 68, 69, 70, 71, 72, 73, 74, + /* 410 */ 75, 76, 77, 78, 79, 80, 276, 105, 297, 164, + /* 420 */ 115, 166, 8, 9, 284, 350, 12, 13, 14, 15, /* 430 */ 16, 119, 120, 293, 210, 211, 212, 213, 214, 215, - /* 440 */ 216, 217, 218, 219, 261, 190, 191, 264, 193, 194, + /* 440 */ 216, 217, 218, 219, 4, 190, 191, 156, 193, 194, /* 450 */ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - /* 460 */ 205, 206, 207, 208, 209, 8, 9, 59, 264, 12, - /* 470 */ 13, 14, 15, 16, 14, 20, 164, 266, 166, 275, - /* 480 */ 20, 14, 15, 16, 22, 222, 282, 8, 9, 270, - /* 490 */ 271, 12, 13, 14, 15, 16, 292, 35, 287, 256, - /* 500 */ 269, 264, 190, 191, 273, 193, 194, 195, 196, 197, + /* 460 */ 205, 206, 207, 208, 209, 8, 9, 95, 264, 12, + /* 470 */ 13, 14, 15, 16, 284, 326, 164, 239, 166, 174, + /* 480 */ 175, 291, 59, 178, 44, 45, 256, 8, 9, 117, + /* 490 */ 300, 12, 13, 14, 15, 16, 292, 256, 84, 350, + /* 500 */ 43, 261, 190, 191, 264, 193, 194, 195, 196, 197, /* 510 */ 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - /* 520 */ 208, 209, 12, 13, 14, 83, 77, 95, 66, 292, - /* 530 */ 20, 0, 22, 256, 222, 20, 256, 22, 14, 60, - /* 540 */ 297, 84, 0, 33, 20, 35, 114, 115, 116, 117, - /* 550 */ 118, 314, 21, 264, 190, 24, 25, 26, 27, 28, - /* 560 */ 29, 30, 31, 32, 264, 50, 56, 105, 20, 332, - /* 570 */ 156, 92, 123, 124, 297, 275, 66, 297, 94, 12, - /* 580 */ 13, 292, 20, 264, 347, 348, 349, 20, 351, 22, - /* 590 */ 326, 354, 292, 83, 275, 231, 232, 233, 234, 235, - /* 600 */ 33, 59, 35, 314, 367, 163, 256, 165, 371, 159, - /* 610 */ 256, 292, 8, 9, 350, 105, 12, 13, 14, 15, - /* 620 */ 16, 332, 46, 56, 309, 146, 164, 312, 166, 119, - /* 630 */ 120, 181, 182, 66, 284, 264, 347, 348, 349, 66, - /* 640 */ 351, 284, 292, 354, 56, 66, 275, 297, 169, 299, - /* 650 */ 83, 297, 190, 191, 194, 2, 367, 300, 244, 83, - /* 660 */ 371, 8, 9, 292, 222, 12, 13, 14, 15, 16, - /* 670 */ 82, 35, 105, 85, 164, 325, 166, 39, 328, 329, - /* 680 */ 330, 331, 332, 333, 0, 335, 119, 120, 0, 210, - /* 690 */ 211, 212, 213, 214, 215, 216, 217, 218, 219, 151, - /* 700 */ 190, 191, 66, 193, 194, 195, 196, 197, 198, 199, + /* 520 */ 208, 209, 12, 13, 14, 4, 159, 297, 19, 264, + /* 530 */ 20, 20, 22, 276, 222, 244, 332, 241, 297, 60, + /* 540 */ 19, 284, 33, 33, 20, 35, 22, 264, 181, 182, + /* 550 */ 293, 347, 348, 349, 33, 351, 47, 292, 275, 35, + /* 560 */ 0, 52, 53, 54, 55, 56, 56, 149, 47, 56, + /* 570 */ 294, 92, 51, 297, 50, 292, 66, 56, 313, 12, + /* 580 */ 13, 256, 20, 114, 115, 256, 326, 20, 299, 22, + /* 590 */ 264, 82, 243, 83, 85, 82, 307, 332, 85, 310, + /* 600 */ 33, 275, 35, 82, 284, 0, 85, 47, 282, 284, + /* 610 */ 350, 291, 347, 348, 349, 105, 351, 292, 292, 354, + /* 620 */ 300, 35, 297, 56, 299, 146, 297, 118, 2, 119, + /* 630 */ 120, 14, 367, 66, 8, 9, 371, 20, 12, 13, + /* 640 */ 14, 15, 16, 0, 175, 227, 228, 178, 169, 324, + /* 650 */ 83, 264, 66, 328, 329, 330, 331, 332, 333, 150, + /* 660 */ 335, 256, 275, 338, 59, 44, 45, 342, 343, 344, + /* 670 */ 292, 14, 105, 309, 164, 311, 166, 20, 353, 292, + /* 680 */ 171, 303, 173, 14, 15, 16, 119, 120, 0, 210, + /* 690 */ 211, 212, 213, 214, 215, 216, 217, 218, 219, 256, + /* 700 */ 190, 191, 297, 193, 194, 195, 196, 197, 198, 199, /* 710 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - /* 720 */ 8, 9, 372, 373, 12, 13, 14, 15, 16, 326, - /* 730 */ 326, 164, 48, 166, 2, 270, 271, 43, 299, 309, - /* 740 */ 8, 9, 312, 37, 12, 13, 14, 15, 16, 310, - /* 750 */ 284, 20, 264, 350, 350, 151, 194, 190, 191, 293, + /* 720 */ 0, 8, 9, 299, 66, 12, 13, 14, 15, 16, + /* 730 */ 146, 164, 294, 166, 310, 297, 277, 66, 266, 280, + /* 740 */ 297, 21, 39, 256, 24, 25, 26, 27, 28, 29, + /* 750 */ 30, 31, 32, 169, 256, 256, 194, 190, 191, 287, /* 760 */ 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, /* 770 */ 203, 204, 205, 206, 207, 208, 209, 12, 13, 18, - /* 780 */ 292, 20, 285, 95, 272, 20, 274, 22, 27, 256, - /* 790 */ 146, 30, 86, 256, 88, 89, 84, 91, 33, 4, - /* 800 */ 35, 95, 114, 115, 116, 117, 118, 285, 47, 318, - /* 810 */ 49, 294, 51, 169, 297, 256, 264, 284, 114, 256, - /* 820 */ 332, 56, 273, 117, 285, 292, 4, 275, 285, 264, - /* 830 */ 297, 66, 299, 256, 297, 347, 348, 349, 256, 351, - /* 840 */ 275, 19, 285, 82, 292, 8, 9, 257, 83, 12, - /* 850 */ 13, 14, 15, 16, 210, 33, 297, 292, 325, 221, - /* 860 */ 297, 328, 329, 330, 331, 332, 333, 256, 335, 47, - /* 870 */ 105, 338, 285, 51, 297, 342, 343, 43, 56, 297, - /* 880 */ 176, 177, 151, 122, 119, 120, 125, 126, 127, 128, + /* 780 */ 272, 20, 274, 95, 297, 20, 94, 22, 27, 256, + /* 790 */ 264, 30, 220, 221, 210, 297, 297, 84, 33, 77, + /* 800 */ 35, 275, 114, 115, 116, 117, 118, 276, 47, 264, + /* 810 */ 49, 194, 51, 256, 284, 284, 264, 284, 292, 256, + /* 820 */ 275, 56, 264, 293, 293, 292, 256, 275, 2, 285, + /* 830 */ 297, 66, 299, 275, 8, 9, 0, 292, 12, 13, + /* 840 */ 14, 15, 16, 82, 292, 123, 124, 257, 83, 285, + /* 850 */ 292, 194, 317, 56, 297, 42, 43, 324, 22, 285, + /* 860 */ 297, 328, 329, 330, 331, 332, 333, 297, 335, 256, + /* 870 */ 105, 338, 35, 8, 9, 342, 343, 12, 13, 14, + /* 880 */ 15, 16, 85, 122, 119, 120, 125, 126, 127, 128, /* 890 */ 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - /* 900 */ 139, 140, 141, 142, 82, 144, 145, 85, 297, 374, - /* 910 */ 256, 264, 264, 18, 264, 264, 294, 265, 23, 297, - /* 920 */ 44, 45, 275, 275, 60, 275, 275, 87, 95, 164, - /* 930 */ 90, 166, 37, 38, 277, 241, 41, 280, 87, 292, - /* 940 */ 292, 90, 292, 292, 220, 221, 256, 321, 256, 365, - /* 950 */ 117, 297, 57, 58, 256, 190, 191, 256, 193, 194, + /* 900 */ 139, 140, 141, 142, 256, 144, 145, 256, 87, 87, + /* 910 */ 297, 90, 90, 18, 264, 8, 9, 0, 23, 12, + /* 920 */ 13, 14, 15, 16, 221, 275, 285, 87, 273, 164, + /* 930 */ 90, 166, 37, 38, 87, 284, 41, 90, 285, 22, + /* 940 */ 151, 152, 292, 292, 285, 297, 60, 256, 297, 256, + /* 950 */ 299, 285, 57, 58, 374, 190, 191, 256, 193, 194, /* 960 */ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - /* 970 */ 205, 206, 207, 208, 209, 264, 284, 264, 83, 264, - /* 980 */ 35, 264, 42, 43, 292, 256, 275, 297, 275, 297, - /* 990 */ 275, 299, 275, 0, 35, 297, 43, 256, 297, 87, - /* 1000 */ 256, 256, 90, 292, 43, 292, 314, 292, 87, 292, - /* 1010 */ 0, 90, 151, 152, 56, 22, 121, 325, 223, 43, - /* 1020 */ 328, 329, 330, 331, 332, 333, 297, 335, 0, 43, - /* 1030 */ 338, 43, 22, 256, 342, 343, 361, 84, 297, 1, - /* 1040 */ 2, 297, 297, 85, 43, 84, 354, 119, 120, 43, - /* 1050 */ 22, 156, 157, 158, 190, 43, 161, 43, 43, 367, - /* 1060 */ 84, 284, 167, 371, 35, 284, 265, 263, 296, 292, - /* 1070 */ 84, 352, 84, 43, 297, 180, 299, 243, 183, 327, - /* 1080 */ 185, 186, 187, 188, 189, 84, 43, 43, 256, 43, - /* 1090 */ 84, 43, 345, 43, 83, 66, 84, 355, 84, 84, - /* 1100 */ 20, 368, 325, 368, 93, 328, 329, 330, 331, 332, - /* 1110 */ 333, 166, 335, 224, 84, 338, 284, 222, 368, 342, - /* 1120 */ 343, 344, 323, 264, 292, 166, 47, 84, 84, 297, - /* 1130 */ 84, 299, 84, 356, 84, 322, 35, 270, 264, 162, - /* 1140 */ 316, 364, 264, 256, 42, 304, 146, 302, 302, 264, - /* 1150 */ 264, 20, 258, 20, 258, 320, 268, 325, 268, 299, - /* 1160 */ 328, 329, 330, 331, 332, 333, 20, 335, 313, 20, - /* 1170 */ 338, 284, 315, 268, 342, 343, 344, 268, 313, 292, - /* 1180 */ 20, 268, 305, 268, 297, 268, 299, 264, 258, 264, - /* 1190 */ 284, 284, 284, 258, 284, 284, 364, 297, 284, 320, - /* 1200 */ 284, 319, 284, 284, 284, 256, 284, 266, 172, 266, - /* 1210 */ 264, 264, 325, 20, 313, 328, 329, 330, 331, 332, - /* 1220 */ 333, 266, 335, 299, 327, 338, 297, 230, 360, 342, - /* 1230 */ 343, 344, 229, 284, 308, 297, 297, 155, 236, 308, - /* 1240 */ 353, 292, 12, 13, 360, 297, 297, 238, 299, 225, - /* 1250 */ 237, 359, 22, 221, 363, 362, 323, 358, 360, 357, - /* 1260 */ 292, 20, 326, 33, 242, 35, 240, 83, 245, 297, - /* 1270 */ 308, 297, 369, 256, 325, 297, 297, 328, 329, 330, - /* 1280 */ 331, 332, 333, 308, 335, 148, 56, 338, 297, 297, - /* 1290 */ 306, 342, 343, 344, 305, 341, 66, 370, 280, 292, - /* 1300 */ 266, 284, 353, 266, 370, 83, 369, 375, 292, 292, - /* 1310 */ 36, 264, 370, 369, 297, 288, 299, 297, 266, 274, - /* 1320 */ 259, 258, 317, 267, 254, 0, 0, 278, 42, 278, - /* 1330 */ 0, 312, 278, 74, 0, 105, 35, 184, 35, 35, - /* 1340 */ 256, 35, 325, 33, 0, 328, 329, 330, 331, 332, - /* 1350 */ 333, 184, 335, 35, 35, 338, 184, 47, 0, 342, - /* 1360 */ 343, 344, 52, 53, 54, 55, 56, 184, 284, 0, - /* 1370 */ 353, 35, 0, 22, 0, 35, 292, 0, 83, 169, - /* 1380 */ 168, 297, 0, 299, 166, 164, 0, 160, 159, 0, - /* 1390 */ 0, 46, 82, 0, 164, 85, 166, 143, 314, 0, - /* 1400 */ 0, 0, 0, 0, 0, 0, 138, 0, 35, 325, - /* 1410 */ 138, 0, 328, 329, 330, 331, 332, 333, 256, 335, - /* 1420 */ 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 1430 */ 0, 201, 202, 203, 204, 205, 206, 207, 354, 0, - /* 1440 */ 0, 0, 0, 0, 0, 0, 284, 0, 42, 0, - /* 1450 */ 0, 367, 0, 22, 292, 371, 0, 147, 148, 297, - /* 1460 */ 150, 299, 0, 0, 154, 56, 0, 0, 14, 14, - /* 1470 */ 0, 0, 256, 39, 42, 0, 314, 40, 43, 46, - /* 1480 */ 0, 0, 46, 173, 155, 39, 0, 325, 0, 0, - /* 1490 */ 328, 329, 330, 331, 332, 333, 39, 335, 0, 256, - /* 1500 */ 284, 0, 0, 35, 39, 47, 47, 35, 292, 61, - /* 1510 */ 0, 35, 39, 297, 35, 299, 354, 39, 0, 0, - /* 1520 */ 0, 47, 0, 39, 0, 35, 22, 284, 90, 367, - /* 1530 */ 47, 35, 35, 371, 35, 292, 0, 43, 35, 0, - /* 1540 */ 297, 325, 299, 92, 328, 329, 330, 331, 332, 333, - /* 1550 */ 43, 335, 35, 256, 338, 22, 35, 22, 342, 343, - /* 1560 */ 35, 49, 0, 22, 35, 0, 35, 0, 325, 35, - /* 1570 */ 0, 328, 329, 330, 331, 332, 333, 334, 335, 336, - /* 1580 */ 337, 284, 22, 20, 0, 35, 0, 170, 22, 292, - /* 1590 */ 0, 0, 0, 0, 297, 0, 299, 43, 83, 43, - /* 1600 */ 84, 226, 226, 256, 151, 220, 83, 43, 2, 148, - /* 1610 */ 84, 151, 84, 83, 46, 151, 84, 46, 43, 46, - /* 1620 */ 83, 83, 325, 83, 43, 328, 329, 330, 331, 332, - /* 1630 */ 333, 284, 335, 84, 46, 338, 84, 84, 153, 292, - /* 1640 */ 343, 43, 226, 35, 297, 84, 299, 35, 35, 35, - /* 1650 */ 35, 35, 43, 256, 22, 0, 84, 83, 311, 190, - /* 1660 */ 84, 83, 83, 46, 46, 83, 179, 84, 83, 256, - /* 1670 */ 0, 84, 325, 39, 192, 328, 329, 330, 331, 332, - /* 1680 */ 333, 284, 335, 83, 83, 83, 83, 93, 46, 292, - /* 1690 */ 46, 149, 147, 83, 297, 84, 299, 284, 22, 94, - /* 1700 */ 35, 35, 83, 35, 84, 292, 84, 83, 83, 35, - /* 1710 */ 297, 84, 299, 83, 35, 84, 83, 22, 35, 84, - /* 1720 */ 83, 95, 325, 35, 83, 328, 329, 330, 331, 332, - /* 1730 */ 333, 83, 335, 256, 83, 107, 107, 43, 325, 22, - /* 1740 */ 60, 328, 329, 330, 331, 332, 333, 61, 335, 256, - /* 1750 */ 107, 35, 107, 66, 81, 43, 35, 35, 35, 35, - /* 1760 */ 35, 284, 22, 366, 35, 35, 66, 35, 35, 292, - /* 1770 */ 35, 35, 35, 35, 297, 0, 299, 284, 35, 35, - /* 1780 */ 39, 47, 0, 35, 39, 292, 373, 0, 311, 47, - /* 1790 */ 297, 35, 299, 47, 39, 0, 35, 47, 39, 256, - /* 1800 */ 0, 35, 325, 35, 0, 328, 329, 330, 331, 332, - /* 1810 */ 333, 22, 335, 21, 21, 256, 22, 376, 325, 22, - /* 1820 */ 376, 328, 329, 330, 331, 332, 333, 284, 335, 20, - /* 1830 */ 337, 376, 376, 376, 376, 292, 376, 376, 376, 376, - /* 1840 */ 297, 376, 299, 284, 376, 376, 376, 376, 376, 376, - /* 1850 */ 376, 292, 376, 376, 311, 376, 297, 376, 299, 376, - /* 1860 */ 376, 376, 376, 376, 376, 376, 376, 376, 325, 376, - /* 1870 */ 311, 328, 329, 330, 331, 332, 333, 376, 335, 256, - /* 1880 */ 376, 376, 376, 376, 325, 376, 376, 328, 329, 330, - /* 1890 */ 331, 332, 333, 376, 335, 376, 256, 376, 376, 376, - /* 1900 */ 376, 376, 376, 376, 376, 376, 376, 284, 376, 376, - /* 1910 */ 376, 376, 376, 376, 376, 292, 376, 376, 376, 376, - /* 1920 */ 297, 376, 299, 376, 284, 376, 376, 376, 376, 376, - /* 1930 */ 376, 376, 292, 376, 376, 376, 376, 297, 256, 299, - /* 1940 */ 376, 376, 376, 376, 376, 376, 376, 376, 325, 376, - /* 1950 */ 376, 328, 329, 330, 331, 332, 333, 376, 335, 376, - /* 1960 */ 376, 376, 256, 376, 376, 325, 284, 376, 328, 329, - /* 1970 */ 330, 331, 332, 333, 292, 335, 376, 376, 376, 297, - /* 1980 */ 376, 299, 376, 376, 376, 376, 376, 376, 376, 376, - /* 1990 */ 284, 376, 376, 376, 376, 376, 376, 376, 292, 376, - /* 2000 */ 376, 376, 376, 297, 376, 299, 376, 325, 376, 376, - /* 2010 */ 328, 329, 330, 331, 332, 333, 376, 335, 256, 376, - /* 2020 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2030 */ 376, 325, 376, 376, 328, 329, 330, 331, 332, 333, - /* 2040 */ 376, 335, 256, 376, 376, 376, 284, 376, 376, 376, - /* 2050 */ 376, 376, 376, 376, 292, 376, 376, 376, 376, 297, - /* 2060 */ 376, 299, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2070 */ 284, 376, 376, 376, 376, 376, 376, 376, 292, 376, - /* 2080 */ 376, 376, 376, 297, 256, 299, 376, 325, 376, 376, - /* 2090 */ 328, 329, 330, 331, 332, 333, 376, 335, 376, 376, - /* 2100 */ 256, 376, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2110 */ 376, 325, 284, 376, 328, 329, 330, 331, 332, 333, - /* 2120 */ 292, 335, 376, 376, 376, 297, 376, 299, 284, 376, - /* 2130 */ 376, 376, 376, 376, 376, 376, 292, 376, 376, 376, - /* 2140 */ 376, 297, 376, 299, 376, 376, 376, 376, 376, 376, - /* 2150 */ 376, 376, 376, 325, 376, 376, 328, 329, 330, 331, - /* 2160 */ 332, 333, 376, 335, 256, 376, 376, 376, 376, 325, - /* 2170 */ 376, 376, 328, 329, 330, 331, 332, 333, 376, 335, - /* 2180 */ 376, 256, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2190 */ 376, 376, 284, 376, 376, 376, 376, 376, 376, 376, - /* 2200 */ 292, 376, 376, 376, 376, 297, 376, 299, 376, 284, - /* 2210 */ 376, 376, 376, 376, 376, 376, 376, 292, 376, 376, - /* 2220 */ 376, 376, 297, 256, 299, 376, 376, 376, 376, 376, - /* 2230 */ 376, 376, 376, 325, 376, 376, 328, 329, 330, 331, - /* 2240 */ 332, 333, 376, 335, 376, 376, 376, 256, 376, 376, - /* 2250 */ 325, 284, 376, 328, 329, 330, 331, 332, 333, 292, - /* 2260 */ 335, 376, 376, 376, 297, 376, 299, 376, 376, 376, - /* 2270 */ 376, 376, 376, 376, 376, 284, 376, 376, 376, 376, - /* 2280 */ 376, 376, 376, 292, 376, 376, 376, 376, 297, 376, - /* 2290 */ 299, 376, 325, 376, 376, 328, 329, 330, 331, 332, - /* 2300 */ 333, 376, 335, 256, 376, 376, 376, 376, 376, 376, - /* 2310 */ 376, 376, 376, 376, 376, 376, 325, 376, 376, 328, - /* 2320 */ 329, 330, 331, 332, 333, 376, 335, 256, 376, 376, - /* 2330 */ 376, 284, 376, 376, 376, 376, 376, 376, 376, 292, - /* 2340 */ 376, 376, 376, 376, 297, 376, 299, 376, 376, 376, - /* 2350 */ 376, 376, 376, 376, 376, 284, 376, 376, 376, 376, - /* 2360 */ 376, 376, 376, 292, 376, 376, 376, 376, 297, 256, - /* 2370 */ 299, 376, 325, 376, 376, 328, 329, 330, 331, 332, - /* 2380 */ 333, 376, 335, 376, 376, 256, 376, 376, 376, 376, - /* 2390 */ 376, 376, 376, 376, 376, 376, 325, 284, 376, 328, - /* 2400 */ 329, 330, 331, 332, 333, 292, 335, 376, 376, 376, - /* 2410 */ 297, 376, 299, 284, 376, 376, 376, 376, 376, 376, - /* 2420 */ 376, 292, 376, 376, 376, 376, 297, 376, 299, 376, - /* 2430 */ 376, 376, 376, 376, 376, 376, 376, 376, 325, 376, - /* 2440 */ 376, 328, 329, 330, 331, 332, 333, 376, 335, 256, - /* 2450 */ 376, 376, 376, 376, 325, 376, 376, 328, 329, 330, - /* 2460 */ 331, 332, 333, 376, 335, 376, 256, 376, 376, 376, - /* 2470 */ 376, 376, 376, 376, 376, 376, 376, 284, 376, 376, - /* 2480 */ 376, 376, 376, 376, 376, 292, 376, 376, 376, 376, - /* 2490 */ 297, 376, 299, 376, 284, 376, 376, 376, 376, 376, - /* 2500 */ 376, 376, 292, 376, 376, 376, 376, 297, 256, 299, - /* 2510 */ 376, 376, 376, 376, 376, 376, 376, 376, 325, 376, - /* 2520 */ 376, 328, 329, 330, 331, 332, 333, 376, 335, 376, - /* 2530 */ 376, 376, 256, 376, 376, 325, 284, 376, 328, 329, - /* 2540 */ 330, 331, 332, 333, 292, 335, 376, 376, 376, 297, - /* 2550 */ 376, 299, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2560 */ 284, 376, 376, 376, 376, 376, 376, 376, 292, 376, - /* 2570 */ 376, 376, 376, 297, 376, 299, 376, 325, 376, 376, - /* 2580 */ 328, 329, 330, 331, 332, 333, 376, 335, 376, 376, - /* 2590 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, - /* 2600 */ 376, 325, 376, 376, 328, 329, 330, 331, 332, 333, - /* 2610 */ 376, 335, + /* 970 */ 205, 206, 207, 208, 209, 324, 264, 284, 83, 328, + /* 980 */ 329, 330, 331, 332, 333, 292, 335, 275, 297, 338, + /* 990 */ 297, 0, 299, 342, 343, 344, 35, 35, 297, 1, + /* 1000 */ 2, 365, 43, 166, 292, 265, 313, 356, 43, 264, + /* 1010 */ 320, 119, 120, 22, 284, 364, 121, 324, 256, 33, + /* 1020 */ 275, 328, 329, 330, 331, 332, 333, 66, 335, 46, + /* 1030 */ 263, 338, 0, 47, 361, 342, 343, 292, 52, 53, + /* 1040 */ 54, 55, 56, 84, 264, 296, 284, 354, 43, 84, + /* 1050 */ 265, 156, 157, 158, 292, 275, 161, 352, 151, 297, + /* 1060 */ 367, 299, 167, 327, 371, 368, 83, 43, 82, 43, + /* 1070 */ 43, 85, 292, 43, 264, 180, 190, 43, 183, 345, + /* 1080 */ 185, 186, 187, 188, 189, 275, 324, 264, 256, 84, + /* 1090 */ 328, 329, 330, 331, 332, 333, 43, 335, 275, 368, + /* 1100 */ 338, 368, 292, 43, 342, 343, 344, 22, 84, 355, + /* 1110 */ 84, 84, 43, 224, 84, 292, 284, 222, 84, 20, + /* 1120 */ 35, 322, 264, 47, 292, 321, 364, 95, 166, 297, + /* 1130 */ 35, 299, 43, 147, 148, 162, 150, 84, 270, 315, + /* 1140 */ 154, 256, 264, 264, 84, 264, 114, 115, 116, 117, + /* 1150 */ 118, 66, 43, 84, 275, 264, 324, 42, 304, 173, + /* 1160 */ 328, 329, 330, 331, 332, 333, 275, 335, 146, 284, + /* 1170 */ 338, 292, 264, 84, 342, 343, 344, 292, 12, 13, + /* 1180 */ 43, 20, 297, 292, 299, 353, 302, 264, 22, 302, + /* 1190 */ 105, 264, 258, 84, 43, 43, 258, 268, 20, 33, + /* 1200 */ 292, 35, 319, 299, 268, 256, 20, 20, 312, 324, + /* 1210 */ 268, 314, 312, 328, 329, 330, 331, 332, 333, 268, + /* 1220 */ 335, 84, 56, 338, 20, 256, 305, 342, 343, 344, + /* 1230 */ 258, 268, 66, 284, 268, 84, 84, 284, 353, 264, + /* 1240 */ 332, 292, 268, 297, 284, 258, 297, 319, 299, 164, + /* 1250 */ 266, 166, 284, 284, 284, 347, 348, 349, 264, 351, + /* 1260 */ 284, 292, 313, 284, 284, 284, 297, 266, 299, 284, + /* 1270 */ 172, 105, 284, 324, 284, 190, 191, 328, 329, 330, + /* 1280 */ 331, 332, 333, 264, 335, 256, 266, 264, 299, 318, + /* 1290 */ 312, 229, 297, 324, 148, 292, 297, 328, 329, 330, + /* 1300 */ 331, 332, 333, 354, 335, 308, 297, 338, 297, 297, + /* 1310 */ 308, 342, 343, 284, 306, 305, 367, 266, 280, 20, + /* 1320 */ 371, 292, 266, 292, 230, 297, 297, 327, 299, 308, + /* 1330 */ 164, 155, 166, 297, 297, 238, 297, 360, 256, 297, + /* 1340 */ 236, 308, 313, 237, 225, 363, 221, 322, 20, 292, + /* 1350 */ 242, 358, 256, 324, 362, 359, 190, 328, 329, 330, + /* 1360 */ 331, 332, 333, 357, 335, 245, 284, 201, 202, 203, + /* 1370 */ 204, 205, 206, 207, 292, 360, 360, 370, 326, 297, + /* 1380 */ 284, 299, 240, 354, 83, 341, 369, 369, 292, 375, + /* 1390 */ 83, 288, 274, 297, 264, 299, 367, 297, 266, 36, + /* 1400 */ 371, 311, 259, 258, 316, 370, 324, 278, 267, 369, + /* 1410 */ 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + /* 1420 */ 324, 256, 278, 254, 328, 329, 330, 331, 332, 333, + /* 1430 */ 0, 335, 278, 256, 338, 370, 0, 42, 0, 343, + /* 1440 */ 74, 0, 184, 35, 35, 256, 35, 35, 184, 284, + /* 1450 */ 0, 35, 35, 184, 289, 0, 184, 292, 0, 35, + /* 1460 */ 0, 284, 297, 0, 299, 22, 289, 35, 0, 292, + /* 1470 */ 83, 169, 168, 284, 297, 166, 299, 164, 0, 0, + /* 1480 */ 160, 292, 159, 0, 0, 46, 297, 0, 299, 324, + /* 1490 */ 0, 0, 143, 328, 329, 330, 331, 332, 333, 0, + /* 1500 */ 335, 324, 0, 256, 0, 328, 329, 330, 331, 332, + /* 1510 */ 333, 0, 335, 324, 0, 138, 35, 328, 329, 330, + /* 1520 */ 331, 332, 333, 256, 335, 0, 138, 0, 8, 9, + /* 1530 */ 0, 284, 12, 13, 14, 15, 16, 0, 0, 292, + /* 1540 */ 42, 0, 0, 0, 297, 0, 299, 0, 0, 0, + /* 1550 */ 0, 284, 0, 0, 0, 366, 289, 0, 0, 292, + /* 1560 */ 0, 0, 0, 0, 297, 0, 299, 0, 22, 0, + /* 1570 */ 0, 324, 56, 256, 0, 328, 329, 330, 331, 332, + /* 1580 */ 333, 0, 335, 0, 0, 256, 42, 14, 0, 14, + /* 1590 */ 39, 324, 0, 0, 39, 328, 329, 330, 331, 332, + /* 1600 */ 333, 284, 335, 155, 84, 46, 0, 43, 40, 292, + /* 1610 */ 39, 0, 46, 284, 297, 0, 299, 61, 289, 0, + /* 1620 */ 373, 292, 35, 47, 39, 0, 297, 47, 299, 35, + /* 1630 */ 39, 0, 35, 47, 39, 0, 35, 256, 39, 0, + /* 1640 */ 0, 324, 0, 47, 0, 328, 329, 330, 331, 332, + /* 1650 */ 333, 35, 335, 324, 337, 22, 0, 328, 329, 330, + /* 1660 */ 331, 332, 333, 256, 335, 284, 43, 35, 90, 92, + /* 1670 */ 289, 35, 35, 292, 0, 22, 35, 43, 297, 0, + /* 1680 */ 299, 35, 35, 35, 22, 0, 22, 49, 0, 35, + /* 1690 */ 35, 284, 0, 35, 0, 22, 20, 0, 0, 292, + /* 1700 */ 35, 170, 22, 0, 297, 324, 299, 0, 0, 328, + /* 1710 */ 329, 330, 331, 332, 333, 179, 335, 0, 256, 0, + /* 1720 */ 0, 0, 39, 151, 46, 43, 83, 148, 22, 84, + /* 1730 */ 256, 324, 83, 151, 83, 328, 329, 330, 331, 332, + /* 1740 */ 333, 151, 335, 83, 226, 93, 284, 43, 46, 149, + /* 1750 */ 147, 153, 83, 83, 292, 84, 84, 43, 284, 297, + /* 1760 */ 83, 299, 46, 35, 46, 84, 292, 43, 84, 83, + /* 1770 */ 83, 297, 83, 299, 84, 84, 83, 43, 46, 84, + /* 1780 */ 256, 46, 43, 84, 84, 35, 324, 35, 35, 35, + /* 1790 */ 328, 329, 330, 331, 332, 333, 256, 335, 324, 35, + /* 1800 */ 2, 43, 328, 329, 330, 331, 332, 333, 284, 335, + /* 1810 */ 190, 84, 83, 83, 83, 226, 292, 84, 46, 46, + /* 1820 */ 84, 297, 22, 299, 284, 220, 83, 83, 83, 35, + /* 1830 */ 226, 94, 292, 84, 35, 84, 35, 297, 83, 299, + /* 1840 */ 83, 35, 192, 84, 83, 35, 84, 84, 324, 83, + /* 1850 */ 35, 83, 328, 329, 330, 331, 332, 333, 256, 335, + /* 1860 */ 22, 83, 83, 107, 324, 95, 35, 107, 328, 329, + /* 1870 */ 330, 331, 332, 333, 83, 335, 107, 256, 107, 43, + /* 1880 */ 22, 61, 60, 35, 66, 81, 284, 43, 35, 35, + /* 1890 */ 35, 35, 35, 66, 292, 22, 35, 35, 35, 297, + /* 1900 */ 35, 299, 35, 35, 35, 284, 0, 35, 0, 35, + /* 1910 */ 35, 47, 35, 292, 0, 39, 35, 47, 297, 256, + /* 1920 */ 299, 39, 39, 0, 35, 47, 324, 47, 0, 39, + /* 1930 */ 328, 329, 330, 331, 332, 333, 35, 335, 35, 0, + /* 1940 */ 22, 21, 376, 376, 22, 324, 22, 284, 21, 328, + /* 1950 */ 329, 330, 331, 332, 333, 292, 335, 20, 376, 376, + /* 1960 */ 297, 256, 299, 376, 376, 376, 376, 376, 376, 376, + /* 1970 */ 376, 256, 376, 376, 376, 376, 376, 376, 376, 376, + /* 1980 */ 376, 376, 376, 376, 376, 376, 376, 324, 376, 284, + /* 1990 */ 376, 328, 329, 330, 331, 332, 333, 292, 335, 284, + /* 2000 */ 376, 376, 297, 376, 299, 376, 376, 292, 376, 376, + /* 2010 */ 376, 376, 297, 376, 299, 376, 376, 376, 376, 376, + /* 2020 */ 376, 376, 376, 256, 376, 376, 376, 376, 376, 324, + /* 2030 */ 376, 376, 376, 328, 329, 330, 331, 332, 333, 324, + /* 2040 */ 335, 376, 376, 328, 329, 330, 331, 332, 333, 256, + /* 2050 */ 335, 284, 376, 376, 376, 376, 376, 376, 376, 292, + /* 2060 */ 376, 376, 376, 376, 297, 256, 299, 376, 376, 376, + /* 2070 */ 376, 376, 376, 376, 376, 376, 376, 284, 376, 376, + /* 2080 */ 376, 376, 376, 376, 376, 292, 376, 376, 376, 376, + /* 2090 */ 297, 324, 299, 284, 376, 328, 329, 330, 331, 332, + /* 2100 */ 333, 292, 335, 376, 376, 376, 297, 376, 299, 376, + /* 2110 */ 376, 376, 376, 376, 376, 256, 376, 324, 376, 376, + /* 2120 */ 376, 328, 329, 330, 331, 332, 333, 256, 335, 376, + /* 2130 */ 376, 376, 376, 324, 376, 376, 376, 328, 329, 330, + /* 2140 */ 331, 332, 333, 284, 335, 376, 376, 376, 376, 376, + /* 2150 */ 376, 292, 376, 376, 376, 284, 297, 376, 299, 376, + /* 2160 */ 376, 376, 376, 292, 376, 376, 376, 376, 297, 376, + /* 2170 */ 299, 376, 376, 376, 376, 376, 376, 256, 376, 376, + /* 2180 */ 376, 376, 376, 324, 376, 376, 376, 328, 329, 330, + /* 2190 */ 331, 332, 333, 376, 335, 324, 376, 376, 376, 328, + /* 2200 */ 329, 330, 331, 332, 333, 284, 335, 376, 376, 376, + /* 2210 */ 376, 376, 376, 292, 376, 376, 376, 376, 297, 256, + /* 2220 */ 299, 376, 376, 376, 376, 376, 376, 376, 376, 376, + /* 2230 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, + /* 2240 */ 376, 376, 376, 376, 376, 324, 376, 284, 376, 328, + /* 2250 */ 329, 330, 331, 332, 333, 292, 335, 376, 376, 376, + /* 2260 */ 297, 256, 299, 376, 376, 376, 376, 376, 376, 376, + /* 2270 */ 376, 256, 376, 376, 376, 376, 376, 376, 376, 376, + /* 2280 */ 376, 376, 376, 376, 376, 376, 376, 324, 376, 284, + /* 2290 */ 376, 328, 329, 330, 331, 332, 333, 292, 335, 284, + /* 2300 */ 376, 376, 297, 376, 299, 376, 376, 292, 376, 376, + /* 2310 */ 376, 376, 297, 376, 299, 376, 376, 376, 376, 376, + /* 2320 */ 376, 256, 376, 376, 376, 376, 376, 376, 376, 324, + /* 2330 */ 376, 376, 376, 328, 329, 330, 331, 332, 333, 324, + /* 2340 */ 335, 376, 376, 328, 329, 330, 331, 332, 333, 284, + /* 2350 */ 335, 376, 376, 376, 376, 376, 376, 292, 376, 376, + /* 2360 */ 376, 376, 297, 376, 299, 376, 376, 376, 376, 376, + /* 2370 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, + /* 2380 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 324, + /* 2390 */ 376, 376, 376, 328, 329, 330, 331, 332, 333, 376, + /* 2400 */ 335, }; #define YY_SHIFT_COUNT (655) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1809) +#define YY_SHIFT_MAX (1939) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 895, 0, 0, 57, 57, 255, 255, 255, 312, 312, /* 10 */ 255, 255, 510, 567, 765, 567, 567, 567, 567, 567, /* 20 */ 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, /* 30 */ 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - /* 40 */ 567, 567, 47, 47, 96, 96, 96, 1230, 1230, 1230, - /* 50 */ 1230, 442, 50, 263, 65, 65, 64, 64, 54, 261, - /* 60 */ 263, 263, 65, 65, 65, 65, 65, 65, 65, 65, - /* 70 */ 59, 65, 65, 65, 121, 323, 405, 65, 65, 405, - /* 80 */ 65, 405, 405, 405, 65, 408, 761, 224, 479, 479, - /* 90 */ 13, 266, 462, 462, 462, 462, 462, 462, 462, 462, - /* 100 */ 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, - /* 110 */ 462, 706, 261, 524, 524, 285, 636, 548, 548, 548, - /* 120 */ 542, 636, 455, 323, 5, 5, 405, 405, 573, 573, - /* 130 */ 484, 579, 253, 253, 253, 253, 253, 253, 253, 128, - /* 140 */ 531, 81, 414, 364, 41, 105, 43, 145, 460, 515, - /* 150 */ 876, 833, 731, 724, 638, 724, 940, 157, 157, 157, - /* 160 */ 795, 562, 889, 1080, 1079, 1101, 977, 1080, 1080, 1102, - /* 170 */ 1000, 1000, 1080, 1080, 1131, 1131, 1133, 59, 323, 59, - /* 180 */ 1146, 1149, 59, 1146, 59, 1160, 59, 59, 1080, 59, - /* 190 */ 1131, 405, 405, 405, 405, 405, 405, 405, 405, 405, - /* 200 */ 405, 405, 1080, 1131, 573, 1133, 408, 1036, 323, 408, - /* 210 */ 1080, 1080, 1146, 408, 1193, 573, 997, 1003, 573, 997, - /* 220 */ 1003, 573, 573, 405, 1002, 1082, 997, 1009, 1013, 1024, - /* 230 */ 889, 1032, 455, 1241, 1022, 1026, 1023, 1022, 1026, 1022, - /* 240 */ 1026, 1184, 1003, 573, 573, 573, 573, 573, 1003, 573, - /* 250 */ 1137, 455, 1160, 408, 484, 408, 455, 1222, 573, 579, - /* 260 */ 1080, 408, 1274, 1131, 2612, 2612, 2612, 2612, 2612, 2612, - /* 270 */ 2612, 335, 1310, 72, 822, 203, 375, 457, 653, 732, - /* 280 */ 604, 712, 837, 837, 837, 837, 837, 837, 837, 837, - /* 290 */ 178, 688, 432, 16, 16, 198, 450, 588, 449, 53, - /* 300 */ 223, 644, 467, 467, 467, 467, 704, 187, 953, 840, - /* 310 */ 851, 912, 921, 993, 1010, 1028, 958, 861, 961, 976, - /* 320 */ 1038, 928, 694, 834, 986, 864, 988, 576, 1001, 1006, - /* 330 */ 1012, 1014, 1015, 945, 959, 1030, 1043, 1044, 1046, 1048, - /* 340 */ 1050, 1011, 1029, 684, 1325, 1326, 1286, 1330, 1259, 1334, - /* 350 */ 1301, 1153, 1303, 1304, 1306, 1167, 1344, 1318, 1319, 1172, - /* 360 */ 1358, 1183, 1369, 1336, 1372, 1351, 1374, 1340, 1377, 1295, - /* 370 */ 1210, 1212, 1218, 1221, 1382, 1386, 1227, 1229, 1389, 1390, - /* 380 */ 1345, 1393, 1399, 1400, 1254, 1401, 1402, 1403, 1404, 1405, - /* 390 */ 1268, 1373, 1407, 1272, 1411, 1421, 1422, 1423, 1424, 1425, - /* 400 */ 1426, 1427, 1428, 1429, 1430, 1439, 1440, 1441, 1406, 1442, - /* 410 */ 1443, 1444, 1445, 1447, 1449, 1431, 1450, 1452, 1456, 1462, - /* 420 */ 1463, 1409, 1466, 1467, 1432, 1434, 1435, 1454, 1433, 1455, - /* 430 */ 1436, 1470, 1437, 1446, 1471, 1475, 1480, 1457, 1329, 1481, - /* 440 */ 1486, 1488, 1448, 1489, 1498, 1468, 1458, 1465, 1501, 1472, - /* 450 */ 1459, 1473, 1502, 1476, 1474, 1478, 1510, 1479, 1483, 1484, - /* 460 */ 1518, 1519, 1520, 1522, 1451, 1438, 1490, 1504, 1524, 1496, - /* 470 */ 1497, 1499, 1503, 1494, 1507, 1517, 1521, 1525, 1536, 1533, - /* 480 */ 1539, 1535, 1512, 1562, 1541, 1529, 1565, 1531, 1567, 1534, - /* 490 */ 1570, 1560, 1563, 1584, 1453, 1550, 1586, 1417, 1566, 1460, - /* 500 */ 1461, 1590, 1591, 1464, 1485, 1592, 1593, 1595, 1554, 1375, - /* 510 */ 1515, 1516, 1523, 1526, 1556, 1528, 1530, 1537, 1538, 1532, - /* 520 */ 1564, 1568, 1571, 1540, 1575, 1376, 1549, 1552, 1573, 1385, - /* 530 */ 1581, 1588, 1553, 1598, 1416, 1561, 1608, 1612, 1613, 1614, - /* 540 */ 1615, 1616, 1561, 1606, 1469, 1609, 1572, 1574, 1576, 1617, - /* 550 */ 1578, 1579, 1618, 1632, 1482, 1582, 1583, 1587, 1585, 1487, - /* 560 */ 1655, 1600, 1542, 1601, 1670, 1634, 1545, 1602, 1594, 1642, - /* 570 */ 1644, 1603, 1611, 1610, 1676, 1619, 1605, 1620, 1665, 1666, - /* 580 */ 1624, 1622, 1668, 1625, 1627, 1674, 1630, 1631, 1679, 1633, - /* 590 */ 1635, 1683, 1637, 1628, 1629, 1643, 1645, 1695, 1626, 1641, - /* 600 */ 1648, 1688, 1651, 1694, 1694, 1717, 1686, 1680, 1716, 1687, - /* 610 */ 1673, 1712, 1721, 1722, 1723, 1724, 1725, 1740, 1729, 1730, - /* 620 */ 1700, 1494, 1732, 1507, 1733, 1735, 1736, 1737, 1738, 1743, - /* 630 */ 1775, 1744, 1734, 1741, 1782, 1748, 1742, 1745, 1787, 1756, - /* 640 */ 1746, 1755, 1795, 1761, 1750, 1759, 1800, 1766, 1768, 1804, - /* 650 */ 1789, 1792, 1794, 1797, 1793, 1809, + /* 40 */ 567, 567, 567, 64, 64, 86, 86, 86, 1166, 1166, + /* 50 */ 1166, 147, 52, 151, 11, 11, 440, 440, 58, 30, + /* 60 */ 151, 151, 11, 11, 11, 11, 11, 11, 11, 11, + /* 70 */ 22, 11, 11, 11, 26, 271, 11, 11, 271, 376, + /* 80 */ 11, 271, 271, 271, 11, 423, 761, 224, 479, 479, + /* 90 */ 13, 266, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, + /* 100 */ 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, 1085, + /* 110 */ 1085, 206, 30, 81, 81, 115, 586, 605, 41, 41, + /* 120 */ 41, 586, 511, 26, 643, 643, 271, 271, 658, 658, + /* 130 */ 692, 671, 253, 253, 253, 253, 253, 253, 253, 509, + /* 140 */ 720, 309, 291, 38, 524, 305, 418, 617, 657, 267, + /* 150 */ 621, 372, 98, 572, 703, 572, 813, 238, 238, 238, + /* 160 */ 60, 562, 889, 1099, 1076, 1095, 973, 1099, 1099, 1115, + /* 170 */ 1022, 1022, 1099, 1099, 1161, 1161, 1178, 22, 26, 22, + /* 180 */ 1186, 1187, 22, 1186, 22, 1204, 22, 22, 1099, 22, + /* 190 */ 1161, 271, 271, 271, 271, 271, 271, 271, 271, 271, + /* 200 */ 271, 271, 1099, 1161, 658, 1178, 423, 1098, 26, 423, + /* 210 */ 1099, 1099, 1186, 423, 1062, 658, 658, 658, 658, 1062, + /* 220 */ 658, 1146, 511, 1204, 423, 692, 423, 511, 1299, 658, + /* 230 */ 1094, 1062, 658, 658, 1094, 1062, 658, 658, 271, 1104, + /* 240 */ 1176, 1094, 1097, 1106, 1119, 889, 1125, 511, 1328, 1108, + /* 250 */ 1142, 1120, 1108, 1142, 1108, 1142, 1301, 1307, 658, 671, + /* 260 */ 1099, 423, 1363, 1161, 2401, 2401, 2401, 2401, 2401, 2401, + /* 270 */ 2401, 335, 986, 188, 521, 414, 457, 713, 626, 826, + /* 280 */ 907, 1520, 688, 865, 865, 865, 865, 865, 865, 865, + /* 290 */ 865, 1032, 272, 14, 14, 469, 367, 513, 722, 139, + /* 300 */ 34, 95, 584, 669, 669, 669, 669, 560, 959, 821, + /* 310 */ 822, 840, 847, 836, 917, 991, 797, 789, 965, 1005, + /* 320 */ 1024, 1026, 1027, 1034, 837, 962, 1053, 998, 892, 296, + /* 330 */ 349, 1060, 886, 1069, 983, 1030, 1089, 1109, 1137, 1151, + /* 340 */ 1152, 152, 961, 231, 1430, 1436, 1395, 1438, 1366, 1441, + /* 350 */ 1408, 1258, 1409, 1411, 1412, 1264, 1450, 1416, 1417, 1269, + /* 360 */ 1455, 1272, 1458, 1424, 1460, 1443, 1463, 1432, 1468, 1387, + /* 370 */ 1302, 1304, 1309, 1313, 1478, 1479, 1320, 1323, 1483, 1484, + /* 380 */ 1439, 1487, 1490, 1491, 1349, 1499, 1502, 1504, 1511, 1514, + /* 390 */ 1377, 1481, 1525, 1388, 1527, 1530, 1537, 1538, 1545, 1547, + /* 400 */ 1548, 1549, 1550, 1552, 1553, 1554, 1557, 1558, 1498, 1541, + /* 410 */ 1542, 1543, 1560, 1561, 1562, 1546, 1563, 1565, 1567, 1569, + /* 420 */ 1570, 1516, 1574, 1581, 1544, 1551, 1564, 1573, 1559, 1575, + /* 430 */ 1566, 1583, 1568, 1555, 1584, 1588, 1592, 1571, 1448, 1593, + /* 440 */ 1606, 1611, 1556, 1615, 1619, 1587, 1576, 1585, 1625, 1594, + /* 450 */ 1580, 1591, 1631, 1597, 1586, 1595, 1635, 1601, 1596, 1599, + /* 460 */ 1639, 1640, 1642, 1644, 1577, 1578, 1616, 1633, 1656, 1632, + /* 470 */ 1636, 1637, 1641, 1623, 1634, 1646, 1647, 1648, 1674, 1653, + /* 480 */ 1679, 1662, 1638, 1685, 1664, 1654, 1688, 1655, 1692, 1658, + /* 490 */ 1694, 1673, 1676, 1697, 1572, 1665, 1698, 1531, 1680, 1582, + /* 500 */ 1579, 1703, 1707, 1590, 1598, 1708, 1717, 1719, 1643, 1645, + /* 510 */ 1536, 1720, 1649, 1600, 1651, 1721, 1683, 1603, 1660, 1652, + /* 520 */ 1678, 1682, 1518, 1669, 1671, 1670, 1672, 1681, 1677, 1706, + /* 530 */ 1704, 1684, 1686, 1687, 1689, 1690, 1714, 1702, 1716, 1693, + /* 540 */ 1724, 1589, 1691, 1695, 1718, 1605, 1734, 1732, 1735, 1699, + /* 550 */ 1739, 1604, 1700, 1728, 1750, 1752, 1753, 1754, 1764, 1700, + /* 560 */ 1798, 1620, 1758, 1729, 1727, 1730, 1733, 1731, 1736, 1772, + /* 570 */ 1743, 1744, 1773, 1800, 1650, 1745, 1737, 1749, 1794, 1799, + /* 580 */ 1755, 1751, 1801, 1757, 1759, 1806, 1761, 1762, 1810, 1766, + /* 590 */ 1763, 1815, 1768, 1756, 1760, 1769, 1771, 1838, 1770, 1778, + /* 600 */ 1779, 1831, 1791, 1836, 1836, 1858, 1820, 1822, 1848, 1818, + /* 610 */ 1804, 1844, 1853, 1854, 1855, 1856, 1857, 1873, 1861, 1862, + /* 620 */ 1827, 1623, 1863, 1634, 1865, 1867, 1868, 1869, 1872, 1874, + /* 630 */ 1906, 1875, 1864, 1876, 1908, 1877, 1870, 1882, 1914, 1881, + /* 640 */ 1878, 1883, 1923, 1889, 1880, 1890, 1928, 1901, 1903, 1939, + /* 650 */ 1918, 1920, 1922, 1924, 1927, 1937, }; #define YY_REDUCE_COUNT (270) -#define YY_REDUCE_MIN (-289) -#define YY_REDUCE_MAX (2276) +#define YY_REDUCE_MIN (-339) +#define YY_REDUCE_MAX (2065) static const short yy_reduce_ofst[] = { - /* 0 */ -65, -204, 692, 777, 832, 887, 949, 1017, 1084, 1162, - /* 10 */ 533, 1216, 1243, 350, 1297, 1347, 1397, 1413, 1477, 1493, - /* 20 */ 1543, 1559, 1623, 1640, 1682, 1706, 1762, 1786, 1828, 1844, - /* 30 */ 1908, 1925, 1967, 1991, 2047, 2071, 2113, 2129, 2193, 2210, - /* 40 */ 2252, 2276, 237, 289, -178, -106, 488, -278, -271, -276, - /* 50 */ -213, -289, -182, -140, 22, 204, -260, -256, -218, -153, - /* 60 */ -49, -44, 34, 300, 319, 371, 552, 565, 647, 648, - /* 70 */ -267, 650, 651, 711, -275, -283, -2, 56, 713, -56, - /* 80 */ 715, 93, 101, 140, 717, -172, 66, -110, -110, -110, - /* 90 */ 62, 231, 123, 243, 277, 280, 354, 537, 559, 563, - /* 100 */ 577, 582, 611, 654, 690, 698, 701, 729, 741, 744, - /* 110 */ 745, -221, -248, 39, 183, 104, 219, 264, 403, 404, - /* 120 */ 211, 465, 79, 439, 315, 430, 466, 357, 517, 622, - /* 130 */ 657, 512, -249, 497, 522, 539, 543, 557, 587, 491, - /* 140 */ 590, 549, 535, 584, 652, 626, 675, 781, 781, 801, - /* 150 */ 804, 772, 752, 719, 719, 719, 747, 733, 735, 750, - /* 160 */ 742, 781, 799, 859, 813, 867, 824, 874, 878, 841, - /* 170 */ 845, 846, 885, 886, 894, 896, 835, 888, 860, 890, - /* 180 */ 855, 857, 905, 865, 909, 877, 913, 915, 923, 917, - /* 190 */ 930, 906, 907, 908, 910, 911, 914, 916, 918, 919, - /* 200 */ 920, 922, 925, 935, 900, 879, 941, 882, 924, 943, - /* 210 */ 946, 947, 901, 955, 897, 929, 868, 926, 938, 884, - /* 220 */ 931, 939, 948, 781, 891, 893, 898, 892, 899, 902, - /* 230 */ 933, 719, 968, 936, 927, 903, 932, 934, 937, 942, - /* 240 */ 944, 954, 962, 972, 974, 978, 979, 991, 975, 992, - /* 250 */ 984, 1007, 989, 1034, 1018, 1037, 1016, 1027, 1020, 1045, - /* 260 */ 1047, 1052, 1061, 1063, 1005, 1019, 1049, 1051, 1054, 1056, - /* 270 */ 1070, + /* 0 */ -245, -199, 693, 651, 762, 325, 832, 885, 949, 1029, + /* 10 */ 533, 969, 1082, -146, 1096, 1165, 1177, 1189, 1247, 1267, + /* 20 */ 1317, 1329, 1381, 1407, 1462, 1474, 1524, 1540, 1602, 1621, + /* 30 */ 1663, 1705, 1715, 1767, 1793, 1809, 1859, 1871, 1921, 1963, + /* 40 */ 2005, 2015, 2065, -260, 265, -190, 204, 908, -276, -272, + /* 50 */ -4, -289, -255, -69, -112, 326, -257, -244, -200, -171, + /* 60 */ -125, -41, -189, 283, 387, 526, 545, 552, 558, 650, + /* 70 */ -214, 712, 745, 780, 289, 140, 810, 823, 190, -275, + /* 80 */ 879, 257, 320, 531, 891, -264, -228, -339, -339, -339, + /* 90 */ 21, -262, -176, -152, 25, 121, 230, 241, 329, 405, + /* 100 */ 443, 487, 498, 499, 557, 563, 570, 613, 648, 691, + /* 110 */ 701, 31, -74, 130, 240, 28, 73, 472, 75, 149, + /* 120 */ 260, 111, 378, 424, 37, 364, 530, -119, 276, 438, + /* 130 */ 459, 508, 544, 564, 574, 641, 653, 659, 666, 535, + /* 140 */ 590, 655, 580, 636, 740, 690, 673, 730, 730, 785, + /* 150 */ 767, 749, 736, 705, 705, 705, 734, 697, 731, 733, + /* 160 */ 754, 730, 799, 858, 804, 868, 824, 878, 881, 854, + /* 170 */ 884, 887, 923, 927, 934, 938, 883, 929, 904, 936, + /* 180 */ 896, 897, 942, 900, 951, 921, 963, 966, 975, 974, + /* 190 */ 972, 953, 960, 968, 970, 976, 979, 980, 981, 985, + /* 200 */ 988, 990, 994, 987, 946, 928, 984, 971, 989, 1001, + /* 210 */ 1019, 1023, 978, 1020, 997, 995, 999, 1009, 1011, 1002, + /* 220 */ 1012, 1008, 1003, 1010, 1051, 1038, 1056, 1031, 1000, 1028, + /* 230 */ 977, 1021, 1036, 1037, 1015, 1033, 1039, 1042, 730, 982, + /* 240 */ 992, 1016, 996, 993, 1006, 1025, 705, 1057, 1052, 1007, + /* 250 */ 1017, 1014, 1035, 1018, 1065, 1040, 1044, 1103, 1100, 1118, + /* 260 */ 1130, 1132, 1143, 1145, 1088, 1090, 1129, 1144, 1154, 1141, + /* 270 */ 1169, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, @@ -861,8 +819,8 @@ static const YYACTIONTYPE yy_default[] = { /* 80 */ 1441, 1441, 1441, 1441, 1441, 1512, 1665, 1441, 1841, 1441, /* 90 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 100 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, - /* 110 */ 1441, 1441, 1441, 1441, 1441, 1514, 1441, 1853, 1853, 1853, - /* 120 */ 1512, 1441, 1441, 1441, 1709, 1709, 1441, 1441, 1441, 1441, + /* 110 */ 1441, 1441, 1441, 1441, 1441, 1514, 1441, 1512, 1853, 1853, + /* 120 */ 1853, 1441, 1441, 1441, 1709, 1709, 1441, 1441, 1441, 1441, /* 130 */ 1608, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1701, /* 140 */ 1441, 1441, 1922, 1441, 1441, 1707, 1876, 1441, 1441, 1441, /* 150 */ 1441, 1561, 1868, 1845, 1859, 1846, 1843, 1907, 1907, 1907, @@ -871,19 +829,19 @@ static const YYACTIONTYPE yy_default[] = { /* 180 */ 1441, 1441, 1514, 1441, 1514, 1441, 1514, 1514, 1441, 1514, /* 190 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 200 */ 1441, 1441, 1441, 1441, 1441, 1441, 1512, 1703, 1441, 1512, - /* 210 */ 1441, 1441, 1441, 1512, 1441, 1441, 1883, 1881, 1441, 1883, - /* 220 */ 1881, 1441, 1441, 1441, 1895, 1891, 1883, 1899, 1897, 1874, - /* 230 */ 1872, 1859, 1441, 1441, 1913, 1909, 1925, 1913, 1909, 1913, - /* 240 */ 1909, 1441, 1881, 1441, 1441, 1441, 1441, 1441, 1881, 1441, - /* 250 */ 1441, 1441, 1441, 1512, 1441, 1512, 1441, 1577, 1441, 1441, + /* 210 */ 1441, 1441, 1441, 1512, 1881, 1441, 1441, 1441, 1441, 1881, + /* 220 */ 1441, 1441, 1441, 1441, 1512, 1441, 1512, 1441, 1441, 1441, + /* 230 */ 1883, 1881, 1441, 1441, 1883, 1881, 1441, 1441, 1441, 1895, + /* 240 */ 1891, 1883, 1899, 1897, 1874, 1872, 1859, 1441, 1441, 1913, + /* 250 */ 1909, 1925, 1913, 1909, 1913, 1909, 1441, 1577, 1441, 1441, /* 260 */ 1441, 1512, 1473, 1441, 1695, 1709, 1611, 1611, 1611, 1515, /* 270 */ 1446, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, - /* 280 */ 1441, 1441, 1779, 1894, 1893, 1817, 1816, 1815, 1813, 1778, - /* 290 */ 1441, 1441, 1573, 1777, 1776, 1441, 1441, 1441, 1441, 1441, - /* 300 */ 1441, 1441, 1770, 1771, 1769, 1768, 1441, 1441, 1441, 1441, + /* 280 */ 1441, 1441, 1441, 1779, 1894, 1893, 1817, 1816, 1815, 1813, + /* 290 */ 1778, 1441, 1573, 1777, 1776, 1441, 1441, 1441, 1441, 1441, + /* 300 */ 1441, 1441, 1441, 1770, 1771, 1769, 1768, 1441, 1441, 1441, /* 310 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, - /* 320 */ 1842, 1441, 1910, 1914, 1441, 1441, 1441, 1753, 1441, 1441, - /* 330 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 320 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1842, 1441, 1910, + /* 330 */ 1914, 1441, 1441, 1441, 1753, 1441, 1441, 1441, 1441, 1441, /* 340 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 350 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 360 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, @@ -900,14 +858,14 @@ static const YYACTIONTYPE yy_default[] = { /* 470 */ 1441, 1441, 1441, 1542, 1541, 1441, 1441, 1441, 1441, 1441, /* 480 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 490 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, - /* 500 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1875, 1441, - /* 510 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, - /* 520 */ 1441, 1441, 1753, 1441, 1892, 1441, 1852, 1848, 1441, 1441, - /* 530 */ 1844, 1441, 1441, 1908, 1441, 1441, 1441, 1441, 1441, 1441, - /* 540 */ 1441, 1441, 1441, 1837, 1441, 1810, 1441, 1441, 1441, 1441, - /* 550 */ 1441, 1441, 1441, 1441, 1764, 1441, 1441, 1441, 1441, 1441, - /* 560 */ 1713, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1752, - /* 570 */ 1441, 1795, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 500 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 510 */ 1441, 1713, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 520 */ 1441, 1875, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 530 */ 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1753, 1441, + /* 540 */ 1892, 1441, 1852, 1848, 1441, 1441, 1844, 1752, 1441, 1441, + /* 550 */ 1908, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, + /* 560 */ 1837, 1441, 1810, 1795, 1441, 1441, 1441, 1441, 1441, 1441, + /* 570 */ 1441, 1441, 1441, 1441, 1764, 1441, 1441, 1441, 1441, 1441, /* 580 */ 1605, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, 1441, /* 590 */ 1441, 1441, 1441, 1590, 1588, 1587, 1586, 1441, 1583, 1441, /* 600 */ 1441, 1441, 1441, 1614, 1613, 1441, 1441, 1441, 1441, 1441, @@ -1564,7 +1522,7 @@ static const char *const yyTokenName[] = { /* 286 */ "signed_literal", /* 287 */ "create_subtable_clause", /* 288 */ "specific_tags_opt", - /* 289 */ "literal_list", + /* 289 */ "expression_list", /* 290 */ "drop_table_clause", /* 291 */ "col_name_list", /* 292 */ "table_name", @@ -1586,21 +1544,21 @@ static const char *const yyTokenName[] = { /* 308 */ "sliding_opt", /* 309 */ "sma_stream_opt", /* 310 */ "func", - /* 311 */ "expression_list", - /* 312 */ "stream_options", - /* 313 */ "topic_name", - /* 314 */ "query_expression", - /* 315 */ "cgroup_name", - /* 316 */ "analyze_opt", - /* 317 */ "explain_options", - /* 318 */ "agg_func_opt", - /* 319 */ "bufsize_opt", - /* 320 */ "stream_name", - /* 321 */ "into_opt", - /* 322 */ "dnode_list", - /* 323 */ "where_clause_opt", - /* 324 */ "signed", - /* 325 */ "literal_func", + /* 311 */ "stream_options", + /* 312 */ "topic_name", + /* 313 */ "query_expression", + /* 314 */ "cgroup_name", + /* 315 */ "analyze_opt", + /* 316 */ "explain_options", + /* 317 */ "agg_func_opt", + /* 318 */ "bufsize_opt", + /* 319 */ "stream_name", + /* 320 */ "into_opt", + /* 321 */ "dnode_list", + /* 322 */ "where_clause_opt", + /* 323 */ "signed", + /* 324 */ "literal_func", + /* 325 */ "literal_list", /* 326 */ "table_alias", /* 327 */ "column_alias", /* 328 */ "expression", @@ -1787,7 +1745,7 @@ static const char *const yyRuleName[] = { /* 126 */ "alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal", /* 127 */ "multi_create_clause ::= create_subtable_clause", /* 128 */ "multi_create_clause ::= multi_create_clause create_subtable_clause", - /* 129 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP table_options", + /* 129 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP expression_list NK_RP table_options", /* 130 */ "multi_drop_clause ::= drop_table_clause", /* 131 */ "multi_drop_clause ::= multi_drop_clause drop_table_clause", /* 132 */ "drop_table_clause ::= exists_opt full_table_name", @@ -2292,13 +2250,13 @@ static void yy_destructor( case 308: /* sliding_opt */ case 309: /* sma_stream_opt */ case 310: /* func */ - case 312: /* stream_options */ - case 314: /* query_expression */ - case 317: /* explain_options */ - case 321: /* into_opt */ - case 323: /* where_clause_opt */ - case 324: /* signed */ - case 325: /* literal_func */ + case 311: /* stream_options */ + case 313: /* query_expression */ + case 316: /* explain_options */ + case 320: /* into_opt */ + case 322: /* where_clause_opt */ + case 323: /* signed */ + case 324: /* literal_func */ case 328: /* expression */ case 329: /* pseudo_column */ case 330: /* column_reference */ @@ -2336,7 +2294,7 @@ static void yy_destructor( case 254: /* account_options */ case 255: /* alter_account_options */ case 257: /* alter_account_option */ - case 319: /* bufsize_opt */ + case 318: /* bufsize_opt */ { } @@ -2349,9 +2307,9 @@ static void yy_destructor( case 292: /* table_name */ case 299: /* function_name */ case 305: /* index_name */ - case 313: /* topic_name */ - case 315: /* cgroup_name */ - case 320: /* stream_name */ + case 312: /* topic_name */ + case 314: /* cgroup_name */ + case 319: /* stream_name */ case 326: /* table_alias */ case 327: /* column_alias */ case 333: /* star_func */ @@ -2375,8 +2333,8 @@ static void yy_destructor( break; case 266: /* not_exists_opt */ case 268: /* exists_opt */ - case 316: /* analyze_opt */ - case 318: /* agg_func_opt */ + case 315: /* analyze_opt */ + case 317: /* agg_func_opt */ case 355: /* set_quantifier_opt */ { @@ -2391,13 +2349,13 @@ static void yy_destructor( case 280: /* tags_def */ case 281: /* multi_drop_clause */ case 288: /* specific_tags_opt */ - case 289: /* literal_list */ + case 289: /* expression_list */ case 291: /* col_name_list */ case 294: /* duration_list */ case 295: /* rollup_func_list */ case 307: /* func_list */ - case 311: /* expression_list */ - case 322: /* dnode_list */ + case 321: /* dnode_list */ + case 325: /* literal_list */ case 334: /* star_func_para_list */ case 336: /* other_para_list */ case 356: /* select_list */ @@ -2870,7 +2828,7 @@ static const struct { { 282, -6 }, /* (126) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ { 279, -1 }, /* (127) multi_create_clause ::= create_subtable_clause */ { 279, -2 }, /* (128) multi_create_clause ::= multi_create_clause create_subtable_clause */ - { 287, -10 }, /* (129) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP table_options */ + { 287, -10 }, /* (129) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP expression_list NK_RP table_options */ { 281, -1 }, /* (130) multi_drop_clause ::= drop_table_clause */ { 281, -2 }, /* (131) multi_drop_clause ::= multi_drop_clause drop_table_clause */ { 290, -2 }, /* (132) drop_table_clause ::= exists_opt full_table_name */ @@ -2990,28 +2948,28 @@ static const struct { { 253, -2 }, /* (246) cmd ::= DESCRIBE full_table_name */ { 253, -3 }, /* (247) cmd ::= RESET QUERY CACHE */ { 253, -4 }, /* (248) cmd ::= EXPLAIN analyze_opt explain_options query_expression */ - { 316, 0 }, /* (249) analyze_opt ::= */ - { 316, -1 }, /* (250) analyze_opt ::= ANALYZE */ - { 317, 0 }, /* (251) explain_options ::= */ - { 317, -3 }, /* (252) explain_options ::= explain_options VERBOSE NK_BOOL */ - { 317, -3 }, /* (253) explain_options ::= explain_options RATIO NK_FLOAT */ + { 315, 0 }, /* (249) analyze_opt ::= */ + { 315, -1 }, /* (250) analyze_opt ::= ANALYZE */ + { 316, 0 }, /* (251) explain_options ::= */ + { 316, -3 }, /* (252) explain_options ::= explain_options VERBOSE NK_BOOL */ + { 316, -3 }, /* (253) explain_options ::= explain_options RATIO NK_FLOAT */ { 253, -6 }, /* (254) cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ { 253, -10 }, /* (255) cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ { 253, -4 }, /* (256) cmd ::= DROP FUNCTION exists_opt function_name */ - { 318, 0 }, /* (257) agg_func_opt ::= */ - { 318, -1 }, /* (258) agg_func_opt ::= AGGREGATE */ - { 319, 0 }, /* (259) bufsize_opt ::= */ - { 319, -2 }, /* (260) bufsize_opt ::= BUFSIZE NK_INTEGER */ + { 317, 0 }, /* (257) agg_func_opt ::= */ + { 317, -1 }, /* (258) agg_func_opt ::= AGGREGATE */ + { 318, 0 }, /* (259) bufsize_opt ::= */ + { 318, -2 }, /* (260) bufsize_opt ::= BUFSIZE NK_INTEGER */ { 253, -8 }, /* (261) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ { 253, -4 }, /* (262) cmd ::= DROP STREAM exists_opt stream_name */ - { 321, 0 }, /* (263) into_opt ::= */ - { 321, -2 }, /* (264) into_opt ::= INTO full_table_name */ - { 312, 0 }, /* (265) stream_options ::= */ - { 312, -3 }, /* (266) stream_options ::= stream_options TRIGGER AT_ONCE */ - { 312, -3 }, /* (267) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - { 312, -4 }, /* (268) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - { 312, -3 }, /* (269) stream_options ::= stream_options WATERMARK duration_literal */ - { 312, -3 }, /* (270) stream_options ::= stream_options IGNORE EXPIRED */ + { 320, 0 }, /* (263) into_opt ::= */ + { 320, -2 }, /* (264) into_opt ::= INTO full_table_name */ + { 311, 0 }, /* (265) stream_options ::= */ + { 311, -3 }, /* (266) stream_options ::= stream_options TRIGGER AT_ONCE */ + { 311, -3 }, /* (267) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + { 311, -4 }, /* (268) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + { 311, -3 }, /* (269) stream_options ::= stream_options WATERMARK duration_literal */ + { 311, -3 }, /* (270) stream_options ::= stream_options IGNORE EXPIRED */ { 253, -3 }, /* (271) cmd ::= KILL CONNECTION NK_INTEGER */ { 253, -3 }, /* (272) cmd ::= KILL QUERY NK_STRING */ { 253, -3 }, /* (273) cmd ::= KILL TRANSACTION NK_INTEGER */ @@ -3019,8 +2977,8 @@ static const struct { { 253, -4 }, /* (275) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ { 253, -4 }, /* (276) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ { 253, -3 }, /* (277) cmd ::= SPLIT VGROUP NK_INTEGER */ - { 322, -2 }, /* (278) dnode_list ::= DNODE NK_INTEGER */ - { 322, -3 }, /* (279) dnode_list ::= dnode_list DNODE NK_INTEGER */ + { 321, -2 }, /* (278) dnode_list ::= DNODE NK_INTEGER */ + { 321, -3 }, /* (279) dnode_list ::= dnode_list DNODE NK_INTEGER */ { 253, -3 }, /* (280) cmd ::= SYNCDB db_name REPLICA */ { 253, -4 }, /* (281) cmd ::= DELETE FROM full_table_name where_clause_opt */ { 253, -1 }, /* (282) cmd ::= query_expression */ @@ -3033,12 +2991,12 @@ static const struct { { 256, -1 }, /* (289) literal ::= NULL */ { 256, -1 }, /* (290) literal ::= NK_QUESTION */ { 297, -1 }, /* (291) duration_literal ::= NK_VARIABLE */ - { 324, -1 }, /* (292) signed ::= NK_INTEGER */ - { 324, -2 }, /* (293) signed ::= NK_PLUS NK_INTEGER */ - { 324, -2 }, /* (294) signed ::= NK_MINUS NK_INTEGER */ - { 324, -1 }, /* (295) signed ::= NK_FLOAT */ - { 324, -2 }, /* (296) signed ::= NK_PLUS NK_FLOAT */ - { 324, -2 }, /* (297) signed ::= NK_MINUS NK_FLOAT */ + { 323, -1 }, /* (292) signed ::= NK_INTEGER */ + { 323, -2 }, /* (293) signed ::= NK_PLUS NK_INTEGER */ + { 323, -2 }, /* (294) signed ::= NK_MINUS NK_INTEGER */ + { 323, -1 }, /* (295) signed ::= NK_FLOAT */ + { 323, -2 }, /* (296) signed ::= NK_PLUS NK_FLOAT */ + { 323, -2 }, /* (297) signed ::= NK_MINUS NK_FLOAT */ { 286, -1 }, /* (298) signed_literal ::= signed */ { 286, -1 }, /* (299) signed_literal ::= NK_STRING */ { 286, -1 }, /* (300) signed_literal ::= NK_BOOL */ @@ -3046,8 +3004,8 @@ static const struct { { 286, -1 }, /* (302) signed_literal ::= duration_literal */ { 286, -1 }, /* (303) signed_literal ::= NULL */ { 286, -1 }, /* (304) signed_literal ::= literal_func */ - { 289, -1 }, /* (305) literal_list ::= signed_literal */ - { 289, -3 }, /* (306) literal_list ::= literal_list NK_COMMA signed_literal */ + { 325, -1 }, /* (305) literal_list ::= signed_literal */ + { 325, -3 }, /* (306) literal_list ::= literal_list NK_COMMA signed_literal */ { 264, -1 }, /* (307) db_name ::= NK_ID */ { 292, -1 }, /* (308) table_name ::= NK_ID */ { 284, -1 }, /* (309) column_name ::= NK_ID */ @@ -3056,9 +3014,9 @@ static const struct { { 327, -1 }, /* (312) column_alias ::= NK_ID */ { 258, -1 }, /* (313) user_name ::= NK_ID */ { 305, -1 }, /* (314) index_name ::= NK_ID */ - { 313, -1 }, /* (315) topic_name ::= NK_ID */ - { 320, -1 }, /* (316) stream_name ::= NK_ID */ - { 315, -1 }, /* (317) cgroup_name ::= NK_ID */ + { 312, -1 }, /* (315) topic_name ::= NK_ID */ + { 319, -1 }, /* (316) stream_name ::= NK_ID */ + { 314, -1 }, /* (317) cgroup_name ::= NK_ID */ { 328, -1 }, /* (318) expression ::= literal */ { 328, -1 }, /* (319) expression ::= pseudo_column */ { 328, -1 }, /* (320) expression ::= column_reference */ @@ -3075,8 +3033,8 @@ static const struct { { 328, -3 }, /* (331) expression ::= column_reference NK_ARROW NK_STRING */ { 328, -3 }, /* (332) expression ::= expression NK_BITAND expression */ { 328, -3 }, /* (333) expression ::= expression NK_BITOR expression */ - { 311, -1 }, /* (334) expression_list ::= expression */ - { 311, -3 }, /* (335) expression_list ::= expression_list NK_COMMA expression */ + { 289, -1 }, /* (334) expression_list ::= expression */ + { 289, -3 }, /* (335) expression_list ::= expression_list NK_COMMA expression */ { 330, -1 }, /* (336) column_reference ::= column_name */ { 330, -3 }, /* (337) column_reference ::= table_name NK_DOT column_name */ { 329, -1 }, /* (338) pseudo_column ::= ROWTS */ @@ -3091,8 +3049,8 @@ static const struct { { 331, -4 }, /* (347) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ { 331, -6 }, /* (348) function_expression ::= CAST NK_LP expression AS type_name NK_RP */ { 331, -1 }, /* (349) function_expression ::= literal_func */ - { 325, -3 }, /* (350) literal_func ::= noarg_func NK_LP NK_RP */ - { 325, -1 }, /* (351) literal_func ::= NOW */ + { 324, -3 }, /* (350) literal_func ::= noarg_func NK_LP NK_RP */ + { 324, -1 }, /* (351) literal_func ::= NOW */ { 335, -1 }, /* (352) noarg_func ::= NOW */ { 335, -1 }, /* (353) noarg_func ::= TODAY */ { 335, -1 }, /* (354) noarg_func ::= TIMEZONE */ @@ -3169,8 +3127,8 @@ static const struct { { 364, -2 }, /* (425) select_item ::= common_expression column_alias */ { 364, -3 }, /* (426) select_item ::= common_expression AS column_alias */ { 364, -3 }, /* (427) select_item ::= table_name NK_DOT NK_STAR */ - { 323, 0 }, /* (428) where_clause_opt ::= */ - { 323, -2 }, /* (429) where_clause_opt ::= WHERE search_condition */ + { 322, 0 }, /* (428) where_clause_opt ::= */ + { 322, -2 }, /* (429) where_clause_opt ::= WHERE search_condition */ { 357, 0 }, /* (430) partition_by_clause_opt ::= */ { 357, -3 }, /* (431) partition_by_clause_opt ::= PARTITION BY expression_list */ { 361, 0 }, /* (432) twindow_clause_opt ::= */ @@ -3198,7 +3156,7 @@ static const struct { { 358, -6 }, /* (454) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ { 359, 0 }, /* (455) every_opt ::= */ { 359, -4 }, /* (456) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - { 314, -4 }, /* (457) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + { 313, -4 }, /* (457) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ { 367, -1 }, /* (458) query_expression_body ::= query_primary */ { 367, -4 }, /* (459) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ { 367, -3 }, /* (460) query_expression_body ::= query_expression_body UNION query_expression_body */ @@ -3696,10 +3654,12 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy89, yymsp[0].minor.yy248); } break; case 115: /* cmd ::= ALTER TABLE alter_table_clause */ - case 116: /* cmd ::= ALTER STABLE alter_table_clause */ yytestcase(yyruleno==116); case 282: /* cmd ::= query_expression */ yytestcase(yyruleno==282); { pCxt->pRootNode = yymsp[0].minor.yy248; } break; + case 116: /* cmd ::= ALTER STABLE alter_table_clause */ +{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy248); } + break; case 117: /* alter_table_clause ::= full_table_name alter_table_options */ { yylhsminor.yy248 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy248, yymsp[0].minor.yy248); } yymsp[-1].minor.yy248 = yylhsminor.yy248; @@ -3745,7 +3705,7 @@ static YYACTIONTYPE yy_reduce( { yylhsminor.yy552 = addNodeToList(pCxt, yymsp[-1].minor.yy552, yymsp[0].minor.yy248); } yymsp[-1].minor.yy552 = yylhsminor.yy552; break; - case 129: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP table_options */ + case 129: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP expression_list NK_RP table_options */ { yylhsminor.yy248 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy89, yymsp[-8].minor.yy248, yymsp[-6].minor.yy248, yymsp[-5].minor.yy552, yymsp[-2].minor.yy552, yymsp[0].minor.yy248); } yymsp[-9].minor.yy248 = yylhsminor.yy248; break; diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 36a2eb3808..6eafa0555b 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -159,7 +159,7 @@ void generatePerformanceSchema(MockCatalogService* mcs) { * c4 | column | DOUBLE | 8 | * c5 | column | DOUBLE | 8 | */ -void generateTestT1(MockCatalogService* mcs) { +void generateTestTables(MockCatalogService* mcs) { ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 6) .setPrecision(TSDB_TIME_PRECISION_MILLI) .setVgid(1) @@ -183,23 +183,7 @@ void generateTestT1(MockCatalogService* mcs) { * tag2 | tag | VARCHAR | 20 | * tag3 | tag | TIMESTAMP | 8 | * Child Table: st1s1, st1s2 - */ -void generateTestST1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 3) - .setPrecision(TSDB_TIME_PRECISION_MILLI) - .addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) - .addColumn("c1", TSDB_DATA_TYPE_INT) - .addColumn("c2", TSDB_DATA_TYPE_BINARY, 20) - .addTag("tag1", TSDB_DATA_TYPE_INT) - .addTag("tag2", TSDB_DATA_TYPE_BINARY, 20) - .addTag("tag3", TSDB_DATA_TYPE_TIMESTAMP); - builder.done(); - mcs->createSubTable("test", "st1", "st1s1", 1); - mcs->createSubTable("test", "st1", "st1s2", 2); - mcs->createSubTable("test", "st1", "st1s3", 1); -} - -/* + * * Super Table: st2 * Field | Type | DataType | Bytes | * ========================================================================== @@ -209,16 +193,32 @@ void generateTestST1(MockCatalogService* mcs) { * jtag | tag | json | -- | * Child Table: st2s1, st2s2 */ -void generateTestST2(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("test", "st2", TSDB_SUPER_TABLE, 3, 1) - .setPrecision(TSDB_TIME_PRECISION_MILLI) - .addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) - .addColumn("c1", TSDB_DATA_TYPE_INT) - .addColumn("c2", TSDB_DATA_TYPE_BINARY, 20) - .addTag("jtag", TSDB_DATA_TYPE_JSON); - builder.done(); - mcs->createSubTable("test", "st2", "st2s1", 1); - mcs->createSubTable("test", "st2", "st2s2", 2); +void generateTestStables(MockCatalogService* mcs) { + { + ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 3) + .setPrecision(TSDB_TIME_PRECISION_MILLI) + .addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) + .addColumn("c1", TSDB_DATA_TYPE_INT) + .addColumn("c2", TSDB_DATA_TYPE_BINARY, 20) + .addTag("tag1", TSDB_DATA_TYPE_INT) + .addTag("tag2", TSDB_DATA_TYPE_BINARY, 20) + .addTag("tag3", TSDB_DATA_TYPE_TIMESTAMP); + builder.done(); + mcs->createSubTable("test", "st1", "st1s1", 1); + mcs->createSubTable("test", "st1", "st1s2", 2); + mcs->createSubTable("test", "st1", "st1s3", 1); + } + { + ITableBuilder& builder = mcs->createTableBuilder("test", "st2", TSDB_SUPER_TABLE, 3, 1) + .setPrecision(TSDB_TIME_PRECISION_MILLI) + .addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) + .addColumn("c1", TSDB_DATA_TYPE_INT) + .addColumn("c2", TSDB_DATA_TYPE_BINARY, 20) + .addTag("jtag", TSDB_DATA_TYPE_JSON); + builder.done(); + mcs->createSubTable("test", "st2", "st2s1", 1); + mcs->createSubTable("test", "st2", "st2s2", 2); + } } void generateFunctions(MockCatalogService* mcs) { @@ -233,6 +233,11 @@ void generateDnodes(MockCatalogService* mcs) { mcs->createDnode(3, "host3", 7030); } +void generateDatabases(MockCatalogService* mcs) { + mcs->createDatabase("test"); + mcs->createDatabase("rollup_db", true); +} + } // namespace int32_t __catalogGetHandle(const char* clusterId, struct SCatalog** catalogHandle) { return 0; } @@ -262,7 +267,7 @@ int32_t __catalogGetDBVgInfo(SCatalog* pCtg, SRequestConnInfo* pConn, const char } int32_t __catalogGetDBCfg(SCatalog* pCtg, SRequestConnInfo* pConn, const char* dbFName, SDbCfgInfo* pDbCfg) { - return 0; + return g_mockCatalogService->catalogGetDBCfg(dbFName, pDbCfg); } int32_t __catalogChkAuth(SCatalog* pCtg, SRequestConnInfo* pConn, const char* user, const char* dbFName, AUTH_TYPE type, @@ -359,11 +364,11 @@ void initMetaDataEnv() { } void generateMetaData() { + generateDatabases(g_mockCatalogService.get()); generateInformationSchema(g_mockCatalogService.get()); generatePerformanceSchema(g_mockCatalogService.get()); - generateTestT1(g_mockCatalogService.get()); - generateTestST1(g_mockCatalogService.get()); - generateTestST2(g_mockCatalogService.get()); + generateTestTables(g_mockCatalogService.get()); + generateTestStables(g_mockCatalogService.get()); generateFunctions(g_mockCatalogService.get()); generateDnodes(g_mockCatalogService.get()); g_mockCatalogService->showTables(); diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 8830bc7cb3..0f759018d9 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -140,6 +140,17 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } + int32_t catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pDbCfg) const { + std::string dbFName(pDbFName); + DbCfgCache::const_iterator it = dbCfg_.find(dbFName.substr(std::string(pDbFName).find_last_of('.') + 1)); + if (dbCfg_.end() == it) { + return TSDB_CODE_FAILED; + } + + memcpy(pDbCfg, &(it->second), sizeof(SDbCfgInfo)); + return TSDB_CODE_SUCCESS; + } + int32_t catalogGetUdfInfo(const std::string& funcName, SFuncInfo* pInfo) const { auto it = udf_.find(funcName); if (udf_.end() == it) { @@ -323,12 +334,21 @@ class MockCatalogServiceImpl { dnode_.insert(std::make_pair(dnodeId, epSet)); } + void createDatabase(const std::string& db, bool rollup) { + SDbCfgInfo cfg = {0}; + if (rollup) { + cfg.pRetensions = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SRetention)); + } + dbCfg_.insert(std::make_pair(db, cfg)); + } + private: typedef std::map> TableMetaCache; typedef std::map DbMetaCache; typedef std::map> UdfMetaCache; typedef std::map> IndexMetaCache; typedef std::map DnodeCache; + typedef std::map DbCfgCache; uint64_t getNextId() { return id_++; } @@ -486,6 +506,7 @@ class MockCatalogServiceImpl { for (int32_t i = 0; i < ndbs; ++i) { SMetaRes res = {0}; res.pRes = taosMemoryCalloc(1, sizeof(SDbCfgInfo)); + res.code = catalogGetDBCfg((const char*)taosArrayGet(pDbCfgReq, i), (SDbCfgInfo*)res.pRes); taosArrayPush(*pDbCfgData, &res); } } @@ -576,6 +597,7 @@ class MockCatalogServiceImpl { UdfMetaCache udf_; IndexMetaCache index_; DnodeCache dnode_; + DbCfgCache dbCfg_; }; MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) {} @@ -605,6 +627,8 @@ void MockCatalogService::createDnode(int32_t dnodeId, const std::string& host, i impl_->createDnode(dnodeId, host, port); } +void MockCatalogService::createDatabase(const std::string& db, bool rollup) { impl_->createDatabase(db, rollup); } + int32_t MockCatalogService::catalogGetTableMeta(const SName* pTableName, STableMeta** pTableMeta) const { return impl_->catalogGetTableMeta(pTableName, pTableMeta); } @@ -621,6 +645,10 @@ int32_t MockCatalogService::catalogGetDBVgInfo(const char* pDbFName, SArray** pV return impl_->catalogGetDBVgInfo(pDbFName, pVgList); } +int32_t MockCatalogService::catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pDbCfg) const { + return impl_->catalogGetDBCfg(pDbFName, pDbCfg); +} + int32_t MockCatalogService::catalogGetUdfInfo(const std::string& funcName, SFuncInfo* pInfo) const { return impl_->catalogGetUdfInfo(funcName, pInfo); } diff --git a/source/libs/parser/test/mockCatalogService.h b/source/libs/parser/test/mockCatalogService.h index 932424823c..5c8a8acad1 100644 --- a/source/libs/parser/test/mockCatalogService.h +++ b/source/libs/parser/test/mockCatalogService.h @@ -63,11 +63,13 @@ class MockCatalogService { void createFunction(const std::string& func, int8_t funcType, int8_t outputType, int32_t outputLen, int32_t bufSize); void createSmaIndex(const SMCreateSmaReq* pReq); void createDnode(int32_t dnodeId, const std::string& host, int16_t port); + void createDatabase(const std::string& db, bool rollup = false); int32_t catalogGetTableMeta(const SName* pTableName, STableMeta** pTableMeta) const; int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const; int32_t catalogGetTableDistVgInfo(const SName* pTableName, SArray** pVgList) const; int32_t catalogGetDBVgInfo(const char* pDbFName, SArray** pVgList) const; + int32_t catalogGetDBCfg(const char* pDbFName, SDbCfgInfo* pDbCfg) const; int32_t catalogGetUdfInfo(const std::string& funcName, SFuncInfo* pInfo) const; int32_t catalogGetTableIndex(const SName* pTableName, SArray** pIndexes) const; int32_t catalogGetDnodeList(SArray** pDnodes) const; diff --git a/source/libs/parser/test/parInitialATest.cpp b/source/libs/parser/test/parInitialATest.cpp index ee9dae2a01..f4d0ba1cc8 100644 --- a/source/libs/parser/test/parInitialATest.cpp +++ b/source/libs/parser/test/parInitialATest.cpp @@ -38,9 +38,9 @@ TEST_F(ParserInitialATest, alterDnode) { TEST_F(ParserInitialATest, alterDatabase) { useDb("root", "test"); - run("ALTER DATABASE wxy_db CACHELAST 1 FSYNC 200 WAL 1"); + run("ALTER DATABASE test CACHELAST 1 FSYNC 200 WAL 1"); - run("ALTER DATABASE wxy_db KEEP 2400"); + run("ALTER DATABASE test KEEP 2400"); } TEST_F(ParserInitialATest, alterLocal) { @@ -77,8 +77,6 @@ TEST_F(ParserInitialATest, alterLocal) { clearAlterLocal(); } -// todo ALTER stable - /* * ALTER TABLE [db_name.]tb_name alter_table_clause * @@ -157,7 +155,7 @@ TEST_F(ParserInitialATest, alterSTable) { }; setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { - ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_TABLE_STMT); + ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_SUPER_TABLE_STMT); SMAlterStbReq req = {0}; ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS); ASSERT_EQ(std::string(req.name), std::string(expect.name)); @@ -181,44 +179,44 @@ TEST_F(ParserInitialATest, alterSTable) { }); // setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, nullptr, 10); - // run("ALTER TABLE st1 TTL 10"); + // run("ALTER STABLE st1 TTL 10"); // clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, "test"); - run("ALTER TABLE st1 COMMENT 'test'"); + run("ALTER STABLE st1 COMMENT 'test'"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_COLUMN, 1, "cc1", TSDB_DATA_TYPE_BIGINT); - run("ALTER TABLE st1 ADD COLUMN cc1 BIGINT"); + run("ALTER STABLE st1 ADD COLUMN cc1 BIGINT"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_COLUMN, 1, "c1"); - run("ALTER TABLE st1 DROP COLUMN c1"); + run("ALTER STABLE st1 DROP COLUMN c1"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c2", TSDB_DATA_TYPE_VARCHAR, 30 + VARSTR_HEADER_SIZE); - run("ALTER TABLE st1 MODIFY COLUMN c2 VARCHAR(30)"); + run("ALTER STABLE st1 MODIFY COLUMN c2 VARCHAR(30)"); clearAlterStbReq(); // setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1"); - // run("ALTER TABLE st1 RENAME COLUMN c1 cc1"); + // run("ALTER STABLE st1 RENAME COLUMN c1 cc1"); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT); - run("ALTER TABLE st1 ADD TAG tag11 BIGINT"); + run("ALTER STABLE st1 ADD TAG tag11 BIGINT"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_TAG, 1, "tag1"); - run("ALTER TABLE st1 DROP TAG tag1"); + run("ALTER STABLE st1 DROP TAG tag1"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, 1, "tag2", TSDB_DATA_TYPE_VARCHAR, 30 + VARSTR_HEADER_SIZE); - run("ALTER TABLE st1 MODIFY TAG tag2 VARCHAR(30)"); + run("ALTER STABLE st1 MODIFY TAG tag2 VARCHAR(30)"); clearAlterStbReq(); setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_NAME, 2, "tag1", 0, 0, "tag11"); - run("ALTER TABLE st1 RENAME TAG tag1 tag11"); + run("ALTER STABLE st1 RENAME TAG tag1 tag11"); clearAlterStbReq(); // todo @@ -228,11 +226,11 @@ TEST_F(ParserInitialATest, alterSTable) { TEST_F(ParserInitialATest, alterSTableSemanticCheck) { useDb("root", "test"); - run("ALTER TABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE); + run("ALTER STABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE); - run("ALTER TABLE st1 MODIFY COLUMN c2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL); + run("ALTER STABLE st1 MODIFY COLUMN c2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL); - run("ALTER TABLE st1 MODIFY TAG tag2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL); + run("ALTER STABLE st1 MODIFY TAG tag2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL); } TEST_F(ParserInitialATest, alterTable) { diff --git a/source/libs/parser/test/parInitialCTest.cpp b/source/libs/parser/test/parInitialCTest.cpp index 0a980fa889..10921a2082 100644 --- a/source/libs/parser/test/parInitialCTest.cpp +++ b/source/libs/parser/test/parInitialCTest.cpp @@ -359,11 +359,11 @@ TEST_F(ParserInitialCTest, createStable) { memset(&expect, 0, sizeof(SMCreateStbReq)); }; - auto setCreateStbReqFunc = [&](const char* pTbname, int8_t igExists = 0, int64_t delay1 = -1, int64_t delay2 = -1, - int64_t watermark1 = TSDB_DEFAULT_ROLLUP_WATERMARK, + auto setCreateStbReqFunc = [&](const char* pDbName, const char* pTbName, int8_t igExists = 0, int64_t delay1 = -1, + int64_t delay2 = -1, int64_t watermark1 = TSDB_DEFAULT_ROLLUP_WATERMARK, int64_t watermark2 = TSDB_DEFAULT_ROLLUP_WATERMARK, int32_t ttl = TSDB_DEFAULT_TABLE_TTL, const char* pComment = nullptr) { - int32_t len = snprintf(expect.name, sizeof(expect.name), "0.test.%s", pTbname); + int32_t len = snprintf(expect.name, sizeof(expect.name), "0.%s.%s", pDbName, pTbName); expect.name[len] = '\0'; expect.igExists = igExists; expect.delay1 = delay1; @@ -454,14 +454,14 @@ TEST_F(ParserInitialCTest, createStable) { tFreeSMCreateStbReq(&req); }); - setCreateStbReqFunc("t1"); + setCreateStbReqFunc("test", "t1"); addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP); addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT); addFieldToCreateStbReqFunc(false, "id", TSDB_DATA_TYPE_INT); run("CREATE STABLE t1(ts TIMESTAMP, c1 INT) TAGS(id INT)"); clearCreateStbReq(); - setCreateStbReqFunc("t1", 1, 100 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_MINUTE, 10, + setCreateStbReqFunc("rollup_db", "t1", 1, 100 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_MINUTE, 10, 1 * MILLISECOND_PER_MINUTE, 100, "test create table"); addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0); addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT); @@ -493,7 +493,7 @@ TEST_F(ParserInitialCTest, createStable) { addFieldToCreateStbReqFunc(false, "a13", TSDB_DATA_TYPE_BOOL); addFieldToCreateStbReqFunc(false, "a14", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); addFieldToCreateStbReqFunc(false, "a15", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE); - run("CREATE STABLE IF NOT EXISTS test.t1(" + run("CREATE STABLE IF NOT EXISTS rollup_db.t1(" "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), " "c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, " "c13 NCHAR(30), c14 VARCHAR(50)) " @@ -507,12 +507,13 @@ TEST_F(ParserInitialCTest, createStable) { TEST_F(ParserInitialCTest, createStableSemanticCheck) { useDb("root", "test"); - run("CREATE STABLE stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(CEIL)", TSDB_CODE_PAR_INVALID_ROLLUP_OPTION); + run("CREATE STABLE rollup_db.stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(CEIL)", + TSDB_CODE_PAR_INVALID_ROLLUP_OPTION); - run("CREATE STABLE stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(MAX) MAX_DELAY 0s WATERMARK 1m", + run("CREATE STABLE rollup_db.stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(MAX) MAX_DELAY 0s WATERMARK 1m", TSDB_CODE_PAR_INVALID_RANGE_OPTION); - run("CREATE STABLE stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(MAX) MAX_DELAY 10s WATERMARK 18m", + run("CREATE STABLE rollup_db.stb2 (ts TIMESTAMP, c1 INT) TAGS (tag1 INT) ROLLUP(MAX) MAX_DELAY 10s WATERMARK 18m", TSDB_CODE_PAR_INVALID_RANGE_OPTION); } @@ -561,30 +562,33 @@ TEST_F(ParserInitialCTest, createStream) { tFreeSCMCreateStreamReq(&req); }); - setCreateStreamReqFunc("s1", "test", "create stream s1 as select * from t1"); - run("CREATE STREAM s1 AS SELECT * FROM t1"); + setCreateStreamReqFunc("s1", "test", "create stream s1 as select count(*) from t1 interval(10s)"); + run("CREATE STREAM s1 AS SELECT COUNT(*) FROM t1 INTERVAL(10S)"); clearCreateStreamReq(); - setCreateStreamReqFunc("s1", "test", "create stream if not exists s1 as select * from t1", nullptr, 1); - run("CREATE STREAM IF NOT EXISTS s1 AS SELECT * FROM t1"); + setCreateStreamReqFunc("s1", "test", "create stream if not exists s1 as select count(*) from t1 interval(10s)", + nullptr, 1); + run("CREATE STREAM IF NOT EXISTS s1 AS SELECT COUNT(*) FROM t1 INTERVAL(10S)"); clearCreateStreamReq(); - setCreateStreamReqFunc("s1", "test", "create stream s1 into st1 as select * from t1", "st1"); - run("CREATE STREAM s1 INTO st1 AS SELECT * FROM t1"); + setCreateStreamReqFunc("s1", "test", "create stream s1 into st1 as select count(*) from t1 interval(10s)", "st1"); + run("CREATE STREAM s1 INTO st1 AS SELECT COUNT(*) FROM t1 INTERVAL(10S)"); clearCreateStreamReq(); - setCreateStreamReqFunc( - "s1", "test", - "create stream if not exists s1 trigger max_delay 20s watermark 10s ignore expired into st1 as select * from t1", - "st1", 1, STREAM_TRIGGER_MAX_DELAY, 20 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_SECOND, 1); - run("CREATE STREAM IF NOT EXISTS s1 TRIGGER MAX_DELAY 20s WATERMARK 10s IGNORE EXPIRED INTO st1 AS SELECT * FROM t1"); + setCreateStreamReqFunc("s1", "test", + "create stream if not exists s1 trigger max_delay 20s watermark 10s ignore expired into st1 " + "as select count(*) from t1 interval(10s)", + "st1", 1, STREAM_TRIGGER_MAX_DELAY, 20 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_SECOND, + 1); + run("CREATE STREAM IF NOT EXISTS s1 TRIGGER MAX_DELAY 20s WATERMARK 10s IGNORE EXPIRED INTO st1 AS SELECT COUNT(*) " + "FROM t1 INTERVAL(10S)"); clearCreateStreamReq(); } TEST_F(ParserInitialCTest, createStreamSemanticCheck) { useDb("root", "test"); - run("CREATE STREAM s1 AS SELECT PERCENTILE(c1, 30) FROM t1", TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC); + run("CREATE STREAM s1 AS SELECT PERCENTILE(c1, 30) FROM t1 INTERVAL(10S)", TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC); } TEST_F(ParserInitialCTest, createTable) { @@ -598,7 +602,7 @@ TEST_F(ParserInitialCTest, createTable) { "c13 NCHAR(30), c15 VARCHAR(50)) " "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)"); - run("CREATE TABLE IF NOT EXISTS test.t1(" + run("CREATE TABLE IF NOT EXISTS rollup_db.t1(" "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), " "c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, " "c13 NCHAR(30), c14 VARCHAR(50)) " @@ -617,6 +621,21 @@ TEST_F(ParserInitialCTest, createTable) { // run("CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy', NOW + 1S)"); } +TEST_F(ParserInitialCTest, createTableSemanticCheck) { + useDb("root", "test"); + + string sql = "CREATE TABLE st1(ts TIMESTAMP, "; + for (int32_t i = 1; i < 4096; ++i) { + if (i > 1) { + sql.append(", "); + } + sql.append("c" + to_string(i) + " INT"); + } + sql.append(") TAGS (t1 int)"); + + run(sql, TSDB_CODE_PAR_TOO_MANY_COLUMNS); +} + TEST_F(ParserInitialCTest, createTopic) { useDb("root", "test"); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index fb27602c21..88930b6269 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -720,7 +720,7 @@ static int32_t pushDownCondOptDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAg // TODO: remove it after full implementation of pushing down to child if (1 != LIST_LENGTH(pAgg->node.pChildren) || QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pAgg->node.pChildren, 0)) && - QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) { + QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) { return TSDB_CODE_SUCCESS; } @@ -1251,7 +1251,7 @@ static SNode* partTagsCreateWrapperFunc(const char* pFuncName, SNode* pNode) { } strcpy(pFunc->functionName, pFuncName); - if (QUERY_NODE_COLUMN == nodeType(pNode)) { + if (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType) { SColumnNode* pCol = (SColumnNode*)pNode; partTagsSetAlias(pFunc->node.aliasName, sizeof(pFunc->node.aliasName), pCol->tableAlias, pCol->colName); } else { @@ -1868,6 +1868,8 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) { pCxt->errCode = terrno; return DEAL_RES_ERROR; } + snprintf(((SExprNode*)pExpr)->aliasName, sizeof(((SExprNode*)pExpr)->aliasName), "%s", + ((SExprNode*)*pNode)->aliasName); nodesDestroyNode(*pNode); *pNode = pExpr; } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index aac9c25f77..0eb05ccbe9 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -552,6 +552,9 @@ static int32_t createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* if (0 == strcmp(pScanLogicNode->tableName.tname, TSDB_INS_TABLE_USER_TABLES) || 0 == strcmp(pScanLogicNode->tableName.tname, TSDB_INS_TABLE_USER_TABLE_DISTRIBUTED)) { vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); + } else { + pSubplan->execNode.nodeId = MNODE_HANDLE; + pSubplan->execNode.epSet = pCxt->pPlanCxt->mgmtEpSet; } SQueryNodeLoad node = {.addr = {.nodeId = MNODE_HANDLE, .epSet = pCxt->pPlanCxt->mgmtEpSet}, .load = 0}; taosArrayPush(pCxt->pExecNodeList, &node); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 60c04c2c30..467a46169a 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -986,6 +986,10 @@ static bool unionIsChildSubplan(SLogicNode* pLogicNode, int32_t groupId) { return ((SExchangeLogicNode*)pLogicNode)->srcGroupId == groupId; } + if (QUERY_NODE_LOGIC_PLAN_MERGE == nodeType(pLogicNode)) { + return ((SMergeLogicNode*)pLogicNode)->srcGroupId == groupId; + } + SNode* pChild; FOREACH(pChild, pLogicNode->pChildren) { bool isChild = unionIsChildSubplan((SLogicNode*)pChild, groupId); @@ -1014,14 +1018,14 @@ static int32_t unionMountSubplan(SLogicSubplan* pParent, SNodeList* pChildren) { return TSDB_CODE_SUCCESS; } -static SLogicSubplan* unionCreateSubplan(SSplitContext* pCxt, SLogicNode* pNode) { +static SLogicSubplan* unionCreateSubplan(SSplitContext* pCxt, SLogicNode* pNode, ESubplanType subplanType) { SLogicSubplan* pSubplan = (SLogicSubplan*)nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN); if (NULL == pSubplan) { return NULL; } pSubplan->id.queryId = pCxt->queryId; pSubplan->id.groupId = pCxt->groupId; - pSubplan->subplanType = SUBPLAN_TYPE_SCAN; + pSubplan->subplanType = subplanType; pSubplan->pNode = pNode; pNode->pParent = NULL; return pSubplan; @@ -1035,7 +1039,7 @@ static int32_t unionSplitSubplan(SSplitContext* pCxt, SLogicSubplan* pUnionSubpl SNode* pChild = NULL; FOREACH(pChild, pSplitNode->pChildren) { - SLogicSubplan* pNewSubplan = unionCreateSubplan(pCxt, (SLogicNode*)pChild); + SLogicSubplan* pNewSubplan = unionCreateSubplan(pCxt, (SLogicNode*)pChild, pUnionSubplan->subplanType); code = nodesListMakeStrictAppend(&pUnionSubplan->pChildren, (SNode*)pNewSubplan); if (TSDB_CODE_SUCCESS == code) { REPLACE_NODE(NULL); diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp index 6a9a711dac..3994db0902 100644 --- a/source/libs/planner/test/planOptimizeTest.cpp +++ b/source/libs/planner/test/planOptimizeTest.cpp @@ -68,6 +68,8 @@ TEST_F(PlanOptimizeTest, PartitionTags) { run("SELECT SUM(c1), tag1 FROM st1 GROUP BY tag1"); run("SELECT SUM(c1), tag1 + 10 FROM st1 GROUP BY tag1 + 10"); + + run("SELECT SUM(c1), tbname FROM st1 GROUP BY tbname"); } TEST_F(PlanOptimizeTest, eliminateProjection) { diff --git a/source/libs/planner/test/planSetOpTest.cpp b/source/libs/planner/test/planSetOpTest.cpp index 62e017052e..de6d7466b8 100644 --- a/source/libs/planner/test/planSetOpTest.cpp +++ b/source/libs/planner/test/planSetOpTest.cpp @@ -97,7 +97,15 @@ TEST_F(PlanSetOpTest, unionSubquery) { run("SELECT * FROM (SELECT c1, c2 FROM t1 UNION SELECT c1, c2 FROM t1)"); } -TEST_F(PlanSetOpTest, bug001) { +TEST_F(PlanSetOpTest, unionWithSubquery) { + useDb("root", "test"); + + run("SELECT c1 FROM (SELECT c1 FROM st1) UNION SELECT c2 FROM (SELECT c1 AS c2 FROM st2)"); + + run("SELECT c1 FROM (SELECT c1 FROM st1 ORDER BY c2) UNION SELECT c1 FROM (SELECT c1 FROM st2)"); +} + +TEST_F(PlanSetOpTest, unionDataTypeConversion) { useDb("root", "test"); run("SELECT c2 FROM t1 WHERE c1 IS NOT NULL GROUP BY c2 " diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 28959d03af..9a5a3d1bc9 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -930,11 +930,6 @@ int32_t qwProcessDelete(QW_FPARAMS_DEF, SQWMsg *qwMsg, SDeleteRes *pRes) { } ctx.plan = plan; - - /* XXXXXXXXXXXXXXXXXXXX */ - SReadHandle *phandle = (SReadHandle*)qwMsg->node; - phandle->deleteQuery = 1; - /* XXXXXXXXXXXXXXXXXXXX */ code = qCreateExecTask(qwMsg->node, mgmt->nodeId, tId, plan, &pTaskInfo, &sinkHandle, NULL, OPTR_EXEC_MODEL_BATCH); if (code) { diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index ba6bd4bd5f..cbb1089d61 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -1035,3 +1035,72 @@ _return: sclFreeRes(ctx.pRes); return code; } + +int32_t scalarGetOperatorResultType(SDataType left, SDataType right, EOperatorType op, SDataType* pRes) { + switch (op) { + case OP_TYPE_ADD: + if (left.type == TSDB_DATA_TYPE_TIMESTAMP && right.type == TSDB_DATA_TYPE_TIMESTAMP) { + qError("invalid op %d, left type:%d, right type:%d", op, left.type, right.type); + return TSDB_CODE_TSC_INVALID_OPERATION; + } + if ((left.type == TSDB_DATA_TYPE_TIMESTAMP && (IS_INTEGER_TYPE(right.type) || right.type == TSDB_DATA_TYPE_BOOL)) || + (right.type == TSDB_DATA_TYPE_TIMESTAMP && (IS_INTEGER_TYPE(left.type) || left.type == TSDB_DATA_TYPE_BOOL))) { + pRes->type = TSDB_DATA_TYPE_TIMESTAMP; + return TSDB_CODE_SUCCESS; + } + pRes->type = TSDB_DATA_TYPE_DOUBLE; + return TSDB_CODE_SUCCESS; + case OP_TYPE_SUB: + if ((left.type == TSDB_DATA_TYPE_TIMESTAMP && right.type == TSDB_DATA_TYPE_BIGINT) || + (right.type == TSDB_DATA_TYPE_TIMESTAMP && left.type == TSDB_DATA_TYPE_BIGINT)) { + pRes->type = TSDB_DATA_TYPE_TIMESTAMP; + return TSDB_CODE_SUCCESS; + } + pRes->type = TSDB_DATA_TYPE_DOUBLE; + return TSDB_CODE_SUCCESS; + case OP_TYPE_MULTI: + if (left.type == TSDB_DATA_TYPE_TIMESTAMP && right.type == TSDB_DATA_TYPE_TIMESTAMP) { + qError("invalid op %d, left type:%d, right type:%d", op, left.type, right.type); + return TSDB_CODE_TSC_INVALID_OPERATION; + } + case OP_TYPE_DIV: + if (left.type == TSDB_DATA_TYPE_TIMESTAMP && right.type == TSDB_DATA_TYPE_TIMESTAMP) { + qError("invalid op %d, left type:%d, right type:%d", op, left.type, right.type); + return TSDB_CODE_TSC_INVALID_OPERATION; + } + case OP_TYPE_REM: + case OP_TYPE_MINUS: + pRes->type = TSDB_DATA_TYPE_DOUBLE; + return TSDB_CODE_SUCCESS; + case OP_TYPE_GREATER_THAN: + case OP_TYPE_GREATER_EQUAL: + case OP_TYPE_LOWER_THAN: + case OP_TYPE_LOWER_EQUAL: + case OP_TYPE_EQUAL: + case OP_TYPE_NOT_EQUAL: + case OP_TYPE_IN: + case OP_TYPE_NOT_IN: + case OP_TYPE_LIKE: + case OP_TYPE_NOT_LIKE: + case OP_TYPE_MATCH: + case OP_TYPE_NMATCH: + case OP_TYPE_IS_NULL: + case OP_TYPE_IS_NOT_NULL: + case OP_TYPE_IS_TRUE: + case OP_TYPE_JSON_CONTAINS: + pRes->type = TSDB_DATA_TYPE_BOOL; + return TSDB_CODE_SUCCESS; + case OP_TYPE_BIT_AND: + case OP_TYPE_BIT_OR: + pRes->type = TSDB_DATA_TYPE_BIGINT; + return TSDB_CODE_SUCCESS; + case OP_TYPE_JSON_GET_VALUE: + pRes->type = TSDB_DATA_TYPE_JSON; + return TSDB_CODE_SUCCESS; + default: + ASSERT(0); + return TSDB_CODE_APP_ERROR; + } +} + + diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index f35f81892d..e6b7c75564 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -360,9 +360,6 @@ static void trtrim(char *input, char *output, int32_t type, int32_t charLen) { static int32_t doLengthFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput, _len_fn lenFn) { int32_t type = GET_PARAM_TYPE(pInput); - if (inputNum != 1 || !IS_VAR_DATA_TYPE(type)) { - return TSDB_CODE_FAILED; - } SColumnInfoData *pInputData = pInput->columnData; SColumnInfoData *pOutputData = pOutput->columnData; @@ -586,9 +583,6 @@ DONE: static int32_t doCaseConvFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput, _conv_fn convFn) { int32_t type = GET_PARAM_TYPE(pInput); - if (inputNum != 1 || !IS_VAR_DATA_TYPE(type)) { - return TSDB_CODE_FAILED; - } SColumnInfoData *pInputData = pInput->columnData; SColumnInfoData *pOutputData = pOutput->columnData; @@ -628,9 +622,6 @@ static int32_t doCaseConvFunction(SScalarParam *pInput, int32_t inputNum, SScala static int32_t doTrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput, _trim_fn trimFn) { int32_t type = GET_PARAM_TYPE(pInput); - if (inputNum != 1 || !IS_VAR_DATA_TYPE(type)) { - return TSDB_CODE_FAILED; - } SColumnInfoData *pInputData = pInput->columnData; SColumnInfoData *pOutputData = pOutput->columnData; @@ -664,16 +655,10 @@ static int32_t doTrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarPar int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int32_t subPos = 0; GET_TYPED_DATA(subPos, int32_t, GET_PARAM_TYPE(&pInput[1]), pInput[1].columnData->pData); - if (subPos == 0) { //subPos needs to be positive or negative values; - return TSDB_CODE_FAILED; - } int32_t subLen = INT16_MAX; if (inputNum == 3) { GET_TYPED_DATA(subLen, int32_t, GET_PARAM_TYPE(&pInput[2]), pInput[2].columnData->pData); - if (subLen < 0 || subLen > INT16_MAX) { //subLen cannot be negative - return TSDB_CODE_FAILED; - } subLen = (GET_PARAM_TYPE(pInput) == TSDB_DATA_TYPE_VARCHAR) ? subLen : subLen * TSDB_NCHAR_SIZE; } @@ -1149,13 +1134,6 @@ int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarP int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int32_t type = GET_PARAM_TYPE(pInput); - if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { - return TSDB_CODE_FAILED; - } - - if (inputNum != 1) { - return TSDB_CODE_FAILED; - } char tmp[TSDB_MAX_JSON_TAG_LEN] = {0}; for (int32_t i = 0; i < pInput[0].numOfRows; ++i) { @@ -1196,6 +1174,8 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); + timeUnit = timeUnit * 1000 / factor; + for (int32_t i = 0; i < pInput[0].numOfRows; ++i) { if (colDataIsNull_s(pInput[0].columnData, i)) { colDataAppendNULL(pOutput->columnData, i); @@ -1228,7 +1208,6 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara char buf[20] = {0}; NUM_TO_STRING(TSDB_DATA_TYPE_BIGINT, &timeVal, sizeof(buf), buf); int32_t tsDigits = (int32_t)strlen(buf); - timeUnit = timeUnit * 1000 / factor; switch (timeUnit) { case 0: { /* 1u */ @@ -1384,6 +1363,11 @@ int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p GET_TYPED_DATA(timePrec, int64_t, GET_PARAM_TYPE(&pInput[2]), pInput[2].columnData->pData); } + int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : + (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); + + timeUnit = timeUnit * 1000 / factor; + int32_t numOfRows = 0; for (int32_t i = 0; i < inputNum; ++i) { if (pInput[i].numOfRows > numOfRows) { @@ -1463,9 +1447,6 @@ int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p } } } else { - int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 : - (timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000); - timeUnit = timeUnit * 1000 / factor; switch(timeUnit) { case 0: { /* 1u */ result = result / 1000; diff --git a/source/libs/scheduler/src/schJob.c b/source/libs/scheduler/src/schJob.c index 6e4838e50c..56ebc21568 100644 --- a/source/libs/scheduler/src/schJob.c +++ b/source/libs/scheduler/src/schJob.c @@ -184,9 +184,7 @@ FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) { } if ((*pJob->chkKillFp)(pJob->chkKillParam)) { - schUpdateJobStatus(pJob, JOB_TASK_STATUS_DROPPING); schUpdateJobErrCode(pJob, TSDB_CODE_TSC_QUERY_KILLED); - return true; } @@ -669,6 +667,11 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { return TSDB_CODE_SUCCESS; } + if (SCH_IS_DATA_SRC_QRY_TASK(pTask)) { + SCH_TASK_ELOG("no execNode specifed for data src task, numOfEps:%d", pTask->plan->execNode.epSet.numOfEps); + SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + SCH_ERR_RET(schSetAddrsFromNodeList(pJob, pTask)); /* @@ -811,14 +814,6 @@ int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) { */ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bool *needRetry) { - int8_t status = 0; - - if (schJobNeedToStop(pJob, &status)) { - *needRetry = false; - SCH_TASK_DLOG("task no more retry cause of job status, job status:%s", jobTaskStatusStr(status)); - return TSDB_CODE_SUCCESS; - } - if (TSDB_CODE_SCH_TIMEOUT_ERROR == errCode) { pTask->maxExecTimes++; if (pTask->timeoutUsec < SCH_MAX_TASK_TIMEOUT_USEC) { @@ -1277,7 +1272,7 @@ int32_t schProcessOnTaskStatusRsp(SQueryNodeEpId* pEpId, SArray* pStatusList) { for (int32_t i = 0; i < taskNum; ++i) { STaskStatus *taskStatus = taosArrayGet(pStatusList, i); - qDebug("QID:%" PRIx64 ",TID:0x%" PRIx64 ",EID:%d task status in server: %s", + qDebug("QID:0x%" PRIx64 ",TID:0x%" PRIx64 ",EID:%d task status in server: %s", taskStatus->queryId, taskStatus->taskId, taskStatus->execId, jobTaskStatusStr(taskStatus->status)); SSchJob *pJob = schAcquireJob(taskStatus->refId); @@ -1495,6 +1490,8 @@ void schFreeJobImpl(void *job) { uint64_t queryId = pJob->queryId; int64_t refId = pJob->refId; + qDebug("QID:0x%" PRIx64 " begin to free sch job, refId:0x%" PRIx64 ", pointer:%p", queryId, refId, pJob); + if (pJob->status == JOB_TASK_STATUS_EXECUTING) { schCancelJob(pJob); } @@ -1535,12 +1532,12 @@ void schFreeJobImpl(void *job) { taosMemoryFreeClear(pJob->resData); taosMemoryFree(pJob); - qDebug("QID:0x%" PRIx64 " sch job freed, refId:0x%" PRIx64 ", pointer:%p", queryId, refId, pJob); - int32_t jobNum = atomic_sub_fetch_32(&schMgmt.jobNum, 1); if (jobNum == 0) { schCloseJobRef(); } + + qDebug("QID:0x%" PRIx64 " sch job freed, refId:0x%" PRIx64 ", pointer:%p", queryId, refId, pJob); } int32_t schLaunchStaticExplainJob(SSchedulerReq *pReq, SSchJob *pJob, bool sync) { @@ -1687,11 +1684,6 @@ _return: int32_t schDoTaskRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf* pData, int32_t rspCode) { int32_t code = 0; - int8_t status = 0; - if (schJobNeedToStop(pJob, &status)) { - SCH_TASK_ELOG("redirect will no continue cause of job status %s", jobTaskStatusStr(status)); - SCH_RET(atomic_load_32(&pJob->errCode)); - } if ((pTask->execId + 1) >= pTask->maxExecTimes) { SCH_TASK_DLOG("task no more retry since reach max try times, execId:%d", pTask->execId); diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c index dcada39f09..07b2560824 100644 --- a/source/libs/scheduler/src/schRemote.c +++ b/source/libs/scheduler/src/schRemote.c @@ -405,13 +405,17 @@ int32_t schHandleCallback(void *param, SDataBuf *pMsg, int32_t rspCode) { code = schHandleRedirect(pJob, pTask, (SDataBuf *)pMsg, rspCode); goto _return; } - - code = schHandleResponseMsg(pJob, pTask, msgType, pMsg->pData, pMsg->len, rspCode); + + schHandleResponseMsg(pJob, pTask, msgType, pMsg->pData, pMsg->len, rspCode); pMsg->pData = NULL; _return: if (pTask) { + if (code) { + schProcessOnTaskFailure(pJob, pTask, code); + } + SCH_UNLOCK_TASK(pTask); } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 74ddc89b40..e2389c2a75 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -225,26 +225,33 @@ void schedulerStopQueryHb(void *pTrans) { schCleanClusterHb(pTrans); } -void schedulerFreeJob(int64_t job, int32_t errCode) { - SSchJob *pJob = schAcquireJob(job); +void schedulerFreeJob(int64_t* job, int32_t errCode) { + if (0 == *job) { + return; + } + + SSchJob *pJob = schAcquireJob(*job); if (NULL == pJob) { - qError("acquire job from jobRef list failed, may be dropped, jobId:0x%" PRIx64, job); + qError("acquire sch job failed, may be dropped, jobId:0x%" PRIx64, *job); + *job = 0; return; } int32_t code = schProcessOnJobDropped(pJob, errCode); if (TSDB_CODE_SCH_JOB_IS_DROPPING == code) { - SCH_JOB_DLOG("sch job is already dropping, refId:0x%" PRIx64, job); + SCH_JOB_DLOG("sch job is already dropping, refId:0x%" PRIx64, *job); + *job = 0; return; } - SCH_JOB_DLOG("start to remove job from jobRef list, refId:0x%" PRIx64, job); + SCH_JOB_DLOG("start to remove job from jobRef list, refId:0x%" PRIx64, *job); - if (taosRemoveRef(schMgmt.jobRef, job)) { - SCH_JOB_ELOG("remove job from job list failed, refId:0x%" PRIx64, job); + if (taosRemoveRef(schMgmt.jobRef, *job)) { + SCH_JOB_ELOG("remove job from job list failed, refId:0x%" PRIx64, *job); } - schReleaseJob(job); + schReleaseJob(*job); + *job = 0; } void schedulerDestroy(void) { diff --git a/source/libs/scheduler/test/schedulerTests.cpp b/source/libs/scheduler/test/schedulerTests.cpp index 098699744d..7fe6cc22bf 100644 --- a/source/libs/scheduler/test/schedulerTests.cpp +++ b/source/libs/scheduler/test/schedulerTests.cpp @@ -457,7 +457,7 @@ void schtFreeQueryJob(int32_t freeThread) { int64_t job = queryJobRefId; if (job && atomic_val_compare_exchange_64(&queryJobRefId, job, 0)) { - schedulerFreeJob(job, 0); + schedulerFreeJob(&job, 0); if (freeThread) { if (++freeNum % schtTestPrintNum == 0) { printf("FreeNum:%d\n", freeNum); @@ -724,7 +724,7 @@ TEST(queryTest, normalCase) { schReleaseJob(job); - schedulerFreeJob(job, 0); + schedulerFreeJob(&job, 0); schtFreeQueryDag(&dag); @@ -828,7 +828,7 @@ TEST(queryTest, readyFirstCase) { schReleaseJob(job); - schedulerFreeJob(job, 0); + schedulerFreeJob(&job, 0); schtFreeQueryDag(&dag); @@ -940,7 +940,7 @@ TEST(queryTest, flowCtrlCase) { schReleaseJob(job); - schedulerFreeJob(job, 0); + schedulerFreeJob(&job, 0); schtFreeQueryDag(&dag); @@ -994,7 +994,7 @@ TEST(insertTest, normalCase) { ASSERT_EQ(code, 0); ASSERT_EQ(res.numOfRows, 20); - schedulerFreeJob(insertJobRefId, 0); + schedulerFreeJob(&insertJobRefId, 0); schedulerDestroy(); } diff --git a/source/libs/sync/inc/syncAppendEntriesReply.h b/source/libs/sync/inc/syncAppendEntriesReply.h index 70ce5a72c6..03148252fb 100644 --- a/source/libs/sync/inc/syncAppendEntriesReply.h +++ b/source/libs/sync/inc/syncAppendEntriesReply.h @@ -44,11 +44,6 @@ int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* p int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg); int32_t syncNodeOnAppendEntriesReplySnapshot2Cb(SSyncNode* ths, SyncAppendEntriesReply* pMsg); -typedef struct SReaderParam { - SyncIndex start; - SyncIndex end; -} SReaderParam; - #ifdef __cplusplus } #endif diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h index 66e5d28bdd..8936cd6ed9 100644 --- a/source/libs/sync/inc/syncInt.h +++ b/source/libs/sync/inc/syncInt.h @@ -174,8 +174,9 @@ int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak); int32_t syncNodeProposeBatch(SSyncNode* pSyncNode, SRpcMsg* pMsgArr, bool* pIsWeakArr, int32_t arrSize); // option -bool syncNodeSnapshotEnable(SSyncNode* pSyncNode); -SyncIndex syncNodeGetSnapshotConfigIndex(SSyncNode* pSyncNode, SyncIndex snapshotLastApplyIndex); +bool syncNodeSnapshotEnable(SSyncNode* pSyncNode); +ESyncStrategy syncNodeStrategy(SSyncNode* pSyncNode); +SyncIndex syncNodeGetSnapshotConfigIndex(SSyncNode* pSyncNode, SyncIndex snapshotLastApplyIndex); // ping -------------- int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg); diff --git a/source/libs/sync/inc/syncRaftEntry.h b/source/libs/sync/inc/syncRaftEntry.h index 37f18a6388..82d5c0a6ea 100644 --- a/source/libs/sync/inc/syncRaftEntry.h +++ b/source/libs/sync/inc/syncRaftEntry.h @@ -29,19 +29,20 @@ extern "C" { typedef struct SSyncRaftEntry { uint32_t bytes; - uint32_t msgType; // SyncClientRequest msgType - uint32_t originalRpcType; // user RpcMsg msgType + uint32_t msgType; // TDMT_SYNC_CLIENT_REQUEST + uint32_t originalRpcType; // origin RpcMsg msgType uint64_t seqNum; bool isWeak; SyncTerm term; SyncIndex index; - uint32_t dataLen; // user RpcMsg.contLen - char data[]; // user RpcMsg.pCont + uint32_t dataLen; // origin RpcMsg.contLen + char data[]; // origin RpcMsg.pCont } SSyncRaftEntry; SSyncRaftEntry* syncEntryBuild(uint32_t dataLen); SSyncRaftEntry* syncEntryBuild2(SyncClientRequest* pMsg, SyncTerm term, SyncIndex index); // step 4 SSyncRaftEntry* syncEntryBuild3(SyncClientRequest* pMsg, SyncTerm term, SyncIndex index); +SSyncRaftEntry* syncEntryBuild4(SRpcMsg* pOriginalMsg, SyncTerm term, SyncIndex index); SSyncRaftEntry* syncEntryBuildNoop(SyncTerm term, SyncIndex index, int32_t vgId); void syncEntryDestory(SSyncRaftEntry* pEntry); char* syncEntrySerialize(const SSyncRaftEntry* pEntry, uint32_t* len); // step 5 diff --git a/source/libs/sync/inc/syncReplication.h b/source/libs/sync/inc/syncReplication.h index 07e12460da..dad7d9b5ec 100644 --- a/source/libs/sync/inc/syncReplication.h +++ b/source/libs/sync/inc/syncReplication.h @@ -54,6 +54,7 @@ extern "C" { int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode); int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode); int32_t syncNodeAppendEntriesPeersSnapshot2(SSyncNode* pSyncNode); + int32_t syncNodeReplicate(SSyncNode* pSyncNode); int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntries* pMsg); int32_t syncNodeAppendEntriesBatch(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntriesBatch* pMsg); diff --git a/source/libs/sync/inc/syncSnapshot.h b/source/libs/sync/inc/syncSnapshot.h index 6801e7212a..3df9c243e7 100644 --- a/source/libs/sync/inc/syncSnapshot.h +++ b/source/libs/sync/inc/syncSnapshot.h @@ -37,26 +37,28 @@ extern "C" { //--------------------------------------------------- typedef struct SSyncSnapshotSender { - bool start; - int32_t seq; - int32_t ack; - void *pReader; - void *pCurrentBlock; - int32_t blockLen; - SSnapshot snapshot; - SSyncCfg lastConfig; - int64_t sendingMS; - SSyncNode *pSyncNode; - int32_t replicaIndex; - SyncTerm term; - SyncTerm privateTerm; - bool finish; + bool start; + int32_t seq; + int32_t ack; + void *pReader; + void *pCurrentBlock; + int32_t blockLen; + SSnapshotParam snapshotParam; + SSnapshot snapshot; + SSyncCfg lastConfig; + int64_t sendingMS; + SSyncNode *pSyncNode; + int32_t replicaIndex; + SyncTerm term; + SyncTerm privateTerm; + bool finish; } SSyncSnapshotSender; SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex); void snapshotSenderDestroy(SSyncSnapshotSender *pSender); bool snapshotSenderIsStart(SSyncSnapshotSender *pSender); -int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader); +int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshotParam snapshotParam, SSnapshot snapshot, + void *pReader); int32_t snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish); int32_t snapshotSend(SSyncSnapshotSender *pSender); int32_t snapshotReSend(SSyncSnapshotSender *pSender); @@ -67,14 +69,15 @@ char *snapshotSender2SimpleStr(SSyncSnapshotSender *pSender, char *event); //--------------------------------------------------- typedef struct SSyncSnapshotReceiver { - bool start; - int32_t ack; - void *pWriter; - SyncTerm term; - SyncTerm privateTerm; - SSnapshot snapshot; - SRaftId fromId; - SSyncNode *pSyncNode; + bool start; + int32_t ack; + void *pWriter; + SyncTerm term; + SyncTerm privateTerm; + SSnapshotParam snapshotParam; + SSnapshot snapshot; + SRaftId fromId; + SSyncNode *pSyncNode; } SSyncSnapshotReceiver; diff --git a/source/libs/sync/src/syncAppendEntries.c b/source/libs/sync/src/syncAppendEntries.c index be48227d40..c923ee3d1d 100644 --- a/source/libs/sync/src/syncAppendEntries.c +++ b/source/libs/sync/src/syncAppendEntries.c @@ -628,8 +628,6 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { #endif -static int32_t syncNodeMakeLogSame2(SSyncNode* ths, SyncAppendEntriesBatch* pMsg) { return 0; } - static int32_t syncNodeMakeLogSame(SSyncNode* ths, SyncAppendEntries* pMsg) { int32_t code; @@ -675,6 +673,51 @@ static int32_t syncNodeMakeLogSame(SSyncNode* ths, SyncAppendEntries* pMsg) { return code; } +static int32_t syncNodeDoMakeLogSame(SSyncNode* ths, SyncIndex FromIndex) { + int32_t code; + + SyncIndex delBegin = FromIndex; + SyncIndex delEnd = ths->pLogStore->syncLogLastIndex(ths->pLogStore); + + // invert roll back! + for (SyncIndex index = delEnd; index >= delBegin; --index) { + if (ths->pFsm->FpRollBackCb != NULL) { + SSyncRaftEntry* pRollBackEntry; + code = ths->pLogStore->syncLogGetEntry(ths->pLogStore, index, &pRollBackEntry); + ASSERT(code == 0); + ASSERT(pRollBackEntry != NULL); + + if (syncUtilUserRollback(pRollBackEntry->msgType)) { + SRpcMsg rpcMsg; + syncEntry2OriginalRpc(pRollBackEntry, &rpcMsg); + + SFsmCbMeta cbMeta = {0}; + cbMeta.index = pRollBackEntry->index; + cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(ths, cbMeta.index); + cbMeta.isWeak = pRollBackEntry->isWeak; + cbMeta.code = 0; + cbMeta.state = ths->state; + cbMeta.seqNum = pRollBackEntry->seqNum; + ths->pFsm->FpRollBackCb(ths->pFsm, &rpcMsg, cbMeta); + rpcFreeCont(rpcMsg.pCont); + } + + syncEntryDestory(pRollBackEntry); + } + } + + // delete confict entries + code = ths->pLogStore->syncLogTruncate(ths->pLogStore, delBegin); + ASSERT(code == 0); + + char eventLog[128]; + snprintf(eventLog, sizeof(eventLog), "log truncate, from %ld to %ld", delBegin, delEnd); + syncNodeEventLog(ths, eventLog); + logStoreSimpleLog2("after syncNodeMakeLogSame", ths->pLogStore); + + return code; +} + static int32_t syncNodePreCommit(SSyncNode* ths, SSyncRaftEntry* pEntry) { SRpcMsg rpcMsg; syncEntry2OriginalRpc(pEntry, &rpcMsg); @@ -694,6 +737,31 @@ static int32_t syncNodePreCommit(SSyncNode* ths, SSyncRaftEntry* pEntry) { return 0; } +static bool syncNodeOnAppendEntriesBatchLogOK(SSyncNode* pSyncNode, SyncAppendEntriesBatch* pMsg) { + if (pMsg->prevLogIndex == SYNC_INDEX_INVALID) { + return true; + } + + SyncIndex myLastIndex = syncNodeGetLastIndex(pSyncNode); + if (pMsg->prevLogIndex > myLastIndex) { + sDebug("vgId:%d sync log not ok, preindex:%ld", pSyncNode->vgId, pMsg->prevLogIndex); + return false; + } + + SyncTerm myPreLogTerm = syncNodeGetPreTerm(pSyncNode, pMsg->prevLogIndex + 1); + if (myPreLogTerm == SYNC_TERM_INVALID) { + sDebug("vgId:%d sync log not ok2, preindex:%ld", pSyncNode->vgId, pMsg->prevLogIndex); + return false; + } + + if (pMsg->prevLogIndex <= myLastIndex && pMsg->prevLogTerm == myPreLogTerm) { + return true; + } + + sDebug("vgId:%d sync log not ok3, preindex:%ld", pSyncNode->vgId, pMsg->prevLogIndex); + return false; +} + // really pre log match // prevLogIndex == -1 static bool syncNodeOnAppendEntriesLogOK(SSyncNode* pSyncNode, SyncAppendEntries* pMsg) { @@ -767,7 +835,6 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc // 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); @@ -780,14 +847,11 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc 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); + SyncIndex matchIndex = ths->commitIndex; + bool hasAppendEntries = pMsg->dataLen > 0; + SOffsetAndContLen* metaTableArr = syncAppendEntriesBatchMetaTableArray(pMsg); + if (hasAppendEntries && pMsg->prevLogIndex == ths->commitIndex) { // make log same do { SyncIndex logLastIndex = ths->pLogStore->syncLogLastIndex(ths->pLogStore); @@ -795,15 +859,15 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc if (hasExtraEntries) { // make log same, rollback deleted entries - code = syncNodeMakeLogSame2(ths, pMsg); + code = syncNodeDoMakeLogSame(ths, pMsg->prevLogIndex + 1); ASSERT(code == 0); } } while (0); // append entry batch - for (int32_t i = 0; i < retArrSize; ++i) { - SSyncRaftEntry* pAppendEntry = syncEntryBuild(1234); + for (int32_t i = 0; i < pMsg->dataCount; ++i) { + SSyncRaftEntry* pAppendEntry = (SSyncRaftEntry*)(pMsg->data + metaTableArr[i].offset); code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry); if (code != 0) { return -1; @@ -821,7 +885,7 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc walFsync(pWal, true); // update match index - matchIndex = pMsg->prevLogIndex + retArrSize; + matchIndex = pMsg->prevLogIndex + pMsg->dataCount; } // prepare response msg @@ -839,13 +903,12 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); syncAppendEntriesReplyDestroy(pReply); - return ret; + return 0; } } while (0); // calculate logOK here, before will coredump, due to fake match - // bool logOK = syncNodeOnAppendEntriesLogOK(ths, pMsg); - bool logOK = true; + bool logOK = syncNodeOnAppendEntriesBatchLogOK(ths, pMsg); // not match // @@ -866,8 +929,9 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc 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); + snprintf(logBuf, sizeof(logBuf), + "recv sync-append-entries-batch, not match, pre-index:%ld, pre-term:%lu, datalen:%d", pMsg->prevLogIndex, + pMsg->prevLogTerm, pMsg->dataLen); syncNodeEventLog(ths, logBuf); // prepare response msg @@ -885,7 +949,7 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg); syncAppendEntriesReplyDestroy(pReply); - return ret; + return 0; } } while (0); @@ -905,28 +969,26 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc bool hasExtraEntries = myLastIndex > pMsg->prevLogIndex; // has entries in SyncAppendEntries msg - bool hasAppendEntries = pMsg->dataLen > 0; + bool hasAppendEntries = pMsg->dataLen > 0; + SOffsetAndContLen* metaTableArr = syncAppendEntriesBatchMetaTableArray(pMsg); - 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); + do { + 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); + } while (0); if (hasExtraEntries) { // make log same, rollback deleted entries - // code = syncNodeMakeLogSame(ths, pMsg); + code = syncNodeDoMakeLogSame(ths, pMsg->prevLogIndex + 1); 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); + for (int32_t i = 0; i < pMsg->dataCount; ++i) { + SSyncRaftEntry* pAppendEntry = (SSyncRaftEntry*)(pMsg->data + metaTableArr[i].offset); code = ths->pLogStore->syncLogAppendEntry(ths->pLogStore, pAppendEntry); if (code != 0) { return -1; @@ -951,7 +1013,7 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc pReply->term = ths->pRaftStore->currentTerm; pReply->privateTerm = ths->pNewNodeReceiver->privateTerm; pReply->success = true; - pReply->matchIndex = hasAppendEntries ? pMsg->prevLogIndex + retArrSize : pMsg->prevLogIndex; + pReply->matchIndex = hasAppendEntries ? pMsg->prevLogIndex + pMsg->dataCount : pMsg->prevLogIndex; // send response SRpcMsg rpcMsg; @@ -991,11 +1053,11 @@ int32_t syncNodeOnAppendEntriesSnapshot2Cb(SSyncNode* ths, SyncAppendEntriesBatc ASSERT(code == 0); } } - return ret; + return 0; } } while (0); - return ret; + return 0; } int32_t syncNodeOnAppendEntriesSnapshotCb(SSyncNode* ths, SyncAppendEntries* pMsg) { diff --git a/source/libs/sync/src/syncAppendEntriesReply.c b/source/libs/sync/src/syncAppendEntriesReply.c index 629d83eb51..f3206e9ccc 100644 --- a/source/libs/sync/src/syncAppendEntriesReply.c +++ b/source/libs/sync/src/syncAppendEntriesReply.c @@ -118,12 +118,12 @@ static void syncNodeStartSnapshot(SSyncNode* ths, SyncIndex beginIndex, SyncInde SSnapshot snapshot = { .data = NULL, .lastApplyIndex = endIndex, .lastApplyTerm = lastApplyTerm, .lastConfigIndex = SYNC_INDEX_INVALID}; - void* pReader = NULL; - SReaderParam readerParam = {.start = beginIndex, .end = endIndex}; + void* pReader = NULL; + SSnapshotParam 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); + snapshotSenderStart(pSender, readerParam, snapshot, pReader); } else { if (pReader != NULL) { @@ -165,23 +165,22 @@ int32_t syncNodeOnAppendEntriesReplySnapshot2Cb(SSyncNode* ths, SyncAppendEntrie if (ths->pLogStore->syncLogExist(ths->pLogStore, newNextIndex) && ths->pLogStore->syncLogExist(ths->pLogStore, newNextIndex - 1)) { - // nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1] + // update next-index, match-index syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), newNextIndex); - - // matchIndex' = [matchIndex EXCEPT ![i][j] = m.mmatchIndex] syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), newMatchIndex); // maybe commit if (ths->state == TAOS_SYNC_STATE_LEADER) { syncMaybeAdvanceCommitIndex(ths); } + } else { // start snapshot - SSnapshot snapshot; - ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot); - syncNodeStartSnapshot(ths, newMatchIndex + 1, snapshot.lastApplyIndex, snapshot.lastApplyTerm, pMsg); + SSnapshot oldSnapshot; + ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &oldSnapshot); + syncNodeStartSnapshot(ths, newMatchIndex + 1, oldSnapshot.lastApplyIndex, oldSnapshot.lastApplyTerm, pMsg); - syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), snapshot.lastApplyIndex + 1); + syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), oldSnapshot.lastApplyIndex + 1); syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), newMatchIndex); } @@ -301,7 +300,8 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries !snapshotSenderIsStart(pSender) && pMsg->privateTerm < pSender->privateTerm) { // has snapshot ASSERT(pReader != NULL); - snapshotSenderStart(pSender, snapshot, pReader); + SSnapshotParam readerParam = {.start = 0, .end = snapshot.lastApplyIndex}; + snapshotSenderStart(pSender, readerParam, snapshot, pReader); } else { // no snapshot diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index ddda60bc18..ad7895b718 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -815,7 +815,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { // create a new raft config file SRaftCfgMeta meta; meta.isStandBy = pSyncInfo->isStandBy; - meta.snapshotEnable = pSyncInfo->snapshotEnable; + meta.snapshotEnable = pSyncInfo->snapshotStrategy; meta.lastConfigIndex = SYNC_INDEX_INVALID; ret = raftCfgCreateFile((SSyncCfg*)&(pSyncInfo->syncCfg), meta, pSyncNode->configPath); ASSERT(ret == 0); @@ -1100,7 +1100,9 @@ void syncNodeClose(SSyncNode* pSyncNode) { } // option -bool syncNodeSnapshotEnable(SSyncNode* pSyncNode) { return pSyncNode->pRaftCfg->snapshotEnable; } +// bool syncNodeSnapshotEnable(SSyncNode* pSyncNode) { return pSyncNode->pRaftCfg->snapshotEnable; } + +ESyncStrategy syncNodeStrategy(SSyncNode* pSyncNode) { return pSyncNode->pRaftCfg->snapshotEnable; } // ping -------------- int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg) { diff --git a/source/libs/sync/src/syncMessage.c b/source/libs/sync/src/syncMessage.c index ad352df59f..e53b9d5e36 100644 --- a/source/libs/sync/src/syncMessage.c +++ b/source/libs/sync/src/syncMessage.c @@ -15,6 +15,7 @@ #include "syncMessage.h" #include "syncRaftCfg.h" +#include "syncRaftEntry.h" #include "syncUtil.h" #include "tcoding.h" @@ -996,7 +997,135 @@ SyncClientRequestBatch* syncClientRequestBatchBuild(SRpcMsg* rpcMsgArr, SRaftMet return pMsg; } -void syncClientRequestBatch2RpcMsg(const SyncClientRequestBatch* pSyncMsg, SRpcMsg* pRpcMsg) {} +void syncClientRequestBatch2RpcMsg(const SyncClientRequestBatch* pSyncMsg, SRpcMsg* pRpcMsg) { + memset(pRpcMsg, 0, sizeof(*pRpcMsg)); + pRpcMsg->msgType = pSyncMsg->msgType; + pRpcMsg->contLen = pSyncMsg->bytes; + pRpcMsg->pCont = rpcMallocCont(pRpcMsg->contLen); + memcpy(pRpcMsg->pCont, pSyncMsg, pRpcMsg->contLen); +} + +void syncClientRequestBatchDestroy(SyncClientRequestBatch* pMsg) { + if (pMsg != NULL) { + taosMemoryFree(pMsg); + } +} + +void syncClientRequestBatchDestroyDeep(SyncClientRequestBatch* pMsg) { + if (pMsg != NULL) { + int32_t arrSize = pMsg->dataCount; + int32_t raftMetaArrayLen = sizeof(SRaftMeta) * arrSize; + SRpcMsg* msgArr = (SRpcMsg*)((char*)(pMsg->data) + raftMetaArrayLen); + for (int i = 0; i < arrSize; ++i) { + if (msgArr[i].pCont != NULL) { + rpcFreeCont(msgArr[i].pCont); + } + } + + taosMemoryFree(pMsg); + } +} + +SRaftMeta* syncClientRequestBatchMetaArr(const SyncClientRequestBatch* pSyncMsg) { + SRaftMeta* raftMetaArr = (SRaftMeta*)(pSyncMsg->data); + return raftMetaArr; +} + +SRpcMsg* syncClientRequestBatchRpcMsgArr(const SyncClientRequestBatch* pSyncMsg) { + int32_t arrSize = pSyncMsg->dataCount; + int32_t raftMetaArrayLen = sizeof(SRaftMeta) * arrSize; + SRpcMsg* msgArr = (SRpcMsg*)((char*)(pSyncMsg->data) + raftMetaArrayLen); + return msgArr; +} + +SyncClientRequestBatch* syncClientRequestBatchFromRpcMsg(const SRpcMsg* pRpcMsg) { + SyncClientRequestBatch* pSyncMsg = taosMemoryMalloc(pRpcMsg->contLen); + ASSERT(pSyncMsg != NULL); + memcpy(pSyncMsg, pRpcMsg->pCont, pRpcMsg->contLen); + ASSERT(pRpcMsg->contLen == pSyncMsg->bytes); + + return pSyncMsg; +} + +cJSON* syncClientRequestBatch2Json(const SyncClientRequestBatch* 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_AddNumberToObject(pRoot, "dataLen", pMsg->dataLen); + cJSON_AddNumberToObject(pRoot, "dataCount", pMsg->dataCount); + + SRaftMeta* metaArr = syncClientRequestBatchMetaArr(pMsg); + SRpcMsg* msgArr = syncClientRequestBatchRpcMsgArr(pMsg); + + cJSON* pMetaArr = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "metaArr", pMetaArr); + for (int i = 0; i < pMsg->dataCount; ++i) { + cJSON* pMeta = cJSON_CreateObject(); + cJSON_AddNumberToObject(pMeta, "seqNum", metaArr[i].seqNum); + cJSON_AddNumberToObject(pMeta, "isWeak", metaArr[i].isWeak); + cJSON_AddItemToArray(pMetaArr, pMeta); + } + + cJSON* pMsgArr = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "msgArr", pMsgArr); + for (int i = 0; i < pMsg->dataCount; ++i) { + cJSON* pRpcMsgJson = syncRpcMsg2Json(&msgArr[i]); + 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, "SyncClientRequestBatch", pRoot); + return pJson; +} + +char* syncClientRequestBatch2Str(const SyncClientRequestBatch* pMsg) { + cJSON* pJson = syncClientRequestBatch2Json(pMsg); + char* serialized = cJSON_Print(pJson); + cJSON_Delete(pJson); + return serialized; +} + +// for debug ---------------------- +void syncClientRequestBatchPrint(const SyncClientRequestBatch* pMsg) { + char* serialized = syncClientRequestBatch2Str(pMsg); + printf("syncClientRequestBatchPrint | len:%lu | %s \n", strlen(serialized), serialized); + fflush(NULL); + taosMemoryFree(serialized); +} + +void syncClientRequestBatchPrint2(char* s, const SyncClientRequestBatch* pMsg) { + char* serialized = syncClientRequestBatch2Str(pMsg); + printf("syncClientRequestBatchPrint2 | len:%lu | %s | %s \n", strlen(serialized), s, serialized); + fflush(NULL); + taosMemoryFree(serialized); +} + +void syncClientRequestBatchLog(const SyncClientRequestBatch* pMsg) { + char* serialized = syncClientRequestBatch2Str(pMsg); + sTrace("syncClientRequestBatchLog | len:%lu | %s", strlen(serialized), serialized); + taosMemoryFree(serialized); +} + +void syncClientRequestBatchLog2(char* s, const SyncClientRequestBatch* pMsg) { + if (gRaftDetailLog) { + char* serialized = syncClientRequestBatch2Str(pMsg); + sTraceLong("syncClientRequestBatchLog2 | len:%lu | %s | %s", strlen(serialized), s, serialized); + taosMemoryFree(serialized); + } +} // ---- message process SyncRequestVote---- SyncRequestVote* syncRequestVoteBuild(int32_t vgId) { @@ -1472,21 +1601,20 @@ void syncAppendEntriesLog2(char* s, const SyncAppendEntries* pMsg) { // block1: SOffsetAndContLen // block2: SOffsetAndContLen Array -// block3: SRpcMsg Array -// block4: SRpcMsg pCont Array +// block3: entry Array -SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SRpcMsg* rpcMsgArr, int32_t arrSize, int32_t vgId) { - ASSERT(rpcMsgArr != NULL); +SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SSyncRaftEntry** entryPArr, int32_t arrSize, int32_t vgId) { + ASSERT(entryPArr != NULL); ASSERT(arrSize > 0); int32_t dataLen = 0; int32_t metaArrayLen = sizeof(SOffsetAndContLen) * arrSize; // - int32_t rpcArrayLen = sizeof(SRpcMsg) * arrSize; // SRpcMsg - int32_t contArrayLen = 0; + int32_t entryArrayLen = 0; for (int i = 0; i < arrSize; ++i) { // SRpcMsg pCont - contArrayLen += rpcMsgArr[i].contLen; + SSyncRaftEntry* pEntry = entryPArr[i]; + entryArrayLen += pEntry->bytes; } - dataLen += (metaArrayLen + rpcArrayLen + contArrayLen); + dataLen += (metaArrayLen + entryArrayLen); uint32_t bytes = sizeof(SyncAppendEntriesBatch) + dataLen; SyncAppendEntriesBatch* pMsg = taosMemoryMalloc(bytes); @@ -1498,30 +1626,30 @@ SyncAppendEntriesBatch* syncAppendEntriesBatchBuild(SRpcMsg* rpcMsgArr, int32_t 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 + // init meta if (i == 0) { - metaArr[i].offset = metaArrayLen + rpcArrayLen; - metaArr[i].contLen = rpcMsgArr[i].contLen; + metaArr[i].offset = metaArrayLen; + metaArr[i].contLen = entryPArr[i]->bytes; } else { metaArr[i].offset = metaArr[i - 1].offset + metaArr[i - 1].contLen; - metaArr[i].contLen = rpcMsgArr[i].contLen; + metaArr[i].contLen = entryPArr[i]->bytes; } - // 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); + // init entry array + ASSERT(metaArr[i].contLen == entryPArr[i]->bytes); + memcpy(pData + metaArr[i].offset, entryPArr[i], metaArr[i].contLen); } return pMsg; } +SOffsetAndContLen* syncAppendEntriesBatchMetaTableArray(SyncAppendEntriesBatch* pMsg) { + return (SOffsetAndContLen*)(pMsg->data); +} + void syncAppendEntriesBatchDestroy(SyncAppendEntriesBatch* pMsg) { if (pMsg != NULL) { taosMemoryFree(pMsg); @@ -1634,16 +1762,12 @@ cJSON* syncAppendEntriesBatch2Json(const SyncAppendEntriesBatch* pMsg) { cJSON_AddNumberToObject(pRoot, "dataLen", pMsg->dataLen); int32_t metaArrayLen = sizeof(SOffsetAndContLen) * pMsg->dataCount; // - int32_t rpcArrayLen = sizeof(SRpcMsg) * pMsg->dataCount; // SRpcMsg - int32_t contArrayLen = pMsg->dataLen - metaArrayLen - rpcArrayLen; + int32_t entryArrayLen = pMsg->dataLen - metaArrayLen; cJSON_AddNumberToObject(pRoot, "metaArrayLen", metaArrayLen); - cJSON_AddNumberToObject(pRoot, "rpcArrayLen", rpcArrayLen); - cJSON_AddNumberToObject(pRoot, "contArrayLen", contArrayLen); + cJSON_AddNumberToObject(pRoot, "entryArrayLen", entryArrayLen); 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); @@ -1654,14 +1778,12 @@ cJSON* syncAppendEntriesBatch2Json(const SyncAppendEntriesBatch* pMsg) { cJSON_AddItemToArray(pMetaArr, pMeta); } - cJSON* pMsgArr = cJSON_CreateArray(); - cJSON_AddItemToObject(pRoot, "msgArr", pMsgArr); + cJSON* pEntryArr = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "entryArr", pEntryArr); 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); + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)(pMsg->data + metaArr[i].offset); + cJSON* pEntryJson = syncEntry2Json(pEntry); + cJSON_AddItemToArray(pEntryArr, pEntryJson); } char* s; @@ -1685,33 +1807,6 @@ char* syncAppendEntriesBatch2Str(const SyncAppendEntriesBatch* pMsg) { 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; // - 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); @@ -2159,6 +2254,9 @@ cJSON* syncSnapshotSend2Json(const SyncSnapshotSend* pMsg) { snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->privateTerm); cJSON_AddStringToObject(pRoot, "privateTerm", u64buf); + snprintf(u64buf, sizeof(u64buf), "%ld", pMsg->beginIndex); + cJSON_AddStringToObject(pRoot, "beginIndex", u64buf); + snprintf(u64buf, sizeof(u64buf), "%ld", pMsg->lastIndex); cJSON_AddStringToObject(pRoot, "lastIndex", u64buf); diff --git a/source/libs/sync/src/syncRaftEntry.c b/source/libs/sync/src/syncRaftEntry.c index 225360630c..0ee4684ea8 100644 --- a/source/libs/sync/src/syncRaftEntry.c +++ b/source/libs/sync/src/syncRaftEntry.c @@ -50,6 +50,22 @@ SSyncRaftEntry* syncEntryBuild3(SyncClientRequest* pMsg, SyncTerm term, SyncInde return pEntry; } +SSyncRaftEntry* syncEntryBuild4(SRpcMsg* pOriginalMsg, SyncTerm term, SyncIndex index) { + SSyncRaftEntry* pEntry = syncEntryBuild(pOriginalMsg->contLen); + ASSERT(pEntry != NULL); + + pEntry->msgType = TDMT_SYNC_CLIENT_REQUEST; + pEntry->originalRpcType = pOriginalMsg->msgType; + pEntry->seqNum = 0; + pEntry->isWeak = 0; + pEntry->term = term; + pEntry->index = index; + pEntry->dataLen = pOriginalMsg->contLen; + memcpy(pEntry->data, pOriginalMsg->pCont, pOriginalMsg->contLen); + + return pEntry; +} + SSyncRaftEntry* syncEntryBuildNoop(SyncTerm term, SyncIndex index, int32_t vgId) { // init rpcMsg SMsgHead head; diff --git a/source/libs/sync/src/syncRaftLog.c b/source/libs/sync/src/syncRaftLog.c index a026892629..83495e7486 100644 --- a/source/libs/sync/src/syncRaftLog.c +++ b/source/libs/sync/src/syncRaftLog.c @@ -32,6 +32,7 @@ static SyncTerm raftLogLastTerm(struct SSyncLogStore* pLogStore); static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry); static int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncRaftEntry** ppEntry); static int32_t raftLogTruncate(struct SSyncLogStore* pLogStore, SyncIndex fromIndex); +static bool raftLogExist(struct SSyncLogStore* pLogStore, SyncIndex index); // private function static int32_t raftLogGetLastEntry(SSyncLogStore* pLogStore, SSyncRaftEntry** ppLastEntry); @@ -83,6 +84,7 @@ SSyncLogStore* logStoreCreate(SSyncNode* pSyncNode) { pLogStore->syncLogGetEntry = raftLogGetEntry; pLogStore->syncLogTruncate = raftLogTruncate; pLogStore->syncLogWriteIndex = raftLogWriteIndex; + pLogStore->syncLogExist = raftLogExist; return pLogStore; } @@ -168,6 +170,13 @@ static SyncIndex raftLogWriteIndex(struct SSyncLogStore* pLogStore) { return lastVer + 1; } +static bool raftLogExist(struct SSyncLogStore* pLogStore, SyncIndex index) { + SSyncLogStoreData* pData = pLogStore->data; + SWal* pWal = pData->pWal; + bool b = walLogExist(pWal, index); + return b; +} + // if success, return last term // if not log, return 0 // if error, return SYNC_TERM_INVALID diff --git a/source/libs/sync/src/syncReplication.c b/source/libs/sync/src/syncReplication.c index 4908822a3a..bcca44130a 100644 --- a/source/libs/sync/src/syncReplication.c +++ b/source/libs/sync/src/syncReplication.c @@ -145,26 +145,34 @@ int32_t syncNodeAppendEntriesPeersSnapshot2(SSyncNode* pSyncNode) { return -1; } - SRpcMsg rpcMsgArr[SYNC_MAX_BATCH_SIZE]; - memset(rpcMsgArr, 0, sizeof(rpcMsgArr)); + SSyncRaftEntry* entryPArr[SYNC_MAX_BATCH_SIZE]; + memset(entryPArr, 0, sizeof(entryPArr)); - int32_t getCount = 0; + int32_t getCount = 0; + SyncIndex getEntryIndex = nextIndex; for (int32_t i = 0; i < pSyncNode->batchSize; ++i) { SSyncRaftEntry* pEntry; - int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, nextIndex, &pEntry); + int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, getEntryIndex, &pEntry); if (code == 0) { ASSERT(pEntry != NULL); - // get rpc msg [i] from entry - syncEntryDestory(pEntry); + entryPArr[i] = pEntry; getCount++; } else { break; } } - SyncAppendEntriesBatch* pMsg = syncAppendEntriesBatchBuild(rpcMsgArr, getCount, pSyncNode->vgId); + SyncAppendEntriesBatch* pMsg = syncAppendEntriesBatchBuild(entryPArr, getCount, pSyncNode->vgId); ASSERT(pMsg != NULL); + for (int32_t i = 0; i < pSyncNode->batchSize; ++i) { + SSyncRaftEntry* pEntry = entryPArr[i]; + if (pEntry != NULL) { + syncEntryDestory(pEntry); + entryPArr[i] = NULL; + } + } + // prepare msg pMsg->srcId = pSyncNode->myRaftId; pMsg->destId = *pDestId; diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index 4466cccbbc..cefe676f90 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -80,13 +80,15 @@ void snapshotSenderDestroy(SSyncSnapshotSender *pSender) { bool snapshotSenderIsStart(SSyncSnapshotSender *pSender) { return pSender->start; } // begin send snapshot by snapshot, pReader -int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader) { +int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshotParam snapshotParam, SSnapshot snapshot, + void *pReader) { ASSERT(!snapshotSenderIsStart(pSender)); - // init snapshot and reader + // init snapshot, parm, reader ASSERT(pSender->pReader == NULL); pSender->pReader = pReader; pSender->snapshot = snapshot; + pSender->snapshotParam = snapshotParam; // init current block if (pSender->pCurrentBlock != NULL) { @@ -162,6 +164,7 @@ int32_t snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, vo pMsg->srcId = pSender->pSyncNode->myRaftId; pMsg->destId = (pSender->pSyncNode->replicasId)[pSender->replicaIndex]; pMsg->term = pSender->pSyncNode->pRaftStore->currentTerm; + pMsg->beginIndex = pSender->snapshotParam.start; pMsg->lastIndex = pSender->snapshot.lastApplyIndex; pMsg->lastTerm = pSender->snapshot.lastApplyTerm; pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex; @@ -439,10 +442,13 @@ static void snapshotReceiverDoStart(SSyncSnapshotReceiver *pReceiver, SyncTerm p pReceiver->snapshot.lastApplyIndex = pBeginMsg->lastIndex; pReceiver->snapshot.lastApplyTerm = pBeginMsg->lastTerm; pReceiver->snapshot.lastConfigIndex = pBeginMsg->lastConfigIndex; + pReceiver->snapshotParam.start = pBeginMsg->beginIndex; + pReceiver->snapshotParam.end = pBeginMsg->lastIndex; // write data ASSERT(pReceiver->pWriter == NULL); - int32_t ret = pReceiver->pSyncNode->pFsm->FpSnapshotStartWrite(pReceiver->pSyncNode->pFsm, &(pReceiver->pWriter)); + int32_t ret = pReceiver->pSyncNode->pFsm->FpSnapshotStartWrite(pReceiver->pSyncNode->pFsm, + &(pReceiver->snapshotParam), &(pReceiver->pWriter)); ASSERT(ret == 0); // event log diff --git a/source/libs/sync/test/CMakeLists.txt b/source/libs/sync/test/CMakeLists.txt index c549b78399..37d9707cfd 100644 --- a/source/libs/sync/test/CMakeLists.txt +++ b/source/libs/sync/test/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable(syncAppendEntriesTest "") add_executable(syncAppendEntriesBatchTest "") add_executable(syncAppendEntriesReplyTest "") add_executable(syncClientRequestTest "") +add_executable(syncClientRequestBatchTest "") add_executable(syncTimeoutTest "") add_executable(syncPingTest "") add_executable(syncPingReplyTest "") @@ -159,6 +160,10 @@ target_sources(syncClientRequestTest PRIVATE "syncClientRequestTest.cpp" ) +target_sources(syncClientRequestBatchTest + PRIVATE + "syncClientRequestBatchTest.cpp" +) target_sources(syncTimeoutTest PRIVATE "syncTimeoutTest.cpp" @@ -407,6 +412,11 @@ target_include_directories(syncClientRequestTest "${TD_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) +target_include_directories(syncClientRequestBatchTest + PUBLIC + "${TD_SOURCE_DIR}/include/libs/sync" + "${CMAKE_CURRENT_SOURCE_DIR}/../inc" +) target_include_directories(syncTimeoutTest PUBLIC "${TD_SOURCE_DIR}/include/libs/sync" @@ -658,6 +668,10 @@ target_link_libraries(syncClientRequestTest sync gtest_main ) +target_link_libraries(syncClientRequestBatchTest + sync + gtest_main +) target_link_libraries(syncTimeoutTest sync gtest_main diff --git a/source/libs/sync/test/syncAppendEntriesBatchTest.cpp b/source/libs/sync/test/syncAppendEntriesBatchTest.cpp index 8784ddd637..515d580b35 100644 --- a/source/libs/sync/test/syncAppendEntriesBatchTest.cpp +++ b/source/libs/sync/test/syncAppendEntriesBatchTest.cpp @@ -3,6 +3,7 @@ #include "syncIO.h" #include "syncInt.h" #include "syncMessage.h" +#include "syncRaftEntry.h" #include "syncUtil.h" #include "trpc.h" @@ -15,30 +16,29 @@ void logTest() { 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; +SSyncRaftEntry *createEntry(int i) { + SSyncRaftEntry *pEntry = syncEntryBuild(20); + assert(pEntry != NULL); + pEntry->msgType = 1; + pEntry->originalRpcType = 2; + pEntry->seqNum = 3; + pEntry->isWeak = true; + pEntry->term = 100; + pEntry->index = 200; + snprintf(pEntry->data, pEntry->dataLen, "value_%d", i); + return pEntry; } SyncAppendEntriesBatch *createMsg() { - SRpcMsg rpcMsgArr[5]; - memset(rpcMsgArr, 0, sizeof(rpcMsgArr)); + SSyncRaftEntry *entryPArr[5]; + memset(entryPArr, 0, sizeof(entryPArr)); for (int32_t i = 0; i < 5; ++i) { - SRpcMsg *pRpcMsg = createRpcMsg(i, 20); - rpcMsgArr[i] = *pRpcMsg; - taosMemoryFree(pRpcMsg); + SSyncRaftEntry *pEntry = createEntry(i); + entryPArr[i] = pEntry; } - SyncAppendEntriesBatch *pMsg = syncAppendEntriesBatchBuild(rpcMsgArr, 5, 1234); + SyncAppendEntriesBatch *pMsg = syncAppendEntriesBatchBuild(entryPArr, 5, 1234); pMsg->srcId.addr = syncUtilAddr2U64("127.0.0.1", 1234); pMsg->srcId.vgId = 100; pMsg->destId.addr = syncUtilAddr2U64("127.0.0.1", 5678); @@ -52,17 +52,17 @@ SyncAppendEntriesBatch *createMsg() { void test1() { SyncAppendEntriesBatch *pMsg = createMsg(); - syncAppendEntriesBatchLog2((char *)"test1:", pMsg); + syncAppendEntriesBatchLog2((char *)"==test1==", pMsg); - SRpcMsg rpcMsgArr[5]; - int32_t retArrSize; - syncAppendEntriesBatch2RpcMsgArray(pMsg, rpcMsgArr, 5, &retArrSize); +/* + SOffsetAndContLen *metaArr = syncAppendEntriesBatchMetaTableArray(pMsg); + int32_t retArrSize = pMsg->dataCount; 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); + SSyncRaftEntry *pEntry = (SSyncRaftEntry*)(pMsg->data + metaArr[i].offset); + ASSERT(pEntry->bytes == metaArr[i].contLen); + syncEntryPrint(pEntry); } +*/ syncAppendEntriesBatchDestroy(pMsg); } diff --git a/source/libs/sync/test/syncClientRequestBatchTest.cpp b/source/libs/sync/test/syncClientRequestBatchTest.cpp new file mode 100644 index 0000000000..ae74baeda4 --- /dev/null +++ b/source/libs/sync/test/syncClientRequestBatchTest.cpp @@ -0,0 +1,125 @@ +#include +#include +#include "syncIO.h" +#include "syncInt.h" +#include "syncMessage.h" +#include "syncUtil.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) { + SyncPing *pSyncMsg = syncPingBuild(20); + snprintf(pSyncMsg->data, pSyncMsg->dataLen, "value_%d", i); + + SRpcMsg *pRpcMsg = (SRpcMsg *)taosMemoryMalloc(sizeof(SRpcMsg)); + memset(pRpcMsg, 0, sizeof(SRpcMsg)); + pRpcMsg->code = 10 * i; + syncPing2RpcMsg(pSyncMsg, pRpcMsg); + + syncPingDestroy(pSyncMsg); + return pRpcMsg; +} + +SyncClientRequestBatch *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); + } + + SRaftMeta raftArr[5]; + memset(raftArr, 0, sizeof(raftArr)); + for (int32_t i = 0; i < 5; ++i) { + raftArr[i].seqNum = i * 10; + raftArr[i].isWeak = i % 2; + } + + SyncClientRequestBatch *pMsg = syncClientRequestBatchBuild(rpcMsgArr, raftArr, 5, 1234); + return pMsg; +} + +void test1() { + SyncClientRequestBatch *pMsg = createMsg(); + syncClientRequestBatchLog2((char *)"==test1==", pMsg); + syncClientRequestBatchDestroyDeep(pMsg); +} + +/* +void test2() { + SyncClientRequest *pMsg = createMsg(); + uint32_t len = pMsg->bytes; + char * serialized = (char *)taosMemoryMalloc(len); + syncClientRequestSerialize(pMsg, serialized, len); + SyncClientRequest *pMsg2 = syncClientRequestBuild(pMsg->dataLen); + syncClientRequestDeserialize(serialized, len, pMsg2); + syncClientRequestLog2((char *)"test2: syncClientRequestSerialize -> syncClientRequestDeserialize ", pMsg2); + + taosMemoryFree(serialized); + syncClientRequestDestroy(pMsg); + syncClientRequestDestroy(pMsg2); +} + +void test3() { + SyncClientRequest *pMsg = createMsg(); + uint32_t len; + char * serialized = syncClientRequestSerialize2(pMsg, &len); + SyncClientRequest *pMsg2 = syncClientRequestDeserialize2(serialized, len); + syncClientRequestLog2((char *)"test3: syncClientRequestSerialize3 -> syncClientRequestDeserialize2 ", pMsg2); + + taosMemoryFree(serialized); + syncClientRequestDestroy(pMsg); + syncClientRequestDestroy(pMsg2); +} + +void test4() { + SyncClientRequest *pMsg = createMsg(); + SRpcMsg rpcMsg; + syncClientRequest2RpcMsg(pMsg, &rpcMsg); + SyncClientRequest *pMsg2 = (SyncClientRequest *)taosMemoryMalloc(rpcMsg.contLen); + syncClientRequestFromRpcMsg(&rpcMsg, pMsg2); + syncClientRequestLog2((char *)"test4: syncClientRequest2RpcMsg -> syncClientRequestFromRpcMsg ", pMsg2); + + rpcFreeCont(rpcMsg.pCont); + syncClientRequestDestroy(pMsg); + syncClientRequestDestroy(pMsg2); +} + +void test5() { + SyncClientRequest *pMsg = createMsg(); + SRpcMsg rpcMsg; + syncClientRequest2RpcMsg(pMsg, &rpcMsg); + SyncClientRequest *pMsg2 = syncClientRequestFromRpcMsg2(&rpcMsg); + syncClientRequestLog2((char *)"test5: syncClientRequest2RpcMsg -> syncClientRequestFromRpcMsg2 ", pMsg2); + + rpcFreeCont(rpcMsg.pCont); + syncClientRequestDestroy(pMsg); + syncClientRequestDestroy(pMsg2); +} +*/ + +int main() { + gRaftDetailLog = true; + tsAsyncLog = 0; + sDebugFlag = DEBUG_DEBUG + DEBUG_TRACE + DEBUG_SCREEN + DEBUG_FILE; + logTest(); + + test1(); + + /* +test2(); +test3(); +test4(); +test5(); +*/ + + return 0; +} diff --git a/source/libs/sync/test/syncConfigChangeSnapshotTest.cpp b/source/libs/sync/test/syncConfigChangeSnapshotTest.cpp index 2908dd5907..968baff952 100644 --- a/source/libs/sync/test/syncConfigChangeSnapshotTest.cpp +++ b/source/libs/sync/test/syncConfigChangeSnapshotTest.cpp @@ -77,7 +77,7 @@ int32_t GetSnapshotCb(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) { return 0; } -int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, void** ppReader) { +int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void* pParam, void** ppReader) { *ppReader = (void*)0xABCD; char logBuf[256] = {0}; snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader); @@ -114,7 +114,7 @@ int32_t SnapshotDoRead(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32 return 0; } -int32_t SnapshotStartWrite(struct SSyncFSM* pFsm, void** ppWriter) { +int32_t SnapshotStartWrite(struct SSyncFSM* pFsm, void *pParam, void** ppWriter) { *ppWriter = (void*)0xCDEF; char logBuf[256] = {0}; snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartWrite== pFsm:%p, *ppWriter:%p", pFsm, *ppWriter); @@ -198,7 +198,7 @@ int64_t createSyncNode(int32_t replicaNum, int32_t myIndex, int32_t vgId, SWal* snprintf(syncInfo.path, sizeof(syncInfo.path), "%s_sync_replica%d_index%d", path, replicaNum, myIndex); syncInfo.pWal = pWal; syncInfo.isStandBy = isStandBy; - syncInfo.snapshotEnable = true; + syncInfo.snapshotStrategy = SYNC_STRATEGY_STANDARD_SNAPSHOT; SSyncCfg* pCfg = &syncInfo.syncCfg; diff --git a/source/libs/sync/test/syncSnapshotReceiverTest.cpp b/source/libs/sync/test/syncSnapshotReceiverTest.cpp index 208a96daa4..b4bf08dd40 100644 --- a/source/libs/sync/test/syncSnapshotReceiverTest.cpp +++ b/source/libs/sync/test/syncSnapshotReceiverTest.cpp @@ -29,7 +29,7 @@ int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void** ppReader) { 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 SnapshotStartWrite(struct SSyncFSM* pFsm, void** ppWriter) { return 0; } +int32_t SnapshotStartWrite(struct SSyncFSM* pFsm, void *pParam, void** ppWriter) { return 0; } int32_t SnapshotStopWrite(struct SSyncFSM* pFsm, void* pWriter, bool isApply) { return 0; } int32_t SnapshotDoWrite(struct SSyncFSM* pFsm, void* pWriter, void* pBuf, int32_t len) { return 0; } diff --git a/source/libs/sync/test/syncSnapshotSenderTest.cpp b/source/libs/sync/test/syncSnapshotSenderTest.cpp index dc38cd3df5..8d1f83b3b1 100644 --- a/source/libs/sync/test/syncSnapshotSenderTest.cpp +++ b/source/libs/sync/test/syncSnapshotSenderTest.cpp @@ -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 SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, 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 SnapshotDoRead(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32_t* len) { return 0; } diff --git a/source/libs/sync/test/syncTestTool.cpp b/source/libs/sync/test/syncTestTool.cpp index 4e84ff0f7e..c6d3a3e4af 100644 --- a/source/libs/sync/test/syncTestTool.cpp +++ b/source/libs/sync/test/syncTestTool.cpp @@ -74,7 +74,7 @@ int32_t GetSnapshotCb(struct SSyncFSM* pFsm, SSnapshot* pSnapshot) { return 0; } -int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void *pParam, void** ppReader) { +int32_t SnapshotStartRead(struct SSyncFSM* pFsm, void* pParam, void** ppReader) { *ppReader = (void*)0xABCD; char logBuf[256] = {0}; snprintf(logBuf, sizeof(logBuf), "==callback== ==SnapshotStartRead== pFsm:%p, *ppReader:%p", pFsm, *ppReader); @@ -111,7 +111,7 @@ int32_t SnapshotDoRead(struct SSyncFSM* pFsm, void* pReader, void** ppBuf, int32 return 0; } -int32_t SnapshotStartWrite(struct SSyncFSM* pFsm, void** ppWriter) { +int32_t SnapshotStartWrite(struct SSyncFSM* pFsm, void *pParam, void** ppWriter) { *ppWriter = (void*)0xCDEF; char logBuf[256] = {0}; @@ -203,7 +203,7 @@ SWal* createWal(char* path, int32_t vgId) { } int64_t createSyncNode(int32_t replicaNum, int32_t myIndex, int32_t vgId, SWal* pWal, char* path, bool isStandBy, - bool enableSnapshot) { + ESyncStrategy enableSnapshot) { SSyncInfo syncInfo; syncInfo.vgId = vgId; syncInfo.msgcb = &gSyncIO->msgcb; @@ -213,7 +213,7 @@ int64_t createSyncNode(int32_t replicaNum, int32_t myIndex, int32_t vgId, SWal* snprintf(syncInfo.path, sizeof(syncInfo.path), "%s_sync_replica%d_index%d", path, replicaNum, myIndex); syncInfo.pWal = pWal; syncInfo.isStandBy = isStandBy; - syncInfo.snapshotEnable = enableSnapshot; + syncInfo.snapshotStrategy = enableSnapshot; SSyncCfg* pCfg = &syncInfo.syncCfg; @@ -316,7 +316,7 @@ int main(int argc, char** argv) { int32_t replicaNum = atoi(argv[1]); int32_t myIndex = atoi(argv[2]); - bool enableSnapshot = atoi(argv[3]); + ESyncStrategy enableSnapshot = (ESyncStrategy)atoi(argv[3]); int32_t lastApplyIndex = atoi(argv[4]); int32_t lastApplyTerm = atoi(argv[5]); int32_t writeRecordNum = atoi(argv[6]); diff --git a/source/libs/tfs/src/tfs.c b/source/libs/tfs/src/tfs.c index 2d3d41de64..62aec219df 100644 --- a/source/libs/tfs/src/tfs.c +++ b/source/libs/tfs/src/tfs.c @@ -291,7 +291,7 @@ int32_t tfsRmdir(STfs *pTfs, const char *rname) { for (int32_t id = 0; id < pTier->ndisk; id++) { STfsDisk *pDisk = pTier->disks[id]; snprintf(aname, TMPNAME_LEN, "%s%s%s", pDisk->path, TD_DIRSEP, rname); - uInfo("====> tfs remove dir : path:%s aname:%s rname:[%s]", pDisk->path, aname, rname); + uInfo("tfs remove dir : path:%s aname:%s rname:[%s]", pDisk->path, aname, rname); taosRemoveDir(aname); } } diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h index b06d541b75..5ce073081d 100644 --- a/source/libs/transport/inc/transComm.h +++ b/source/libs/transport/inc/transComm.h @@ -96,8 +96,8 @@ typedef void* queue[2]; #define QUEUE_DATA(e, type, field) ((type*)((void*)((char*)(e)-offsetof(type, field)))) #define TRANS_RETRY_COUNT_LIMIT 100 // retry count limit -#define TRANS_RETRY_INTERVAL 15 // ms retry interval -#define TRANS_CONN_TIMEOUT 3 // connect timeout +#define TRANS_RETRY_INTERVAL 15 // ms retry interval +#define TRANS_CONN_TIMEOUT 3 // connect timeout typedef SRpcMsg STransMsg; typedef SRpcCtx STransCtx; @@ -180,18 +180,18 @@ typedef enum { Normal, Quit, Release, Register, Update } STransMsgType; typedef enum { ConnNormal, ConnAcquire, ConnRelease, ConnBroken, ConnInPool } ConnStatus; #define container_of(ptr, type, member) ((type*)((char*)(ptr)-offsetof(type, member))) -#define RPC_RESERVE_SIZE (sizeof(STranConnCtx)) +#define RPC_RESERVE_SIZE (sizeof(STranConnCtx)) #define rpcIsReq(type) (type & 1U) #define TRANS_RESERVE_SIZE (sizeof(STranConnCtx)) -#define TRANS_MSG_OVERHEAD (sizeof(STransMsgHead)) -#define transHeadFromCont(cont) ((STransMsgHead*)((char*)cont - sizeof(STransMsgHead))) -#define transContFromHead(msg) (msg + sizeof(STransMsgHead)) +#define TRANS_MSG_OVERHEAD (sizeof(STransMsgHead)) +#define transHeadFromCont(cont) ((STransMsgHead*)((char*)cont - sizeof(STransMsgHead))) +#define transContFromHead(msg) (msg + sizeof(STransMsgHead)) #define transMsgLenFromCont(contLen) (contLen + sizeof(STransMsgHead)) -#define transContLenFromMsg(msgLen) (msgLen - sizeof(STransMsgHead)); -#define transIsReq(type) (type & 1U) +#define transContLenFromMsg(msgLen) (msgLen - sizeof(STransMsgHead)); +#define transIsReq(type) (type & 1U) #define transLabel(trans) ((STrans*)trans)->label @@ -253,7 +253,7 @@ int transAsyncSend(SAsyncPool* pool, queue* mq); do { \ if (id > 0) { \ tTrace("handle step1"); \ - SExHandle* exh2 = transAcquireExHandle(id); \ + SExHandle* exh2 = transAcquireExHandle(transGetRefMgt(), id); \ if (exh2 == NULL || id != exh2->refId) { \ tTrace("handle %p except, may already freed, ignore msg, ref1: %" PRIu64 ", ref2 : %" PRIu64 "", exh1, \ exh2 ? exh2->refId : 0, id); \ @@ -261,7 +261,7 @@ int transAsyncSend(SAsyncPool* pool, queue* mq); } \ } else if (id == 0) { \ tTrace("handle step2"); \ - SExHandle* exh2 = transAcquireExHandle(id); \ + SExHandle* exh2 = transAcquireExHandle(transGetRefMgt(), id); \ if (exh2 == NULL || id == exh2->refId) { \ tTrace("handle %p except, may already freed, ignore msg, ref1: %" PRIu64 ", ref2 : %" PRIu64 "", exh1, id, \ exh2 ? exh2->refId : 0); \ @@ -391,13 +391,16 @@ void transThreadOnce(); void transInit(); void transCleanup(); -int32_t transOpenExHandleMgt(int size); -void transCloseExHandleMgt(); -int64_t transAddExHandle(void* p); -int32_t transRemoveExHandle(int64_t refId); -SExHandle* transAcquireExHandle(int64_t refId); -int32_t transReleaseExHandle(int64_t refId); -void transDestoryExHandle(void* handle); +int32_t transOpenRefMgt(int size, void (*func)(void*)); +void transCloseRefMgt(int32_t refMgt); +int64_t transAddExHandle(int32_t refMgt, void* p); +int32_t transRemoveExHandle(int32_t refMgt, int64_t refId); +void* transAcquireExHandle(int32_t refMgt, int64_t refId); +int32_t transReleaseExHandle(int32_t refMgt, int64_t refId); +void transDestoryExHandle(void* handle); + +int32_t transGetRefMgt(); +int32_t transGetInstMgt(); #ifdef __cplusplus } diff --git a/source/libs/transport/inc/transportInt.h b/source/libs/transport/inc/transportInt.h index 462debb247..5fb2980ceb 100644 --- a/source/libs/transport/inc/transportInt.h +++ b/source/libs/transport/inc/transportInt.h @@ -57,7 +57,7 @@ typedef struct { void* parent; void* tcphandle; // returned handle from TCP initialization - int32_t refMgt; + int64_t refId; TdThreadMutex mutex; } SRpcInfo; diff --git a/source/libs/transport/src/trans.c b/source/libs/transport/src/trans.c index 936cfe870d..48e7d7c91d 100644 --- a/source/libs/transport/src/trans.c +++ b/source/libs/transport/src/trans.c @@ -76,16 +76,23 @@ void* rpcOpen(const SRpcInit* pInit) { if (pInit->user) { memcpy(pRpc->user, pInit->user, strlen(pInit->user)); } - return pRpc; + + int64_t refId = transAddExHandle(transGetInstMgt(), pRpc); + transAcquireExHandle(transGetInstMgt(), refId); + pRpc->refId = refId; + return (void*)refId; } void rpcClose(void* arg) { tInfo("start to close rpc"); + transRemoveExHandle(transGetInstMgt(), (int64_t)arg); + transReleaseExHandle(transGetInstMgt(), (int64_t)arg); + tInfo("finish to close rpc"); + return; +} +void rpcCloseImpl(void* arg) { SRpcInfo* pRpc = (SRpcInfo*)arg; (*taosCloseHandle[pRpc->connType])(pRpc->tcphandle); taosMemoryFree(pRpc); - tInfo("finish to close rpc"); - - return; } void* rpcMallocCont(int32_t contLen) { @@ -140,11 +147,10 @@ void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pMsg, SRpcMsg* pRsp) { transSendRecv(shandle, pEpSet, pMsg, pRsp); } -void rpcSendResponse(const SRpcMsg* pMsg) { transSendResponse(pMsg); } +void rpcSendResponse(const SRpcMsg* pMsg) { transSendResponse(pMsg); } int32_t rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return 0; } - void rpcRefHandle(void* handle, int8_t type) { assert(type == TAOS_CONN_SERVER || type == TAOS_CONN_CLIENT); (*taosRefHandle[type])(handle); diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index c140de24d8..8b771f6f8a 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -47,6 +47,7 @@ typedef struct SCliMsg { queue q; STransMsgType type; + int64_t refId; uint64_t st; int sent; //(0: no send, 1: alread sent) } SCliMsg; @@ -262,13 +263,17 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) { #define REQUEST_PERSIS_HANDLE(msg) ((msg)->info.persistHandle == 1) #define REQUEST_RELEASE_HANDLE(cmsg) ((cmsg)->type == Release) +#define EPSET_IS_VALID(epSet) ((epSet) != NULL && (epSet)->numOfEps != 0) #define EPSET_GET_SIZE(epSet) (epSet)->numOfEps #define EPSET_GET_INUSE_IP(epSet) ((epSet)->eps[(epSet)->inUse].fqdn) #define EPSET_GET_INUSE_PORT(epSet) ((epSet)->eps[(epSet)->inUse].port) -#define EPSET_FORWARD_INUSE(epSet) \ - do { \ - (epSet)->inUse = (++((epSet)->inUse)) % ((epSet)->numOfEps); \ +#define EPSET_FORWARD_INUSE(epSet) \ + do { \ + if ((epSet)->numOfEps != 0) { \ + (epSet)->inUse = (++((epSet)->inUse)) % ((epSet)->numOfEps); \ + } \ } while (0) + #define EPSET_DEBUG_STR(epSet, tbuf) \ do { \ int len = snprintf(tbuf, sizeof(tbuf), "epset:{"); \ @@ -501,18 +506,17 @@ static SCliConn* getConnFromPool(void* pool, char* ip, uint32_t port) { } static void allocConnRef(SCliConn* conn, bool update) { if (update) { - transRemoveExHandle(conn->refId); + transRemoveExHandle(transGetRefMgt(), conn->refId); conn->refId = -1; } SExHandle* exh = taosMemoryCalloc(1, sizeof(SExHandle)); exh->handle = conn; exh->pThrd = conn->hostThrd; - exh->refId = transAddExHandle(exh); + exh->refId = transAddExHandle(transGetRefMgt(), exh); conn->refId = exh->refId; } static void addConnToPool(void* pool, SCliConn* conn) { if (conn->status == ConnInPool) { - // assert(0); return; } SCliThrd* thrd = conn->hostThrd; @@ -601,16 +605,14 @@ static void cliDestroyConn(SCliConn* conn, bool clear) { tTrace("%s conn %p remove from conn pool", CONN_GET_INST_LABEL(conn), conn); QUEUE_REMOVE(&conn->conn); QUEUE_INIT(&conn->conn); - transRemoveExHandle(conn->refId); + transRemoveExHandle(transGetRefMgt(), conn->refId); conn->refId = -1; if (clear) { if (!uv_is_closing((uv_handle_t*)conn->stream)) { + uv_read_stop(conn->stream); uv_close((uv_handle_t*)conn->stream, cliDestroy); } - //} else { - // cliDestroy((uv_handle_t*)conn->stream); - //} } } static void cliDestroy(uv_handle_t* handle) { @@ -619,7 +621,7 @@ static void cliDestroy(uv_handle_t* handle) { } SCliConn* conn = handle->data; - transRemoveExHandle(conn->refId); + transRemoveExHandle(transGetRefMgt(), conn->refId); taosMemoryFree(conn->ip); conn->stream->data = NULL; taosMemoryFree(conn->stream); @@ -635,7 +637,6 @@ static bool cliHandleNoResp(SCliConn* conn) { SCliMsg* pMsg = transQueueGet(&conn->cliMsgs, 0); if (REQUEST_NO_RESP(&pMsg->msg)) { transQueuePop(&conn->cliMsgs); - // taosArrayRemove(msgs, 0); destroyCmsg(pMsg); res = true; } @@ -668,7 +669,6 @@ static void cliSendCb(uv_write_t* req, int status) { void cliSend(SCliConn* pConn) { CONN_HANDLE_BROKEN(pConn); - // assert(taosArrayGetSize(pConn->cliMsgs) > 0); assert(!transQueueEmpty(&pConn->cliMsgs)); SCliMsg* pCliMsg = NULL; @@ -747,7 +747,7 @@ static void cliHandleQuit(SCliMsg* pMsg, SCliThrd* pThrd) { } static void cliHandleRelease(SCliMsg* pMsg, SCliThrd* pThrd) { int64_t refId = (int64_t)(pMsg->msg.info.handle); - SExHandle* exh = transAcquireExHandle(refId); + SExHandle* exh = transAcquireExHandle(transGetRefMgt(), refId); if (exh == NULL) { tDebug("%" PRId64 " already release", refId); } @@ -773,14 +773,14 @@ SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrd* pThrd, bool* ignore) { SCliConn* conn = NULL; int64_t refId = (int64_t)(pMsg->msg.info.handle); if (refId != 0) { - SExHandle* exh = transAcquireExHandle(refId); + SExHandle* exh = transAcquireExHandle(transGetRefMgt(), refId); if (exh == NULL) { *ignore = true; destroyCmsg(pMsg); return NULL; } else { conn = exh->handle; - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); } return conn; }; @@ -810,6 +810,11 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd) { STrans* pTransInst = pThrd->pTransInst; cliMayCvtFqdnToIp(&pCtx->epSet, &pThrd->cvtAddr); + if (!EPSET_IS_VALID(&pCtx->epSet)) { + destroyCmsg(pMsg); + tError("invalid epset"); + return; + } bool ignore = false; SCliConn* conn = cliGetConn(pMsg, pThrd, &ignore); @@ -977,6 +982,7 @@ void cliSendQuit(SCliThrd* thrd) { } void cliWalkCb(uv_handle_t* handle, void* arg) { if (!uv_is_closing(handle)) { + uv_read_stop((uv_stream_t*)handle); uv_close(handle, cliDestroy); } } @@ -1066,7 +1072,7 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) { if (retry) { pMsg->sent = 0; pCtx->retryCnt += 1; - if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL) { + if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_RPC_BROKEN_LINK) { cliCompareAndSwap(&pCtx->retryLimit, TRANS_RETRY_COUNT_LIMIT, EPSET_GET_SIZE(&pCtx->epSet) * 3); if (pCtx->retryCnt < pCtx->retryLimit) { transUnrefCliHandle(pConn); @@ -1077,12 +1083,14 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) { } else { cliCompareAndSwap(&pCtx->retryLimit, TRANS_RETRY_COUNT_LIMIT, TRANS_RETRY_COUNT_LIMIT); if (pCtx->retryCnt < pCtx->retryLimit) { - addConnToPool(pThrd->pool, pConn); if (pResp->contLen == 0) { EPSET_FORWARD_INUSE(&pCtx->epSet); } else { - tDeserializeSEpSet(pResp->pCont, pResp->contLen, &pCtx->epSet); + if (tDeserializeSEpSet(pResp->pCont, pResp->contLen, &pCtx->epSet) < 0) { + tError("%s conn %p failed to deserialize epset", CONN_GET_INST_LABEL(pConn)); + } } + addConnToPool(pThrd->pool, pConn); transFreeMsg(pResp->pCont); cliSchedMsgToNextNode(pMsg, pThrd); return -1; @@ -1152,12 +1160,12 @@ void transUnrefCliHandle(void* handle) { } SCliThrd* transGetWorkThrdFromHandle(int64_t handle) { SCliThrd* pThrd = NULL; - SExHandle* exh = transAcquireExHandle(handle); + SExHandle* exh = transAcquireExHandle(transGetRefMgt(), handle); if (exh == NULL) { return NULL; } pThrd = exh->pThrd; - transReleaseExHandle(handle); + transReleaseExHandle(transGetRefMgt(), handle); return pThrd; } SCliThrd* transGetWorkThrd(STrans* trans, int64_t handle) { @@ -1184,10 +1192,13 @@ void transReleaseCliHandle(void* handle) { } void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransCtx* ctx) { - STrans* pTransInst = (STrans*)shandle; + STrans* pTransInst = (STrans*)transAcquireExHandle(transGetInstMgt(), (int64_t)shandle); + if (pTransInst == NULL) return; + SCliThrd* pThrd = transGetWorkThrd(pTransInst, (int64_t)pReq->info.handle); if (pThrd == NULL) { transFreeMsg(pReq->pCont); + transReleaseExHandle(transGetInstMgt(), (int64_t)shandle); return; } @@ -1208,19 +1219,24 @@ void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STra cliMsg->msg = *pReq; cliMsg->st = taosGetTimestampUs(); cliMsg->type = Normal; + cliMsg->refId = (int64_t)shandle; STraceId* trace = &pReq->info.traceId; tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle); ASSERT(transAsyncSend(pThrd->asyncPool, &(cliMsg->q)) == 0); + transReleaseExHandle(transGetInstMgt(), (int64_t)shandle); return; } void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransMsg* pRsp) { - STrans* pTransInst = (STrans*)shandle; + STrans* pTransInst = (STrans*)transAcquireExHandle(transGetInstMgt(), (int64_t)shandle); + if (pTransInst == NULL) return; + SCliThrd* pThrd = transGetWorkThrd(pTransInst, (int64_t)pReq->info.handle); if (pThrd == NULL) { transFreeMsg(pReq->pCont); + transReleaseExHandle(transGetInstMgt(), (int64_t)shandle); return; } tsem_t* sem = taosMemoryCalloc(1, sizeof(tsem_t)); @@ -1241,6 +1257,7 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM cliMsg->msg = *pReq; cliMsg->st = taosGetTimestampUs(); cliMsg->type = Normal; + cliMsg->refId = (int64_t)shandle; STraceId* trace = &pReq->info.traceId; tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid, @@ -1250,13 +1267,16 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM tsem_wait(sem); tsem_destroy(sem); taosMemoryFree(sem); + + transReleaseExHandle(transGetInstMgt(), (int64_t)shandle); return; } /* * **/ void transSetDefaultAddr(void* shandle, const char* ip, const char* fqdn) { - STrans* pTransInst = shandle; + STrans* pTransInst = (STrans*)transAcquireExHandle(transGetInstMgt(), (int64_t)shandle); + if (pTransInst == NULL) return; SCvtAddr cvtAddr = {0}; if (ip != NULL && fqdn != NULL) { @@ -1271,11 +1291,13 @@ void transSetDefaultAddr(void* shandle, const char* ip, const char* fqdn) { SCliMsg* cliMsg = taosMemoryCalloc(1, sizeof(SCliMsg)); cliMsg->ctx = pCtx; cliMsg->type = Update; + cliMsg->refId = (int64_t)shandle; SCliThrd* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[i]; tDebug("%s update epset at thread:%08" PRId64 "", pTransInst->label, thrd->pid); transAsyncSend(thrd->asyncPool, &(cliMsg->q)); } + transReleaseExHandle(transGetInstMgt(), (int64_t)shandle); } #endif diff --git a/source/libs/transport/src/transComm.c b/source/libs/transport/src/transComm.c index 57549c59bb..5f6e3db615 100644 --- a/source/libs/transport/src/transComm.c +++ b/source/libs/transport/src/transComm.c @@ -19,6 +19,7 @@ static TdThreadOnce transModuleInit = PTHREAD_ONCE_INIT; static int32_t refMgt; +static int32_t instMgt; int transAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) { T_MD5_CTX context; @@ -479,53 +480,54 @@ bool transEpSetIsEqual(SEpSet* a, SEpSet* b) { } return true; } -static int32_t transGetRefMgt() { - // - return refMgt; -} static void transInitEnv() { - refMgt = transOpenExHandleMgt(50000); + refMgt = transOpenRefMgt(50000, transDestoryExHandle); + instMgt = taosOpenRef(50, rpcCloseImpl); uv_os_setenv("UV_TCP_SINGLE_ACCEPT", "1"); } static void transDestroyEnv() { - // close ref - transCloseExHandleMgt(); + transCloseRefMgt(refMgt); + transCloseRefMgt(instMgt); } void transInit() { // init env taosThreadOnce(&transModuleInit, transInitEnv); } + +int32_t transGetRefMgt() { return refMgt; } +int32_t transGetInstMgt() { return instMgt; } + void transCleanup() { // clean env transDestroyEnv(); } -int32_t transOpenExHandleMgt(int size) { +int32_t transOpenRefMgt(int size, void (*func)(void*)) { // added into once later - return taosOpenRef(size, transDestoryExHandle); + return taosOpenRef(size, func); } -void transCloseExHandleMgt() { +void transCloseRefMgt(int32_t mgt) { // close ref - taosCloseRef(transGetRefMgt()); + taosCloseRef(mgt); } -int64_t transAddExHandle(void* p) { +int64_t transAddExHandle(int32_t refMgt, void* p) { // acquire extern handle - return taosAddRef(transGetRefMgt(), p); + return taosAddRef(refMgt, p); } -int32_t transRemoveExHandle(int64_t refId) { +int32_t transRemoveExHandle(int32_t refMgt, int64_t refId) { // acquire extern handle - return taosRemoveRef(transGetRefMgt(), refId); + return taosRemoveRef(refMgt, refId); } -SExHandle* transAcquireExHandle(int64_t refId) { +void* transAcquireExHandle(int32_t refMgt, int64_t refId) { // acquire extern handle - return (SExHandle*)taosAcquireRef(transGetRefMgt(), refId); + return (void*)taosAcquireRef(refMgt, refId); } -int32_t transReleaseExHandle(int64_t refId) { +int32_t transReleaseExHandle(int32_t refMgt, int64_t refId) { // release extern handle - return taosReleaseRef(transGetRefMgt(), refId); + return taosReleaseRef(refMgt, refId); } void transDestoryExHandle(void* handle) { if (handle == NULL) { diff --git a/source/libs/transport/src/transSvr.c b/source/libs/transport/src/transSvr.c index d32156dd0d..7323aa0882 100644 --- a/source/libs/transport/src/transSvr.c +++ b/source/libs/transport/src/transSvr.c @@ -261,7 +261,7 @@ static void uvHandleReq(SSvrConn* pConn) { // 2. once send out data, cli conn released to conn pool immediately // 3. not mixed with persist transMsg.info.ahandle = (void*)pHead->ahandle; - transMsg.info.handle = (void*)transAcquireExHandle(pConn->refId); + transMsg.info.handle = (void*)transAcquireExHandle(transGetRefMgt(), pConn->refId); transMsg.info.refId = pConn->refId; transMsg.info.traceId = pHead->traceId; @@ -279,7 +279,7 @@ static void uvHandleReq(SSvrConn* pConn) { pConnInfo->clientPort = ntohs(pConn->addr.sin_port); tstrncpy(pConnInfo->user, pConn->user, sizeof(pConnInfo->user)); - transReleaseExHandle(pConn->refId); + transReleaseExHandle(transGetRefMgt(), pConn->refId); STrans* pTransInst = pConn->pTransInst; (*pTransInst->cfp)(pTransInst->parent, &transMsg, NULL); @@ -507,15 +507,15 @@ void uvWorkerAsyncCb(uv_async_t* handle) { SExHandle* exh1 = transMsg.info.handle; int64_t refId = transMsg.info.refId; - SExHandle* exh2 = transAcquireExHandle(refId); + SExHandle* exh2 = transAcquireExHandle(transGetRefMgt(), refId); if (exh2 == NULL || exh1 != exh2) { tTrace("handle except msg %p, ignore it", exh1); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); destroySmsg(msg); continue; } msg->pConn = exh1->handle; - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); (*transAsyncHandle[msg->type])(msg, pThrd); } } @@ -757,8 +757,8 @@ static SSvrConn* createConn(void* hThrd) { SExHandle* exh = taosMemoryMalloc(sizeof(SExHandle)); exh->handle = pConn; exh->pThrd = pThrd; - exh->refId = transAddExHandle(exh); - transAcquireExHandle(exh->refId); + exh->refId = transAddExHandle(transGetRefMgt(), exh); + transAcquireExHandle(transGetRefMgt(), exh->refId); pConn->refId = exh->refId; transRefSrvHandle(pConn); @@ -789,14 +789,14 @@ static void destroyConnRegArg(SSvrConn* conn) { } } static int reallocConnRef(SSvrConn* conn) { - transReleaseExHandle(conn->refId); - transRemoveExHandle(conn->refId); + transReleaseExHandle(transGetRefMgt(), conn->refId); + transRemoveExHandle(transGetRefMgt(), conn->refId); // avoid app continue to send msg on invalid handle SExHandle* exh = taosMemoryMalloc(sizeof(SExHandle)); exh->handle = conn; exh->pThrd = conn->hostThrd; - exh->refId = transAddExHandle(exh); - transAcquireExHandle(exh->refId); + exh->refId = transAddExHandle(transGetRefMgt(), exh); + transAcquireExHandle(transGetRefMgt(), exh->refId); conn->refId = exh->refId; return 0; @@ -808,8 +808,8 @@ static void uvDestroyConn(uv_handle_t* handle) { } SWorkThrd* thrd = conn->hostThrd; - transReleaseExHandle(conn->refId); - transRemoveExHandle(conn->refId); + transReleaseExHandle(transGetRefMgt(), conn->refId); + transRemoveExHandle(transGetRefMgt(), conn->refId); tDebug("%s conn %p destroy", transLabel(thrd->pTransInst), conn); transQueueDestroy(&conn->srvMsgs); @@ -1029,8 +1029,9 @@ void transUnrefSrvHandle(void* handle) { } void transReleaseSrvHandle(void* handle) { - SExHandle* exh = handle; - int64_t refId = exh->refId; + SRpcHandleInfo* info = handle; + SExHandle* exh = info->handle; + int64_t refId = info->refId; ASYNC_CHECK_HANDLE(exh, refId); @@ -1045,11 +1046,11 @@ void transReleaseSrvHandle(void* handle) { tTrace("%s conn %p start to release", transLabel(pThrd->pTransInst), exh->handle); transAsyncSend(pThrd->asyncPool, &m->q); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return1: tTrace("handle %p failed to send to release handle", exh); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return2: tTrace("handle %p failed to send to release handle", exh); @@ -1074,12 +1075,12 @@ void transSendResponse(const STransMsg* msg) { STraceId* trace = (STraceId*)&msg->info.traceId; tGTrace("conn %p start to send resp (1/2)", exh->handle); transAsyncSend(pThrd->asyncPool, &m->q); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return1: tTrace("handle %p failed to send resp", exh); rpcFreeCont(msg->pCont); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return2: tTrace("handle %p failed to send resp", exh); @@ -1103,13 +1104,13 @@ void transRegisterMsg(const STransMsg* msg) { tTrace("%s conn %p start to register brokenlink callback", transLabel(pThrd->pTransInst), exh->handle); transAsyncSend(pThrd->asyncPool, &m->q); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return1: tTrace("handle %p failed to register brokenlink", exh); rpcFreeCont(msg->pCont); - transReleaseExHandle(refId); + transReleaseExHandle(transGetRefMgt(), refId); return; _return2: tTrace("handle %p failed to register brokenlink", exh); diff --git a/source/libs/transport/test/transUT.cpp b/source/libs/transport/test/transUT.cpp index 86c4830284..b55f771ebd 100644 --- a/source/libs/transport/test/transUT.cpp +++ b/source/libs/transport/test/transUT.cpp @@ -175,7 +175,7 @@ static void processReleaseHandleCb(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) rpcMsg.code = 0; rpcSendResponse(&rpcMsg); - rpcReleaseHandle(pMsg->info.handle, TAOS_CONN_SERVER); + rpcReleaseHandle(&pMsg->info, TAOS_CONN_SERVER); } static void processRegisterFailure(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { { diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c index 9245c03826..27f12259bc 100644 --- a/source/libs/wal/src/walWrite.c +++ b/source/libs/wal/src/walWrite.c @@ -332,21 +332,25 @@ int32_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog terrno = TSDB_CODE_WAL_SIZE_LIMIT; return -1; } + taosThreadMutexLock(&pWal->mutex); if (index == pWal->vers.lastVer + 1) { if (taosArrayGetSize(pWal->fileInfoSet) == 0) { pWal->vers.firstVer = index; if (walRoll(pWal) < 0) { + taosThreadMutexUnlock(&pWal->mutex); return -1; } } else { int64_t passed = walGetSeq() - pWal->lastRollSeq; if (pWal->cfg.rollPeriod != -1 && pWal->cfg.rollPeriod != 0 && passed > pWal->cfg.rollPeriod) { if (walRoll(pWal) < 0) { + taosThreadMutexUnlock(&pWal->mutex); return -1; } } else if (pWal->cfg.segSize != -1 && pWal->cfg.segSize != 0 && walGetLastFileSize(pWal) > pWal->cfg.segSize) { if (walRoll(pWal) < 0) { + taosThreadMutexUnlock(&pWal->mutex); return -1; } } @@ -355,6 +359,7 @@ int32_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog // reject skip log or rewrite log // must truncate explicitly first terrno = TSDB_CODE_WAL_INVALID_VER; + taosThreadMutexUnlock(&pWal->mutex); return -1; } @@ -362,8 +367,6 @@ int32_t walWriteWithSyncInfo(SWal *pWal, int64_t index, tmsg_t msgType, SSyncLog ASSERT(pWal->writeCur >= 0); - taosThreadMutexLock(&pWal->mutex); - if (pWal->pWriteIdxTFile == NULL || pWal->pWriteLogTFile == NULL) { walSetWrite(pWal); taosLSeekFile(pWal->pWriteLogTFile, 0, SEEK_END); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index a2304483bf..9cd1294c17 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -178,6 +178,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ALREADY_EXIST, "Dnode already exists" TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_EXIST, "Dnode does not exist") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DNODES, "Too many dnodes") TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_DNODES, "Out of dnodes") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_MEM_IN_DNODE, "No enough memory in dnode") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_CFG, "Cluster cfg inconsistent") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_ID, "Cluster id not match") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DNODE_CFG, "Invalid dnode cfg") @@ -434,6 +435,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RECONFIG_NOT_READY, "Sync not ready for re TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready for propose") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_STANDBY_NOT_READY, "Sync not ready for standby") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_BATCH_ERROR, "Sync batch error") +TAOS_DEFINE_ERROR(TSDB_CODE_SYN_TIMEOUT, "Sync timeout") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INTERNAL_ERROR, "Sync internal error") // wal diff --git a/source/util/src/ttimer.c b/source/util/src/ttimer.c index 36b9437b66..7256331c85 100644 --- a/source/util/src/ttimer.c +++ b/source/util/src/ttimer.c @@ -18,6 +18,7 @@ #include "taoserror.h" #include "tlog.h" #include "tsched.h" +#include "tdef.h" #define tmrFatal(...) \ { \ @@ -110,7 +111,7 @@ typedef struct time_wheel_t { tmr_obj_t** slots; } time_wheel_t; -static int32_t tsMaxTmrCtrl = 512; +static int32_t tsMaxTmrCtrl = TSDB_MAX_VNODES_PER_DB + 100; static TdThreadOnce tmrModuleInit = PTHREAD_ONCE_INIT; static TdThreadMutex tmrCtrlMutex; diff --git a/tests/script/api/stopquery.c b/tests/script/api/stopquery.c index 4c7964c983..0f27fdf9f9 100644 --- a/tests/script/api/stopquery.c +++ b/tests/script/api/stopquery.c @@ -52,6 +52,7 @@ typedef struct { typedef struct SSP_CB_PARAM { TAOS *taos; bool fetch; + bool free; int32_t *end; } SSP_CB_PARAM; @@ -156,7 +157,58 @@ void sqCloseQueryCb(void *param, TAOS_RES *pRes, int code) { } } -int sqSyncStopQuery(bool fetch) { +void sqKillFetchCb(void *param, TAOS_RES *pRes, int numOfRows) { + SSP_CB_PARAM *qParam = (SSP_CB_PARAM *)param; + taos_kill_query(qParam->taos); + + *qParam->end = 1; +} + +void sqKillQueryCb(void *param, TAOS_RES *pRes, int code) { + SSP_CB_PARAM *qParam = (SSP_CB_PARAM *)param; + if (code == 0 && pRes) { + if (qParam->fetch) { + taos_fetch_rows_a(pRes, sqKillFetchCb, param); + } else { + taos_kill_query(qParam->taos); + *qParam->end = 1; + } + } else { + sqExit("select", taos_errstr(pRes)); + } +} + +void sqAsyncFetchCb(void *param, TAOS_RES *pRes, int numOfRows) { + SSP_CB_PARAM *qParam = (SSP_CB_PARAM *)param; + if (numOfRows > 0) { + taos_fetch_rows_a(pRes, sqAsyncFetchCb, param); + } else { + *qParam->end = 1; + if (qParam->free) { + taos_free_result(pRes); + } + } +} + + +void sqAsyncQueryCb(void *param, TAOS_RES *pRes, int code) { + SSP_CB_PARAM *qParam = (SSP_CB_PARAM *)param; + if (code == 0 && pRes) { + if (qParam->fetch) { + taos_fetch_rows_a(pRes, sqAsyncFetchCb, param); + } else { + if (qParam->free) { + taos_free_result(pRes); + } + *qParam->end = 1; + } + } else { + sqExit("select", taos_errstr(pRes)); + } +} + + +int sqStopSyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -189,7 +241,7 @@ int sqSyncStopQuery(bool fetch) { CASE_LEAVE(); } -int sqAsyncStopQuery(bool fetch) { +int sqStopAsyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -219,7 +271,7 @@ int sqAsyncStopQuery(bool fetch) { CASE_LEAVE(); } -int sqSyncFreeQuery(bool fetch) { +int sqFreeSyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -250,7 +302,7 @@ int sqSyncFreeQuery(bool fetch) { CASE_LEAVE(); } -int sqAsyncFreeQuery(bool fetch) { +int sqFreeAsyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -280,7 +332,7 @@ int sqAsyncFreeQuery(bool fetch) { CASE_LEAVE(); } -int sqSyncCloseQuery(bool fetch) { +int sqCloseSyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -310,7 +362,7 @@ int sqSyncCloseQuery(bool fetch) { CASE_LEAVE(); } -int sqAsyncCloseQuery(bool fetch) { +int sqCloseAsyncQuery(bool fetch) { CASE_ENTER(); for (int32_t i = 0; i < runTimes; ++i) { char sql[1024] = {0}; @@ -360,9 +412,39 @@ void *syncQueryThreadFp(void *arg) { taos_fetch_row(pRes); } - taos_free_result(pRes); + if (qParam->free) { + taos_free_result(pRes); + } } +void *asyncQueryThreadFp(void *arg) { + SSP_CB_PARAM* qParam = (SSP_CB_PARAM*)arg; + char sql[1024] = {0}; + int32_t code = 0; + TAOS *taos = taos_connect(hostName, "root", "taosdata", NULL, 0); + if (taos == NULL) sqExit("taos_connect", taos_errstr(NULL)); + + qParam->taos = taos; + + sprintf(sql, "reset query cache"); + sqExecSQLE(taos, sql); + + sprintf(sql, "use %s", dbName); + sqExecSQLE(taos, sql); + + sprintf(sql, "select * from %s", tbName); + + int32_t qEnd = 0; + SSP_CB_PARAM param = {0}; + param.fetch = qParam->fetch; + param.end = &qEnd; + taos_query_a(taos, sql, sqAsyncQueryCb, ¶m); + while (0 == qEnd) { + usleep(5000); + } +} + + void *closeThreadFp(void *arg) { SSP_CB_PARAM* qParam = (SSP_CB_PARAM*)arg; while (true) { @@ -376,7 +458,22 @@ void *closeThreadFp(void *arg) { } -int sqConSyncCloseQuery(bool fetch) { + +void *killThreadFp(void *arg) { + SSP_CB_PARAM* qParam = (SSP_CB_PARAM*)arg; + while (true) { + if (qParam->taos) { + usleep(rand() % 10000); + taos_kill_query(qParam->taos); + break; + } + usleep(1); + } +} + + + +int sqConCloseSyncQuery(bool fetch) { CASE_ENTER(); pthread_t qid, cid; for (int32_t i = 0; i < runTimes; ++i) { @@ -391,26 +488,160 @@ int sqConSyncCloseQuery(bool fetch) { CASE_LEAVE(); } +int sqConCloseAsyncQuery(bool fetch) { + CASE_ENTER(); + pthread_t qid, cid; + for (int32_t i = 0; i < runTimes; ++i) { + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + pthread_create(&qid, NULL, asyncQueryThreadFp, (void*)¶m); + pthread_create(&cid, NULL, closeThreadFp, (void*)¶m); + + pthread_join(qid, NULL); + pthread_join(cid, NULL); + } + CASE_LEAVE(); +} + + +int sqKillSyncQuery(bool fetch) { + CASE_ENTER(); + for (int32_t i = 0; i < runTimes; ++i) { + char sql[1024] = {0}; + int32_t code = 0; + TAOS *taos = taos_connect(hostName, "root", "taosdata", NULL, 0); + if (taos == NULL) sqExit("taos_connect", taos_errstr(NULL)); + + sprintf(sql, "reset query cache"); + sqExecSQL(taos, sql); + + sprintf(sql, "use %s", dbName); + sqExecSQL(taos, sql); + + sprintf(sql, "select * from %s", tbName); + TAOS_RES* pRes = taos_query(taos, sql); + code = taos_errno(pRes); + if (code) { + sqExit("taos_query", taos_errstr(pRes)); + } + + if (fetch) { + taos_fetch_row(pRes); + } + + taos_kill_query(taos); + + taos_close(taos); + } + CASE_LEAVE(); +} + +int sqKillAsyncQuery(bool fetch) { + CASE_ENTER(); + for (int32_t i = 0; i < runTimes; ++i) { + char sql[1024] = {0}; + int32_t code = 0; + TAOS *taos = taos_connect(hostName, "root", "taosdata", NULL, 0); + if (taos == NULL) sqExit("taos_connect", taos_errstr(NULL)); + + sprintf(sql, "reset query cache"); + sqExecSQL(taos, sql); + + sprintf(sql, "use %s", dbName); + sqExecSQL(taos, sql); + + sprintf(sql, "select * from %s", tbName); + + int32_t qEnd = 0; + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + param.end = &qEnd; + param.taos = taos; + taos_query_a(taos, sql, sqKillQueryCb, ¶m); + while (0 == qEnd) { + usleep(5000); + } + + taos_close(taos); + } + CASE_LEAVE(); +} + +int sqConKillSyncQuery(bool fetch) { + CASE_ENTER(); + pthread_t qid, cid; + for (int32_t i = 0; i < runTimes; ++i) { + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + pthread_create(&qid, NULL, syncQueryThreadFp, (void*)¶m); + pthread_create(&cid, NULL, killThreadFp, (void*)¶m); + + pthread_join(qid, NULL); + pthread_join(cid, NULL); + } + CASE_LEAVE(); +} + +int sqConKillAsyncQuery(bool fetch) { + CASE_ENTER(); + pthread_t qid, cid; + for (int32_t i = 0; i < runTimes; ++i) { + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + pthread_create(&qid, NULL, asyncQueryThreadFp, (void*)¶m); + pthread_create(&cid, NULL, killThreadFp, (void*)¶m); + + pthread_join(qid, NULL); + pthread_join(cid, NULL); + } + CASE_LEAVE(); +} + + + void sqRunAllCase(void) { /* - sqSyncStopQuery(false); - sqSyncStopQuery(true); - sqAsyncStopQuery(false); - sqAsyncStopQuery(true); + sqStopSyncQuery(false); + sqStopSyncQuery(true); + sqStopAsyncQuery(false); + sqStopAsyncQuery(true); - sqSyncFreeQuery(false); - sqSyncFreeQuery(true); - sqAsyncFreeQuery(false); - sqAsyncFreeQuery(true); + sqFreeSyncQuery(false); + sqFreeSyncQuery(true); + sqFreeAsyncQuery(false); + sqFreeAsyncQuery(true); - sqSyncCloseQuery(false); - sqSyncCloseQuery(true); - sqAsyncCloseQuery(false); - sqAsyncCloseQuery(true); -*/ - sqConSyncCloseQuery(false); - sqConSyncCloseQuery(true); + sqCloseSyncQuery(false); + sqCloseSyncQuery(true); + sqCloseAsyncQuery(false); + sqCloseAsyncQuery(true); + + sqConCloseSyncQuery(false); + sqConCloseSyncQuery(true); + sqConCloseAsyncQuery(false); + sqConCloseAsyncQuery(true); +*/ +#if 0 + + sqKillSyncQuery(false); + sqKillSyncQuery(true); + sqKillAsyncQuery(false); + sqKillAsyncQuery(true); +#endif + + //sqConKillSyncQuery(false); + sqConKillSyncQuery(true); +#if 0 + sqConKillAsyncQuery(false); + sqConKillAsyncQuery(true); +#endif + + int32_t l = 5; + while (l) { + printf("%d\n", l--); + sleep(1); + } } diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 2b33067381..cbcc2d86ef 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -164,6 +164,7 @@ ./test.sh -f tsim/sma/drop_sma.sim ./test.sh -f tsim/sma/tsmaCreateInsertQuery.sim ./test.sh -f tsim/sma/rsmaCreateInsertQuery.sim +./test.sh -f tsim/sma/rsmaPersistenceRecovery.sim # --- valgrind ./test.sh -f tsim/valgrind/checkError.sim -v diff --git a/tests/script/sh/deploy.sh b/tests/script/sh/deploy.sh index d54624872f..1deea26337 100755 --- a/tests/script/sh/deploy.sh +++ b/tests/script/sh/deploy.sh @@ -121,7 +121,7 @@ echo "firstEp ${HOSTNAME}:7100" >> $TAOS_CFG echo "secondEp ${HOSTNAME}:7200" >> $TAOS_CFG echo "fqdn ${HOSTNAME}" >> $TAOS_CFG echo "serverPort ${NODE}" >> $TAOS_CFG -echo "supportVnodes 128" >> $TAOS_CFG +echo "supportVnodes 1024" >> $TAOS_CFG echo "dataDir $DATA_DIR" >> $TAOS_CFG echo "logDir $LOG_DIR" >> $TAOS_CFG echo "debugFlag 0" >> $TAOS_CFG @@ -135,7 +135,7 @@ echo "jniDebugFlag 143" >> $TAOS_CFG echo "qDebugFlag 143" >> $TAOS_CFG echo "rpcDebugFlag 143" >> $TAOS_CFG echo "tmrDebugFlag 131" >> $TAOS_CFG -echo "uDebugFlag 131" >> $TAOS_CFG +echo "uDebugFlag 143" >> $TAOS_CFG echo "sDebugFlag 143" >> $TAOS_CFG echo "wDebugFlag 143" >> $TAOS_CFG echo "numOfLogLines 20000000" >> $TAOS_CFG diff --git a/tests/script/sh/stop_dnodes.sh b/tests/script/sh/stop_dnodes.sh index b431c0627c..d30c75022a 100755 --- a/tests/script/sh/stop_dnodes.sh +++ b/tests/script/sh/stop_dnodes.sh @@ -14,7 +14,7 @@ while [ -n "$PID" ]; do echo kill -9 $PID #pkill -9 taosd kill -9 $PID - echo "Killing processes locking on port 6030" + echo "Killing taosd processes" if [ "$OS_TYPE" != "Darwin" ]; then fuser -k -n tcp 6030 else diff --git a/tests/script/tmp/prepare.sim b/tests/script/tmp/prepare.sim index 3b43656a41..2e16ee7bda 100644 --- a/tests/script/tmp/prepare.sim +++ b/tests/script/tmp/prepare.sim @@ -7,39 +7,33 @@ system sh/deploy.sh -n dnode4 -i 4 return -system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 -system sh/deploy.sh -n dnode4 -i 4 -system sh/deploy.sh -n dnode5 -i 5 -system sh/deploy.sh -n dnode6 -i 6 -system sh/deploy.sh -n dnode7 -i 7 -system sh/deploy.sh -n dnode8 -i 8 -system sh/deploy.sh -n dnode9 -i 9 system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -system sh/exec.sh -n dnode3 -s start -system sh/exec.sh -n dnode4 -s start -system sh/exec.sh -n dnode5 -s start -system sh/exec.sh -n dnode6 -s start -system sh/exec.sh -n dnode7 -s start -system sh/exec.sh -n dnode8 -s start -system sh/exec.sh -n dnode9 -s start +sql connect -sleep 2000 +$num = 200 +$i = 0 +while $i < $num + $port = $i + 8000 + $i = $i + 1 + sql create dnode $hostname port $port +endw -sql create dnode $hostname port 7200 -sql create dnode $hostname port 7300 -sql create dnode $hostname port 7400 -sql create dnode $hostname port 7500 -sql create dnode $hostname port 7600 -sql create dnode $hostname port 7700 -sql create dnode $hostname port 7800 -sql create dnode $hostname port 7900 +$i = 0 +while $i < $num + $port = $i + 8000 + $i = $i + 1 + $name = dnode . $port + system sh/deploy.sh -n $name -i 1 + system sh/cfg.sh -n $name -c serverPort -v $port + system sh/exec.sh -n $name -s start +endw -sql show dnodes; -print $data00 $data01 -print $data10 $data11 -print $data20 $data21 -print $data30 $data31 -print $data40 $data41 \ No newline at end of file +return + +sql create database db vgroups 1024 buffer 3; +sql use db; +sql create table if not exists stb (ts timestamp, c1 int, c2 float, c3 double) tags (t1 int unsigned); +sql create table ct1 using stb tags(1000); +sql create table ct2 using stb tags(1000) ; +sql show db.tables; +sql insert into ct1 values(now+0s, 10, 2.0, 3.0); \ No newline at end of file diff --git a/tests/script/tsim/insert/update0.sim b/tests/script/tsim/insert/update0.sim index ed74188bcb..41a389b6e8 100644 --- a/tests/script/tsim/insert/update0.sim +++ b/tests/script/tsim/insert/update0.sim @@ -8,8 +8,8 @@ print =============== create database sql create database d0 keep 365000d,365000d,365000d sql use d0 -print =============== create super table and register rsma -sql create table if not exists stb (ts timestamp, c1 int) tags (city binary(20),district binary(20)) rollup(min); +print =============== create super table +sql create table if not exists stb (ts timestamp, c1 int) tags (city binary(20),district binary(20)); sql show stables if $rows != 1 then diff --git a/tests/script/tsim/sma/rsmaPersistenceRecovery.sim b/tests/script/tsim/sma/rsmaPersistenceRecovery.sim new file mode 100644 index 0000000000..1b54e5a47d --- /dev/null +++ b/tests/script/tsim/sma/rsmaPersistenceRecovery.sim @@ -0,0 +1,237 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print =============== create database with retentions +sql create database d0 retentions 5s:7d,5m:21d,15m:365d; +sql use d0 + +print =============== create super table and register rsma +sql create table if not exists stb (ts timestamp, c1 int, c2 float) tags (city binary(20),district binary(20)) rollup(max) max_delay 5s,5s watermark 2s,3s; + +sql show stables +if $rows != 1 then + return -1 +endi + +print =============== create child table +sql create table ct1 using stb tags("BeiJing", "ChaoYang"); + +sql show tables +if $rows != 1 then + return -1 +endi + +print =============== insert data and trigger rollup +sql insert into ct1 values(now, 10, 10.0); +sql insert into ct1 values(now+1s, 1, 1.0); +sql insert into ct1 values(now+2s, 100, 100.0); + +print =============== wait maxdelay 5+1 seconds for results +sleep 6000 + +print =============== select * from retention level 2 from memory +sql select * from ct1; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 2 file rows $rows > 2 + return -1 +endi + + +if $data01 != 100 then + if $data01 != 10 then + print retention level 2 file result $data01 != 100 or 10 + return -1 + endi +endi + +print =============== select * from retention level 1 from memory +sql select * from ct1 where ts > now-8d; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 1 file rows $rows > 2 + return -1 +endi + +if $data01 != 100 then + if $data01 != 10 then + print retention level 1 file result $data01 != 100 or 10 + return -1 + endi +endi + +print =============== select * from retention level 0 from memory +sql select * from ct1 where ts > now-3d; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 + +if $rows < 1 then + print retention level 0 file rows $rows < 1 + return -1 +endi + +if $data01 != 10 then + print retention level 0 file result $data01 != 10 + return -1 +endi + +#=================================================================== + + +#==================== reboot to trigger commit data to file +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode1 -s start + +print =============== select * from retention level 2 from file +sql select * from ct1; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 2 file rows $rows > 2 + return -1 +endi + +if $data01 != 100 then + if $data01 != 10 then + print retention level 2 file result $data01 != 100 or 10 + return -1 + endi +endi + +print =============== select * from retention level 1 from file +sql select * from ct1 where ts > now-8d; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 1 file rows $rows > 2 + return -1 +endi + +if $data01 != 100 then + if $data01 != 10 then + print retention level 1 file result $data01 != 100 or 10 + return -1 + endi +endi + +print =============== select * from retention level 0 from file +sql select * from ct1 where ts > now-3d; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 +if $rows < 1 then + print retention level 0 file rows $rows < 1 + return -1 +endi + +if $data01 != 10 then + print retention level 0 file result $data01 != 10 + return -1 +endi + +print =============== insert after rsma qtaskinfo recovery +sql insert into ct1 values(now, 50, 500.0); +sql insert into ct1 values(now+1s, 40, 40.0); + +print =============== wait maxdelay 5+1 seconds for results +sleep 6000 + +print =============== select * from retention level 2 from file and memory after rsma qtaskinfo recovery +sql select * from ct1; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 2 file/mem rows $rows > 2 + return -1 +endi + +if $data01 != 100 then + if $data01 != 10 then + print retention level 2 file/mem result $data01 != 100 or 10 + return -1 + endi +endi + +if $data02 != 500.00000 then + if $data02 != 100.00000 then + print retention level 1 file/mem result $data02 != 500.00000 or 100.00000 + return -1 + endi +endi + +print =============== select * from retention level 1 from file and memory after rsma qtaskinfo recovery +sql select * from ct1 where ts > now-8d; +print $data00 $data01 $data02 +if $rows > 2 then + print retention level 1 file/mem rows $rows > 2 + return -1 +endi + +if $data01 != 100 then + if $data01 != 10 then + print retention level 1 file/mem result $data01 != 100 or 10 + return -1 + endi +endi + +if $data02 != 500.00000 then + if $data02 != 100.00000 then + print retention level 1 file/mem result $data02 != 500.00000 or 100.00000 + return -1 + endi +endi + + +print =============== select * from retention level 0 from file and memory after rsma qtaskinfo recovery +sql select * from ct1 where ts > now-3d; +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 +print $data30 $data31 $data32 +print $data40 $data41 $data42 + +if $rows < 1 then + print retention level 0 file/mem rows $rows < 1 + return -1 +endi + +if $data01 != 10 then + print retention level 0 file/mem result $data01 != 10 + return -1 +endi + +if $data11 != 1 then + print retention level 0 file/mem result $data11 != 1 + return -1 +endi + +if $data21 != 100 then + print retention level 0 file/mem result $data21 != 100 + return -1 +endi + +if $data31 != 50 then + print retention level 0 file/mem result $data31 != 50 + return -1 +endi + +if $data32 != 500.00000 then + print retention level 0 file/mem result $data32 != 500.00000 + return -1 +endi + + +if $data41 != 40 then + print retention level 0 file/mem result $data41 != 40 + return -1 +endi + +if $data42 != 40.00000 then + print retention level 0 file/mem result $data42 != 40.00000 + return -1 +endi + + + +system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/tmq/basic1.sim b/tests/script/tsim/tmq/basic1.sim index ee9e87cf04..6880f290f5 100644 --- a/tests/script/tsim/tmq/basic1.sim +++ b/tests/script/tsim/tmq/basic1.sim @@ -131,6 +131,7 @@ if $data[0][1] != $consumerId then return -1 endi if $data[0][2] != $expectmsgcnt then + print expect $expectmsgcnt , actual $data02 return -1 endi if $data[0][3] != $expectmsgcnt then diff --git a/tests/script/tsim/valgrind/basic.sim b/tests/script/tsim/valgrind/basic.sim index 0f11ae0313..b449527568 100644 --- a/tests/script/tsim/valgrind/basic.sim +++ b/tests/script/tsim/valgrind/basic.sim @@ -1,8 +1,33 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode1 -s start -v sql connect -sql create database d0 vgroups 1; +print =============== step1: create drop show dnodes +$x = 0 +step1: + $x = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not ready! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +if $rows != 1 then + return -1 +endi +goto _OVER + +print =============== step2: create alter drop show user +sql create user u1 pass 'taosdata' +sql show users +sql alter user u1 sysinfo 1 +sql alter user u1 enable 1 +sql alter user u1 pass 'taosdata' +sql alter user u2 sysinfo 0 +sql drop user u1 + +_OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/system-test/1-insert/block_wise.py b/tests/system-test/1-insert/block_wise.py new file mode 100644 index 0000000000..6c779c64d7 --- /dev/null +++ b/tests/system-test/1-insert/block_wise.py @@ -0,0 +1,442 @@ +import datetime +import re + +from dataclasses import dataclass, field +from typing import List, Any, Tuple +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.constant import * + +PRIMARY_COL = "ts" + +INT_COL = "c_int" +BINT_COL = "c_bint" +SINT_COL = "c_sint" +TINT_COL = "c_tint" +FLOAT_COL = "c_float" +DOUBLE_COL = "c_double" +BOOL_COL = "c_bool" +TINT_UN_COL = "c_utint" +SINT_UN_COL = "c_usint" +BINT_UN_COL = "c_ubint" +INT_UN_COL = "c_uint" +BINARY_COL = "c_binary" +NCHAR_COL = "c_nchar" +TS_COL = "c_ts" + +NUM_COL = [INT_COL, BINT_COL, SINT_COL, TINT_COL, FLOAT_COL, DOUBLE_COL, ] +CHAR_COL = [BINARY_COL, NCHAR_COL, ] +BOOLEAN_COL = [BOOL_COL, ] +TS_TYPE_COL = [TS_COL, ] + +INT_TAG = "t_int" + +ALL_COL = [PRIMARY_COL, INT_COL, BINT_COL, SINT_COL, TINT_COL, FLOAT_COL, DOUBLE_COL, BINARY_COL, NCHAR_COL, BOOL_COL, TS_COL] +TAG_COL = [INT_TAG] + +# insert data args: +TIME_STEP = 10000 +NOW = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + +# init db/table +DBNAME = "db" +STBNAME = "stb1" +CTBNAME = "ct1" +NTBNAME = "nt1" + + +@dataclass +class DataSet: + ts_data : List[int] = field(default_factory=list) + int_data : List[int] = field(default_factory=list) + bint_data : List[int] = field(default_factory=list) + sint_data : List[int] = field(default_factory=list) + tint_data : List[int] = field(default_factory=list) + int_un_data : List[int] = field(default_factory=list) + bint_un_data: List[int] = field(default_factory=list) + sint_un_data: List[int] = field(default_factory=list) + tint_un_data: List[int] = field(default_factory=list) + float_data : List[float] = field(default_factory=list) + double_data : List[float] = field(default_factory=list) + bool_data : List[int] = field(default_factory=list) + binary_data : List[str] = field(default_factory=list) + nchar_data : List[str] = field(default_factory=list) + + +@dataclass +class BSMAschema: + creation : str = "CREATE" + tb_type : str = "stable" + tbname : str = STBNAME + cols : Tuple[str] = None + tags : Tuple[str] = None + sma_flag : str = "SMA" + sma_cols : Tuple[str] = None + create_tabel_sql : str = None + other : Any = None + + drop : str = "DROP" + drop_flag : str = "INDEX" + querySmaOptimize : int = 1 + show : str = "SHOW" + show_msg : str = "INDEXES" + show_oper : str = "FROM" + dbname : str = None + rollup_db : bool = False + + def __post_init__(self): + if isinstance(self.other, dict): + for k,v in self.other.items(): + + if k.lower() == "tbname" and isinstance(v, str) and not self.tbname: + self.tbname = v + del self.other[k] + + if k.lower() == "cols" and (isinstance(v, tuple) or isinstance(v, list)) and not self.cols: + self.cols = v + del self.other[k] + + if k.lower() == "tags" and (isinstance(v, tuple) or isinstance(v, list)) and not self.tags: + self.tags = v + del self.other[k] + + if k.lower() == "sma_flag" and isinstance(v, str) and not self.sma_flag: + self.sma_flag = v + del self.other[k] + + if k.lower() == "sma_cols" and (isinstance(v, tuple) or isinstance(v, list)) and not self.sma_cols: + self.sma_cols = v + del self.other[k] + + if k.lower() == "create_tabel_sql" and isinstance(v, str) and not self.create_tabel_sql: + self.create_tabel_sql = v + del self.other[k] + + # bSma show and drop operator is not completed + if k.lower() == "drop_flag" and isinstance(v, str) and not self.drop_flag: + self.drop_flag = v + del self.other[k] + + if k.lower() == "show_msg" and isinstance(v, str) and not self.show_msg: + self.show_msg = v + del self.other[k] + + if k.lower() == "dbname" and isinstance(v, str) and not self.dbname: + self.dbname = v + del self.other[k] + + if k.lower() == "show_oper" and isinstance(v, str) and not self.show_oper: + self.show_oper = v + del self.other[k] + + if k.lower() == "rollup_db" and isinstance(v, bool) and not self.rollup_db: + self.rollup_db = v + del self.other[k] + + + +# from ...pytest.util.sql import * +# from ...pytest.util.constant import * + +class TDTestCase: + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + self.precision = "ms" + self.sma_count = 0 + self.sma_created_index = [] + + def __create_sma_index(self, sma:BSMAschema): + if sma.create_tabel_sql: + sql = sma.create_tabel_sql + else: + sql = f"{sma.creation} {sma.tb_type} {sma.tbname} ({', '.join(sma.cols)}) " + + if sma.tb_type == "stable" or (sma.tb_type=="table" and sma.tags): + sql = f"{sma.creation} {sma.tb_type} {sma.tbname} ({', '.join(sma.cols)}) tags ({', '.join(sma.tags)}) " + + + if sma.sma_flag: + sql += sma.sma_flag + if sma.sma_cols: + sql += f"({', '.join(sma.sma_cols)})" + + if isinstance(sma.other, dict): + for k,v in sma.other.items(): + if isinstance(v,tuple) or isinstance(v, list): + sql += f" {k} ({' '.join(v)})" + else: + sql += f" {k} {v}" + if isinstance(sma.other, tuple) or isinstance(sma.other, list): + sql += " ".join(sma.other) + if isinstance(sma.other, int) or isinstance(sma.other, float) or isinstance(sma.other, str): + sql += f" {sma.other}" + + return sql + + def __get_bsma_table_col_tag_str(self, sql:str): + p = re.compile(r"[(](.*)[)]", re.S) + + if "tags" in (col_str := sql): + col_str = re.findall(p, sql.split("tags")[0])[0].split(",") + if (tag_str := re.findall(p, sql.split("tags")[1])[0].split(",") ): + col_str.extend(tag_str) + + return col_str + + def __get_bsma_col_tag_names(self, col_tags:list): + return [ col_tag.strip().split(" ")[0] for col_tag in col_tags ] + + @property + def __get_db_tbname(self): + tb_list = [] + tdSql.query("show tables") + for row in tdSql.queryResult: + tb_list.append(row[0]) + tdSql.query("show tables") + for row in tdSql.queryResult: + tb_list.append(row[0]) + + return tb_list + + def __bsma_create_check(self, sma:BSMAschema): + if not sma.creation: + return False + if not sma.create_tabel_sql and (not sma.tbname or not sma.tb_type or not sma.cols): + return False + if not sma.create_tabel_sql and (sma.tb_type == "stable" and not sma.tags): + return False + if not sma.sma_flag or not isinstance(sma.sma_flag, str) or sma.sma_flag.upper() != "SMA": + return False + if sma.tbname in self.__get_db_tbname: + return False + + if sma.create_tabel_sql: + col_tag_list = self.__get_bsma_col_tag_names(self.__get_bsma_table_col_tag_str(sma.create_tabel_sql)) + else: + col_str = list(sma.cols) + if sma.tags: + col_str.extend(list(sma.tags)) + col_tag_list = self.__get_bsma_col_tag_names(col_str) + if not sma.sma_cols: + return False + for col in sma.sma_cols: + if col not in col_tag_list: + return False + + return True + + def bsma_create_check(self, sma:BSMAschema): + if self.__bsma_create_check(sma): + tdSql.query(self.__create_sma_index(sma)) + tdLog.info(f"current sql: {self.__create_sma_index(sma)}") + + else: + tdSql.error(self.__create_sma_index(sma)) + + + def __sma_drop_check(self, sma:BSMAschema): + pass + + def sma_drop_check(self, sma:BSMAschema): + pass + + def __show_sma_index(self, sma:BSMAschema): + pass + + def __sma_show_check(self, sma:BSMAschema): + pass + + def sma_show_check(self, sma:BSMAschema): + pass + + @property + def __create_sma_sql(self): + err_sqls = [] + cur_sqls = [] + # err_set + ### case 1: required fields check + err_sqls.append( BSMAschema(creation="", tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_cols=(PRIMARY_COL, INT_COL ) ) ) + err_sqls.append( BSMAschema(tbname="", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_cols=(PRIMARY_COL, INT_COL ) ) ) + err_sqls.append( BSMAschema(tbname="stb2", cols=(), tags=(f"{INT_TAG} int",), sma_cols=(PRIMARY_COL, INT_COL ) ) ) + err_sqls.append( BSMAschema(tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(), sma_cols=(PRIMARY_COL, INT_COL ) ) ) + err_sqls.append( BSMAschema(tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_flag="", sma_cols=(PRIMARY_COL, INT_COL ) ) ) + err_sqls.append( BSMAschema(tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_cols=() ) ) + ### case 2: + err_sqls.append( BSMAschema(tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_cols=({BINT_COL}) ) ) + + # current_set + cur_sqls.append( BSMAschema(tbname="stb2", cols=(f"{PRIMARY_COL} timestamp", f"{INT_COL} int"), tags=(f"{INT_TAG} int",), sma_cols=(PRIMARY_COL, INT_COL ) ) ) + + return err_sqls, cur_sqls + + def test_create_sma(self): + err_sqls , cur_sqls = self.__create_sma_sql + for err_sql in err_sqls: + self.bsma_create_check(err_sql) + for cur_sql in cur_sqls: + self.bsma_create_check(cur_sql) + + @property + def __drop_sma_sql(self): + err_sqls = [] + cur_sqls = [] + # err_set + ## case 1: required fields check + return err_sqls, cur_sqls + + def test_drop_sma(self): + err_sqls , cur_sqls = self.__drop_sma_sql + for err_sql in err_sqls: + self.sma_drop_check(err_sql) + for cur_sql in cur_sqls: + self.sma_drop_check(cur_sql) + + def all_test(self): + self.test_create_sma() + + def __create_tb(self): + tdLog.printNoPrefix("==========step: create table") + create_stb_sql = f'''create table {STBNAME}( + ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, + {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, + {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp, + {TINT_UN_COL} tinyint unsigned, {SINT_UN_COL} smallint unsigned, + {INT_UN_COL} int unsigned, {BINT_UN_COL} bigint unsigned + ) tags ({INT_TAG} int) + ''' + create_ntb_sql = f'''create table {NTBNAME}( + ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, + {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, + {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp, + {TINT_UN_COL} tinyint unsigned, {SINT_UN_COL} smallint unsigned, + {INT_UN_COL} int unsigned, {BINT_UN_COL} bigint unsigned + ) + ''' + tdSql.execute(create_stb_sql) + tdSql.execute(create_ntb_sql) + + for i in range(4): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )') + + def __data_set(self, rows): + data_set = DataSet() + + for i in range(rows): + data_set.ts_data.append(NOW + 1 * (rows - i)) + data_set.int_data.append(rows - i) + data_set.bint_data.append(11111 * (rows - i)) + data_set.sint_data.append(111 * (rows - i) % 32767) + data_set.tint_data.append(11 * (rows - i) % 127) + data_set.int_un_data.append(rows - i) + data_set.bint_un_data.append(11111 * (rows - i)) + data_set.sint_un_data.append(111 * (rows - i) % 32767) + data_set.tint_un_data.append(11 * (rows - i) % 127) + data_set.float_data.append(1.11 * (rows - i)) + data_set.double_data.append(1100.0011 * (rows - i)) + data_set.bool_data.append((rows - i) % 2) + data_set.binary_data.append(f'binary{(rows - i)}') + data_set.nchar_data.append(f'nchar_测试_{(rows - i)}') + + return data_set + + def __insert_data(self): + tdLog.printNoPrefix("==========step: start inser data into tables now.....") + data = self.__data_set(rows=self.rows) + + # now_time = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + null_data = '''null, null, null, null, null, null, null, null, null, null, null, null, null, null''' + zero_data = "0, 0, 0, 0, 0, 0, 0, 'binary_0', 'nchar_0', 0, 0, 0, 0, 0" + + for i in range(self.rows): + row_data = f''' + {data.int_data[i]}, {data.bint_data[i]}, {data.sint_data[i]}, {data.tint_data[i]}, {data.float_data[i]}, {data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {data.tint_un_data[i]}, + {data.sint_un_data[i]}, {data.int_un_data[i]}, {data.bint_un_data[i]} + ''' + neg_row_data = f''' + {-1 * data.int_data[i]}, {-1 * data.bint_data[i]}, {-1 * data.sint_data[i]}, {-1 * data.tint_data[i]}, {-1 * data.float_data[i]}, {-1 * data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {1 * data.tint_un_data[i]}, + {1 * data.sint_un_data[i]}, {1 * data.int_un_data[i]}, {1 * data.bint_un_data[i]} + ''' + + tdSql.execute( + f"insert into ct1 values ( {NOW - i * TIME_STEP}, {row_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - i * int(TIME_STEP * 0.6)}, {neg_row_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - i * int(TIME_STEP * 0.8) }, {row_data} )") + tdSql.execute( + f"insert into {NTBNAME} values ( {NOW - i * int(TIME_STEP * 1.2)}, {row_data} )") + + tdSql.execute( + f"insert into ct2 values ( {NOW + int(TIME_STEP * 0.6)}, {null_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.6)}, {null_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - self.rows * int(TIME_STEP * 0.29) }, {null_data} )") + + tdSql.execute( + f"insert into ct4 values ( {NOW + int(TIME_STEP * 0.8)}, {null_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.8)}, {null_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - self.rows * int(TIME_STEP * 0.39)}, {null_data} )") + + tdSql.execute( + f"insert into {NTBNAME} values ( {NOW + int(TIME_STEP * 1.2)}, {null_data} )") + tdSql.execute( + f"insert into {NTBNAME} values ( {NOW - (self.rows + 1) * int(TIME_STEP * 1.2)}, {null_data} )") + tdSql.execute( + f"insert into {NTBNAME} values ( {NOW - self.rows * int(TIME_STEP * 0.59)}, {null_data} )") + + def run(self): + self.rows = 10 + + tdLog.printNoPrefix("==========step0:all check") + + tdLog.printNoPrefix("==========step1:create table in normal database") + tdSql.prepare() + self.__create_tb() + self.__insert_data() + self.all_test() + + # drop databases, create same name db、stb and sma index + tdSql.prepare() + self.__create_tb() + self.__insert_data() + self.all_test() + + tdLog.printNoPrefix("==========step2:create table in rollup database") + tdSql.execute("create database db3 retentions 1s:4m,2s:8m,3s:12m") + tdSql.execute("use db3") + tdSql.query(f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s max_delay 1m sma({INT_COL})") + + tdSql.execute("drop database if exists db1 ") + tdSql.execute("drop database if exists db2 ") + + tdDnodes.stop(1) + tdDnodes.start(1) + + tdLog.printNoPrefix("==========step4:after wal, all check again ") + tdSql.prepare() + self.__create_tb() + self.__insert_data() + self.all_test() + + # drop databases, create same name db、stb and sma index + tdSql.prepare() + self.__create_tb() + self.__insert_data() + self.all_test() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/1-insert/create_retentions.py b/tests/system-test/1-insert/create_retentions.py index 4b37eeb9a5..db902d0031 100644 --- a/tests/system-test/1-insert/create_retentions.py +++ b/tests/system-test/1-insert/create_retentions.py @@ -1,6 +1,6 @@ import datetime -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import List from util.log import * from util.sql import * @@ -36,36 +36,20 @@ NOW = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) @dataclass class DataSet: - ts_data : List[int] = None - int_data : List[int] = None - bint_data : List[int] = None - sint_data : List[int] = None - tint_data : List[int] = None - int_un_data : List[int] = None - bint_un_data : List[int] = None - sint_un_data : List[int] = None - tint_un_data : List[int] = None - float_data : List[float] = None - double_data : List[float] = None - bool_data : List[int] = None - binary_data : List[str] = None - nchar_data : List[str] = None - - def __post_init__(self): - self.ts_data = [] - self.int_data = [] - self.bint_data = [] - self.sint_data = [] - self.tint_data = [] - self.int_un_data = [] - self.bint_un_data = [] - self.sint_un_data = [] - self.tint_un_data = [] - self.float_data = [] - self.double_data = [] - self.bool_data = [] - self.binary_data = [] - self.nchar_data = [] + ts_data : List[int] = field(default_factory=list) + int_data : List[int] = field(default_factory=list) + bint_data : List[int] = field(default_factory=list) + sint_data : List[int] = field(default_factory=list) + tint_data : List[int] = field(default_factory=list) + int_un_data : List[int] = field(default_factory=list) + bint_un_data: List[int] = field(default_factory=list) + sint_un_data: List[int] = field(default_factory=list) + tint_un_data: List[int] = field(default_factory=list) + float_data : List[float] = field(default_factory=list) + double_data : List[float] = field(default_factory=list) + bool_data : List[int] = field(default_factory=list) + binary_data : List[str] = field(default_factory=list) + nchar_data : List[str] = field(default_factory=list) class TDTestCase: @@ -107,15 +91,15 @@ class TDTestCase: f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(count) watermark 1min", f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) max_delay -1s", f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark -1m", - # f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) watermark 1m ", - # f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) max_delay 1m ", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) watermark 1m ", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) max_delay 1m ", f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} binary(16)) tags (tag1 int) rollup(avg) watermark 1s", - f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) tags (tag1 int) rollup(avg) max_delay 1m", - # f"create table ntb_1 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) rollup(avg) watermark 1s max_delay 1s", - # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) tags (tag1 int) " , - # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) " , - # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) " , - # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) " , + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {NCHAR_COL} nchar(16)) tags (tag1 int) rollup(avg) max_delay 1m", + # f"create table ntb_1 ({PRIMARY_COL} timestamp, {INT_COL} int, {NCHAR_COL} nchar(16)) rollup(avg) watermark 1s max_delay 1s", + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {NCHAR_COL} nchar(16)) tags (tag1 int) " , + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) " , + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) " , + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) " , # watermark, max_delay: [0, 900000], [ms, s, m, ?] f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) max_delay 1u", @@ -136,8 +120,9 @@ class TDTestCase: f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark 5s max_delay 1m", f"create stable stb3 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(max) watermark 5s max_delay 1m", f"create stable stb4 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(sum) watermark 5s max_delay 1m", - # f"create stable stb5 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(last) watermark 5s max_delay 1m", - # f"create stable stb6 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s max_delay 1m", + f"create stable stb5 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(last) watermark 5s max_delay 1m", + f"create stable stb6 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s max_delay 1m", + f"create stable stb7 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s max_delay 1m sma({INT_COL})", ] def test_create_stb(self): @@ -150,7 +135,7 @@ class TDTestCase: # assert "rollup" in tdSql.description tdSql.checkRows(len(self.create_stable_sql_current)) - # tdSql.execute("use db") # because db is a noraml database, not a rollup database, should not be able to create a rollup database + tdSql.execute("use db") # because db is a noraml database, not a rollup database, should not be able to create a rollup stable # tdSql.error(f"create stable nor_db_rollup_stb ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) watermark 5s max_delay 1m") @@ -210,20 +195,6 @@ class TDTestCase: data_set.binary_data.append(f'binary{(rows - i)}') data_set.nchar_data.append(f'nchar_测试_{(rows - i)}') - # neg_data_set.ts_data.append(-1 * i) - # neg_data_set.int_data.append(-i) - # neg_data_set.bint_data.append(-11111 * i) - # neg_data_set.sint_data.append(-111 * i % 32767) - # neg_data_set.tint_data.append(-11 * i % 127) - # neg_data_set.int_un_data.append(-i) - # neg_data_set.bint_un_data.append(-11111 * i) - # neg_data_set.sint_un_data.append(-111 * i % 32767) - # neg_data_set.tint_un_data.append(-11 * i % 127) - # neg_data_set.float_data.append(-1.11 * i) - # neg_data_set.double_data.append(-1100.0011 * i) - # neg_data_set.binary_data.append(f'binary{i}') - # neg_data_set.nchar_data.append(f'nchar_测试_{i}') - return data_set def __insert_data(self): @@ -279,9 +250,14 @@ class TDTestCase: tdLog.printNoPrefix("==========step2:create table in rollup database") tdSql.execute("create database db3 retentions 1s:4m,2s:8m,3s:12m") + + tdSql.execute("drop database if exists db1 ") + tdSql.execute("drop database if exists db2 ") + tdSql.execute("use db3") - self.__create_tb() - self.__insert_data() + # self.__create_tb() + # self.__insert_data() + self.all_test() tdSql.execute("drop database if exists db1 ") tdSql.execute("drop database if exists db2 ") diff --git a/tests/system-test/1-insert/time_range_wise.py b/tests/system-test/1-insert/time_range_wise.py index d4434987a6..a620a4b51a 100644 --- a/tests/system-test/1-insert/time_range_wise.py +++ b/tests/system-test/1-insert/time_range_wise.py @@ -325,7 +325,7 @@ class TDTestCase: def __sma_create_check(self, sma:SMAschema): if self.updatecfgDict["querySmaOptimize"] == 0: return False - # # TODO: if database is a rollup-db, can not create sma index + # TODO: if database is a rollup-db, can not create sma index # tdSql.query("select database()") # if sma.rollup_db : # return False @@ -493,8 +493,8 @@ class TDTestCase: err_sqls , cur_sqls = self.__drop_sma_sql for err_sql in err_sqls: self.sma_drop_check(err_sql) - # for cur_sql in cur_sqls: - # self.sma_drop_check(cur_sql) + for cur_sql in cur_sqls: + self.sma_drop_check(cur_sql) def all_test(self): self.test_create_sma() @@ -605,24 +605,23 @@ class TDTestCase: tdLog.printNoPrefix("==========step1:create table in normal database") tdSql.prepare() self.__create_tb() - # self.__insert_data() + self.__insert_data() self.all_test() # drop databases, create same name db、stb and sma index - # tdSql.prepare() - # self.__create_tb() - # self.__insert_data() - # self.all_test() - - - - return + tdSql.prepare() + self.__create_tb() + self.__insert_data() + self.all_test() tdLog.printNoPrefix("==========step2:create table in rollup database") tdSql.execute("create database db3 retentions 1s:4m,2s:8m,3s:12m") tdSql.execute("use db3") - self.__create_tb() - self.__insert_data() + # self.__create_tb() + tdSql.execute(f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s max_delay 1m sma({INT_COL}) ") + self.all_test() + + # self.__insert_data() tdSql.execute("drop database if exists db1 ") tdSql.execute("drop database if exists db2 ") diff --git a/tests/system-test/2-query/abs.py b/tests/system-test/2-query/abs.py index 961a6446b5..90a1b8f343 100644 --- a/tests/system-test/2-query/abs.py +++ b/tests/system-test/2-query/abs.py @@ -139,7 +139,7 @@ class TDTestCase: ) for i in range(4): tdSql.execute( - f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_apercentile.py b/tests/system-test/2-query/distribute_agg_apercentile.py index fd1455ce16..022d13c5ae 100644 --- a/tests/system-test/2-query/distribute_agg_apercentile.py +++ b/tests/system-test/2-query/distribute_agg_apercentile.py @@ -36,7 +36,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_avg.py b/tests/system-test/2-query/distribute_agg_avg.py index 647a262558..c690a17b4a 100644 --- a/tests/system-test/2-query/distribute_agg_avg.py +++ b/tests/system-test/2-query/distribute_agg_avg.py @@ -53,7 +53,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_count.py b/tests/system-test/2-query/distribute_agg_count.py index 2ac9c86df0..b3638dac4b 100644 --- a/tests/system-test/2-query/distribute_agg_count.py +++ b/tests/system-test/2-query/distribute_agg_count.py @@ -55,7 +55,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_max.py b/tests/system-test/2-query/distribute_agg_max.py index 5c9760cbcf..0924ea16ac 100644 --- a/tests/system-test/2-query/distribute_agg_max.py +++ b/tests/system-test/2-query/distribute_agg_max.py @@ -55,7 +55,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_min.py b/tests/system-test/2-query/distribute_agg_min.py index dd20d88229..8d077fd59b 100644 --- a/tests/system-test/2-query/distribute_agg_min.py +++ b/tests/system-test/2-query/distribute_agg_min.py @@ -55,7 +55,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_spread.py b/tests/system-test/2-query/distribute_agg_spread.py index 94f1a61d77..c91fd1d30b 100644 --- a/tests/system-test/2-query/distribute_agg_spread.py +++ b/tests/system-test/2-query/distribute_agg_spread.py @@ -55,7 +55,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_stddev.py b/tests/system-test/2-query/distribute_agg_stddev.py index 5050e6e940..59ede38983 100644 --- a/tests/system-test/2-query/distribute_agg_stddev.py +++ b/tests/system-test/2-query/distribute_agg_stddev.py @@ -64,7 +64,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/distribute_agg_sum.py b/tests/system-test/2-query/distribute_agg_sum.py index add4d75c61..8dcd902b3d 100644 --- a/tests/system-test/2-query/distribute_agg_sum.py +++ b/tests/system-test/2-query/distribute_agg_sum.py @@ -53,7 +53,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/function_null.py b/tests/system-test/2-query/function_null.py index 4de7a7f113..545872b39d 100644 --- a/tests/system-test/2-query/function_null.py +++ b/tests/system-test/2-query/function_null.py @@ -42,7 +42,7 @@ class TDTestCase: ) for i in range(4): tdSql.execute( - f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/irate.py b/tests/system-test/2-query/irate.py index 238924d851..d0573a6bf4 100644 --- a/tests/system-test/2-query/irate.py +++ b/tests/system-test/2-query/irate.py @@ -97,7 +97,7 @@ class TDTestCase: ) for i in range(4): tdSql.execute( - f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/json_tag.py b/tests/system-test/2-query/json_tag.py index c18d1dab0e..84aab3d624 100644 --- a/tests/system-test/2-query/json_tag.py +++ b/tests/system-test/2-query/json_tag.py @@ -566,7 +566,7 @@ class TDTestCase: tdSql.checkRows(3) tdSql.query("select bottom(dataint,100) from jsons1 where jtag->'tag1'>1") tdSql.checkRows(3) - tdSql.query("select percentile(dataint,20) from jsons1 where jtag->'tag1'>1") + #tdSql.query("select percentile(dataint,20) from jsons1 where jtag->'tag1'>1") tdSql.query("select apercentile(dataint, 50) from jsons1 where jtag->'tag1'>1") tdSql.checkData(0, 0, 1.5) # tdSql.query("select last_row(dataint) from jsons1 where jtag->'tag1'>1") diff --git a/tests/system-test/2-query/max.py b/tests/system-test/2-query/max.py index 46426a5a95..3cd023648e 100644 --- a/tests/system-test/2-query/max.py +++ b/tests/system-test/2-query/max.py @@ -109,7 +109,7 @@ class TDTestCase: ''' ) for i in range(20): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') for i in range(9): tdSql.execute( diff --git a/tests/system-test/2-query/twa.py b/tests/system-test/2-query/twa.py index b400e503d9..9f0e189a5f 100644 --- a/tests/system-test/2-query/twa.py +++ b/tests/system-test/2-query/twa.py @@ -34,7 +34,7 @@ class TDTestCase: ) for i in range(self.tb_nums): - tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {1*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') ts = self.ts for j in range(self.row_nums): ts+=j*self.time_step diff --git a/tests/system-test/7-tmq/tmqConsFromTsdb-1ctb.py b/tests/system-test/7-tmq/tmqConsFromTsdb-1ctb.py new file mode 100644 index 0000000000..1d2aaccda5 --- /dev/null +++ b/tests/system-test/7-tmq/tmqConsFromTsdb-1ctb.py @@ -0,0 +1,263 @@ + +import taos +import sys +import time +import socket +import os +import threading +import math + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.vgroups = 1 + self.ctbNum = 1 + self.rowsPerTbl = 100000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdDnodes.stop(1) + tdDnodes.start(1) + return + + def tmqCase1(self): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 0 + expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + + if expectRowsList[0] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[0], resultList[0])) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + tmqCom.checkFileContent(consumerId, queryString) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self): + tdLog.printNoPrefix("======== test case 2: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + totalRowsInserted = expectRowsList[0] + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 1 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] / 3) + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 0") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + firstConsumeRows = resultList[0] + + if not (expectrowcnt <= resultList[0] and totalRowsInserted >= resultList[0]): + tdLog.info("act consume rows: %d, expect consume rows between %d and %d"%(resultList[0], expectrowcnt, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 2 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 1/3) + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 1") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + secondConsumeRows = resultList[0] + + if not (expectrowcnt <= resultList[0] and totalRowsInserted >= resultList[0]): + tdLog.info("act consume rows: %d, expect consume rows between %d and %d"%(resultList[0], expectrowcnt, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 3 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 1/3) + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 1") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + thirdConsumeRows = resultList[0] + + if not (totalRowsInserted >= resultList[0]): + tdLog.info("act consume rows: %d, expect consume rows between %d and %d"%(resultList[0], expectrowcnt, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + # total consume + actConsumeTotalRows = firstConsumeRows + secondConsumeRows + thirdConsumeRows + + if not (totalRowsInserted == actConsumeTotalRows): + tdLog.info("sum of two consume rows: %d should be equal to total inserted rows: %d"%(actConsumeTotalRows, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + self.tmqCase1() + self.tmqCase2() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmqConsFromTsdb1-1ctb.py b/tests/system-test/7-tmq/tmqConsFromTsdb1-1ctb.py new file mode 100644 index 0000000000..5cb373092b --- /dev/null +++ b/tests/system-test/7-tmq/tmqConsFromTsdb1-1ctb.py @@ -0,0 +1,241 @@ + +import taos +import sys +import time +import socket +import os +import threading +import math + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.vgroups = 1 + self.ctbNum = 1 + self.rowsPerTbl = 100000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdDnodes.stop(1) + tdDnodes.start(1) + return + + def tmqCase3(self): + tdLog.printNoPrefix("======== test case 3: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 15, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + totalRowsInserted = expectRowsList[0] + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 3 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] / 3) + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + consumerId = 4 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2/3) + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 0") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 2 + resultList = tmqCom.selectConsumeResult(expectRows) + actConsumeTotalRows = resultList[0] + resultList[1] + + if not (totalRowsInserted == actConsumeTotalRows): + tdLog.info("sum of two consume rows: %d should be equal to total inserted rows: %d"%(actConsumeTotalRows, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def tmqCase4(self): + tdLog.printNoPrefix("======== test case 4: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 10, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + totalRowsInserted = expectRowsList[0] + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 5 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"]) + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 0") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("wait commit notify") + tmqCom.getStartCommitNotifyFromTmqsim() + + tdLog.info("pkill consume processor") + tdCom.killProcessor("tmq_sim") + + # time.sleep(10) + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 6 + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 1") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + + actConsumeTotalRows = resultList[0] + + if not (actConsumeTotalRows > 0 and actConsumeTotalRows < totalRowsInserted): + tdLog.info("act consume rows: %d"%(actConsumeTotalRows)) + tdLog.info("and second consume rows should be between 0 and %d"%(totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 4 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + self.tmqCase3() + self.tmqCase4() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmqConsFromTsdb1-mutilVg.py b/tests/system-test/7-tmq/tmqConsFromTsdb1-mutilVg.py new file mode 100644 index 0000000000..dd8a0ad33a --- /dev/null +++ b/tests/system-test/7-tmq/tmqConsFromTsdb1-mutilVg.py @@ -0,0 +1,241 @@ + +import taos +import sys +import time +import socket +import os +import threading +import math + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.vgroups = 4 + self.ctbNum = 10 + self.rowsPerTbl = 10000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdDnodes.stop(1) + tdDnodes.start(1) + return + + def tmqCase3(self): + tdLog.printNoPrefix("======== test case 3: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 10, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + totalRowsInserted = expectRowsList[0] + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 3 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] / 3) + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + consumerId = 4 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2/3) + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 0") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 2 + resultList = tmqCom.selectConsumeResult(expectRows) + actConsumeTotalRows = resultList[0] + resultList[1] + + if not (totalRowsInserted == actConsumeTotalRows): + tdLog.info("sum of two consume rows: %d should be equal to total inserted rows: %d"%(actConsumeTotalRows, totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def tmqCase4(self): + tdLog.printNoPrefix("======== test case 4: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 1, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 10, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 1} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + topicNameList = ['topic1'] + expectRowsList = [] + tmqCom.initConsumerTable() + + tdLog.info("create topics from stb with filter") + queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + # sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + totalRowsInserted = expectRowsList[0] + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 5 + expectrowcnt = math.ceil(paraDict["rowsPerTbl"] * paraDict["ctbNum"]) + topicList = topicNameList[0] + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:1000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 0") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("wait commit notify") + tmqCom.getStartCommitNotifyFromTmqsim() + + tdLog.info("pkill consume processor") + tdCom.killProcessor("tmq_sim") + + # time.sleep(10) + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 6 + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor 1") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + tdLog.info("wait the consume result") + + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + + actConsumeTotalRows = resultList[0] + + if not (actConsumeTotalRows > 0 and actConsumeTotalRows < totalRowsInserted): + tdLog.info("act consume rows: %d"%(actConsumeTotalRows)) + tdLog.info("and second consume rows should be between 0 and %d"%(totalRowsInserted)) + tdLog.exit("%d tmq consume rows error!"%consumerId) + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 4 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + self.tmqCase3() + self.tmqCase4() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmqConsFromTsdb1.py b/tests/system-test/7-tmq/tmqConsFromTsdb1.py index af06c774d6..a183eda1c7 100644 --- a/tests/system-test/7-tmq/tmqConsFromTsdb1.py +++ b/tests/system-test/7-tmq/tmqConsFromTsdb1.py @@ -85,7 +85,7 @@ class TDTestCase: 'rowsPerTbl': 10000, 'batchNum': 10, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 10, + 'pollDelay': 15, 'showMsg': 1, 'showRow': 1, 'snapshot': 1} diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 8f5791f1c5..eb411b33fa 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -19,11 +19,15 @@ python3 ./test.py -f 1-insert/influxdb_line_taosc_insert.py python3 ./test.py -f 1-insert/opentsdb_telnet_line_taosc_insert.py python3 ./test.py -f 1-insert/opentsdb_json_taosc_insert.py python3 ./test.py -f 1-insert/test_stmt_muti_insert_query.py -python3 ./test.py -f 1-insert/test_stmt_set_tbname_tag.py +python3 ./test.py -f 1-insert/test_stmt_set_tbname_tag.py python3 ./test.py -f 1-insert/alter_stable.py python3 ./test.py -f 1-insert/alter_table.py python3 ./test.py -f 1-insert/insertWithMoreVgroup.py python3 ./test.py -f 1-insert/table_comment.py +python3 ./test.py -f 1-insert/time_range_wise.py +python3 ./test.py -f 1-insert/block_wise.py +python3 ./test.py -f 1-insert/create_retentions.py + #python3 ./test.py -f 1-insert/table_param_ttl.py python3 ./test.py -f 2-query/between.py python3 ./test.py -f 2-query/distinct.py @@ -114,19 +118,19 @@ python3 ./test.py -f 2-query/twa.py python3 ./test.py -f 2-query/irate.py python3 ./test.py -f 2-query/function_null.py -python3 ./test.py -f 2-query/queryQnode.py +python3 ./test.py -f 2-query/queryQnode.py -#python3 ./test.py -f 6-cluster/5dnode1mnode.py +#python3 ./test.py -f 6-cluster/5dnode1mnode.py #python3 ./test.py -f 6-cluster/5dnode2mnode.py -N 5 -M 3 #python3 ./test.py -f 6-cluster/5dnode3mnodeStop.py -N 5 -M 3 #python3 ./test.py -f 6-cluster/5dnode3mnodeStopLoop.py -N 5 -M 3 # BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopDnodeCreateDb.py -N 5 -M 3 -# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopMnodeCreateDb.py -N 5 -M 3 +# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopMnodeCreateDb.py -N 5 -M 3 python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopVnodeCreateDb.py -N 5 -M 3 -# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopDnodeCreateStb.py -N 5 -M 3 -# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopMnodeCreateStb.py -N 5 -M 3 +# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopDnodeCreateStb.py -N 5 -M 3 +# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopMnodeCreateStb.py -N 5 -M 3 # python3 ./test.py -f 6-cluster/5dnode3mnodeSep1VnodeStopVnodeCreateStb.py -N 5 -M 3 -# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeStopInsert.py +# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeStopInsert.py # python3 ./test.py -f 6-cluster/5dnode3mnodeDrop.py -N 5 # python3 test.py -f 6-cluster/5dnode3mnodeStopConnect.py -N 5 -M 3 @@ -158,3 +162,6 @@ python3 ./test.py -f 7-tmq/tmqAlterSchema.py python3 ./test.py -f 7-tmq/tmqConsFromTsdb.py python3 ./test.py -f 7-tmq/tmqConsFromTsdb1.py python3 ./test.py -f 7-tmq/tmqConsFromTsdb-mutilVg.py +python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-mutilVg.py +python3 ./test.py -f 7-tmq/tmqConsFromTsdb-1ctb.py +python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-1ctb.py