diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h
index b238bfa566..d571153c1a 100644
--- a/include/common/taosmsg.h
+++ b/include/common/taosmsg.h
@@ -706,41 +706,31 @@ typedef struct {
} SStatusRsp;
typedef struct {
- uint32_t vgId;
- int32_t dbCfgVersion;
- int32_t maxTables;
- int32_t cacheBlockSize;
- int32_t totalBlocks;
- int32_t daysPerFile;
- int32_t daysToKeep;
- int32_t daysToKeep1;
- int32_t daysToKeep2;
- int32_t minRowsPerFileBlock;
- int32_t maxRowsPerFileBlock;
- int32_t commitTime;
- int32_t fsyncPeriod;
- int8_t precision;
- int8_t compression;
- int8_t walLevel;
- int8_t vgReplica;
- int8_t wals;
- int8_t quorum;
- int8_t update;
- int8_t cacheLastRow;
- int32_t vgCfgVersion;
- int8_t dbReplica;
- int8_t dbType;
- int8_t reserved[8];
-} SVnodeCfg;
-
-typedef struct {
- int32_t nodeId;
- char nodeEp[TSDB_EP_LEN];
+ uint16_t port;
+ char fqdn[TSDB_FQDN_LEN];
} SVnodeDesc;
typedef struct {
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
- SVnodeCfg cfg;
+ uint32_t vgId;
+ int32_t cacheBlockSize;
+ int32_t totalBlocks;
+ int32_t daysPerFile;
+ int32_t daysToKeep0;
+ int32_t daysToKeep1;
+ int32_t daysToKeep2;
+ int32_t minRowsPerFileBlock;
+ int32_t maxRowsPerFileBlock;
+ int32_t fsyncPeriod;
+ int8_t reserved[16];
+ int8_t precision;
+ int8_t compression;
+ int8_t cacheLastRow;
+ int8_t update;
+ int8_t walLevel;
+ int8_t replica;
+ int8_t quorum;
+ int8_t selfIndex;
SVnodeDesc nodes[TSDB_MAX_REPLICA];
} SCreateVnodeMsg, SAlterVnodeMsg;
diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h
index 2eef9db064..a3de2452ac 100644
--- a/include/common/tdataformat.h
+++ b/include/common/tdataformat.h
@@ -308,7 +308,7 @@ static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSche
SET_DOUBLE_PTR(pData, value);
break;
case TSDB_DATA_TYPE_TIMESTAMP:
- if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
+ if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
*(TSKEY *)pData = tdGetKey(*(TKEY *)value);
} else {
*(TSKEY *)pData = *(TSKEY *)value;
diff --git a/include/common/ttime.h b/include/common/ttime.h
index 0d9b89b6f9..926d23c239 100644
--- a/include/common/ttime.h
+++ b/include/common/ttime.h
@@ -23,6 +23,8 @@ extern "C" {
#include "taosdef.h"
#include "taosmsg.h"
+#define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
+
/*
* @return timestamp decided by global conf variable, tsTimePrecision
* if precision == TSDB_TIME_PRECISION_MICRO, it returns timestamp in microsecond.
@@ -50,7 +52,6 @@ void deltaToUtcInitOnce();
int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision);
-
#ifdef __cplusplus
}
#endif
diff --git a/include/libs/function/function.h b/include/libs/function/function.h
index 8c290dbced..fecb2e87fc 100644
--- a/include/libs/function/function.h
+++ b/include/libs/function/function.h
@@ -13,8 +13,8 @@
* along with this program. If not, see .
*/
-#ifndef TDENGINE_TFUNCTION_H
-#define TDENGINE_TFUNCTION_H
+#ifndef TDENGINE_FUNCTION_H
+#define TDENGINE_FUNCTION_H
#ifdef __cplusplus
extern "C" {
@@ -24,6 +24,8 @@ extern "C" {
#include "tvariant.h"
#include "tbuffer.h"
+#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
+
#define FUNCTION_SCALAR 1
#define FUNCTION_AGG 2
@@ -184,6 +186,25 @@ typedef struct SResultDataInfo {
int32_t intermediateBytes;
} SResultDataInfo;
+
+typedef struct SMultiFunctionsDesc {
+ bool stableQuery;
+ bool groupbyColumn;
+ bool simpleAgg;
+ bool arithmeticOnAgg;
+ bool projectionQuery;
+ bool hasFilter;
+ bool onlyTagQuery;
+ bool orderProjectQuery;
+ bool stateWindow;
+ bool globalMerge;
+ bool multigroupResult;
+ bool blockDistribution;
+ bool timewindow;
+ bool topbotQuery;
+ bool interpQuery;
+} SMultiFunctionsDesc;
+
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
bool isSuperTable);
@@ -199,8 +220,10 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct
const char* qGetFunctionName(int32_t functionId);
+void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
+
#ifdef __cplusplus
}
#endif
-#endif // TDENGINE_TFUNCTION_H
+#endif // TDENGINE_FUNCTION_H
diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h
index b80eda0b86..262479ee4a 100644
--- a/include/libs/parser/parser.h
+++ b/include/libs/parser/parser.h
@@ -24,6 +24,7 @@ extern "C" {
#include "common.h"
#include "tname.h"
#include "tvariant.h"
+#include "function.h"
typedef struct SColumn {
uint64_t tableUid;
@@ -130,20 +131,6 @@ typedef struct STableMetaInfo {
SArray *tagColList; // SArray, involved tag columns
} STableMetaInfo;
-typedef struct SQueryAttrInfo {
- bool stableQuery;
- bool groupbyColumn;
- bool simpleAgg;
- bool arithmeticOnAgg;
- bool projectionQuery;
- bool hasFilter;
- bool onlyTagQuery;
- bool orderProjectQuery;
- bool stateWindow;
- bool globalMerge;
- bool multigroupResult;
-} SQueryAttrInfo;
-
typedef struct SQueryStmtInfo {
int16_t command; // the command may be different for each subclause, so keep it seperately.
uint32_t type; // query/insert type
@@ -177,7 +164,6 @@ typedef struct SQueryStmtInfo {
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
bool distinct; // distinct tag or not
- bool onlyHasTagCond;
int32_t bufLen;
char* buf;
SArray *pUdfInfo;
@@ -186,7 +172,7 @@ typedef struct SQueryStmtInfo {
SArray *pUpstream; // SArray
struct SQueryStmtInfo *pDownstream;
int32_t havingFieldNum;
- SQueryAttrInfo info;
+ SMultiFunctionsDesc info;
} SQueryStmtInfo;
typedef struct SColumnIndex {
diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h
index a0602ec1b0..9ffd74c229 100644
--- a/include/libs/sync/sync.h
+++ b/include/libs/sync/sync.h
@@ -22,11 +22,10 @@ extern "C" {
#include
#include "taosdef.h"
-#include "wal.h"
-typedef int64_t SyncNodeId;
-typedef int32_t SyncGroupId;
-typedef int64_t SyncIndex;
+typedef int32_t SyncNodeId;
+typedef int32_t SyncGroupId;
+typedef int64_t SyncIndex;
typedef uint64_t SSyncTerm;
typedef enum {
@@ -41,41 +40,42 @@ typedef struct {
} SSyncBuffer;
typedef struct {
- uint16_t nodePort; // node sync Port
- char nodeFqdn[TSDB_FQDN_LEN]; // node FQDN
+ SyncNodeId nodeId;
+ uint16_t nodePort; // node sync Port
+ char nodeFqdn[TSDB_FQDN_LEN]; // node FQDN
} SNodeInfo;
typedef struct {
- int selfIndex;
- int nNode;
- SNodeInfo* nodeInfo;
+ int32_t selfIndex;
+ int32_t replica;
+ SNodeInfo nodeInfo[TSDB_MAX_REPLICA];
} SSyncCluster;
typedef struct {
- int32_t selfIndex;
- int nNode;
- SNodeInfo* node;
- ESyncRole* role;
+ int32_t selfIndex;
+ int32_t replica;
+ SNodeInfo node[TSDB_MAX_REPLICA];
+ ESyncRole role[TSDB_MAX_REPLICA];
} SNodesRole;
typedef struct SSyncFSM {
void* pData;
// apply committed log, bufs will be free by raft module
- int (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData);
+ int32_t (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData);
// cluster commit callback
- int (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData);
+ int32_t (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData);
// fsm return snapshot in ppBuf, bufs will be free by raft module
// TODO: getSnapshot SHOULD be async?
- int (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int* objId, bool* isLast);
+ int32_t (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int32_t* objId, bool* isLast);
// fsm apply snapshot with pBuf data
- int (*applySnapshot)(struct SSyncFSM* fsm, SSyncBuffer* pBuf, int objId, bool isLast);
+ int32_t (*applySnapshot)(struct SSyncFSM* fsm, SSyncBuffer* pBuf, int32_t objId, bool isLast);
// call when restore snapshot and log done
- int (*onRestoreDone)(struct SSyncFSM* fsm);
+ int32_t (*onRestoreDone)(struct SSyncFSM* fsm);
void (*onRollback)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf);
@@ -83,52 +83,79 @@ typedef struct SSyncFSM {
} SSyncFSM;
+typedef struct SSyncLogStore {
+ void* pData;
+
+ // write log with given index
+ int32_t (*logWrite)(struct SSyncLogStore* logStore, SyncIndex index, SSyncBuffer* pBuf);
+
+ // mark log with given index has been commtted
+ int32_t (*logCommit)(struct SSyncLogStore* logStore, SyncIndex index);
+
+ // prune log before given index
+ int32_t (*logPrune)(struct SSyncLogStore* logStore, SyncIndex index);
+
+ // rollback log after given index
+ int32_t (*logRollback)(struct SSyncLogStore* logStore, SyncIndex index);
+} SSyncLogStore;
+
typedef struct SSyncServerState {
- SNodeInfo voteFor;
- SSyncTerm term;
+ SyncNodeId voteFor;
+ SSyncTerm term;
} SSyncServerState;
+typedef struct SSyncClusterConfig {
+ // Log index number of current cluster config.
+ SyncIndex index;
+
+ // Log index number of previous cluster config.
+ SyncIndex prevIndex;
+
+ // current cluster
+ const SSyncCluster* cluster;
+} SSyncClusterConfig;
+
typedef struct SStateManager {
void* pData;
- void (*saveServerState)(struct SStateManager* stateMng, const SSyncServerState* state);
+ int32_t (*saveServerState)(struct SStateManager* stateMng, SSyncServerState* state);
- const SSyncServerState* (*readServerState)(struct SStateManager* stateMng);
+ int32_t (*readServerState)(struct SStateManager* stateMng, SSyncServerState* state);
- void (*saveCluster)(struct SStateManager* stateMng, const SSyncCluster* cluster);
+ // void (*saveCluster)(struct SStateManager* stateMng, const SSyncClusterConfig* cluster);
- const SSyncCluster* (*readCluster)(struct SStateManager* stateMng);
+ // const SSyncClusterConfig* (*readCluster)(struct SStateManager* stateMng);
} SStateManager;
typedef struct {
- SyncGroupId vgId;
-
- twalh walHandle;
-
- SyncIndex snapshotIndex;
- SSyncCluster syncCfg;
-
- SSyncFSM fsm;
-
+ SyncGroupId vgId;
+ SyncIndex snapshotIndex;
+ SSyncCluster syncCfg;
+ SSyncFSM fsm;
+ SSyncLogStore logStore;
SStateManager stateManager;
} SSyncInfo;
+struct SSyncNode;
+typedef struct SSyncNode SSyncNode;
+
int32_t syncInit();
void syncCleanUp();
-SyncNodeId syncStart(const SSyncInfo*);
-void syncStop(SyncNodeId);
+SSyncNode* syncStart(const SSyncInfo*);
+void syncReconfig(const SSyncNode*, const SSyncCluster*);
+void syncStop(const SSyncNode*);
-int32_t syncPropose(SyncNodeId nodeId, SSyncBuffer buffer, void* pData, bool isWeak);
+int32_t syncPropose(SSyncNode* syncNode, SSyncBuffer buffer, void* pData, bool isWeak);
-int32_t syncAddNode(SyncNodeId nodeId, const SNodeInfo *pNode);
+// int32_t syncAddNode(SSyncNode syncNode, const SNodeInfo *pNode);
-int32_t syncRemoveNode(SyncNodeId nodeId, const SNodeInfo *pNode);
+// int32_t syncRemoveNode(SSyncNode syncNode, const SNodeInfo *pNode);
-extern int32_t syncDebugFlag;
+extern int32_t syncDebugFlag;
#ifdef __cplusplus
}
#endif
-#endif /*_TD_LIBS_SYNC_H*/
+#endif /*_TD_LIBS_SYNC_H*/
diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h
index 9a3310922d..143bdf0710 100644
--- a/include/libs/wal/wal.h
+++ b/include/libs/wal/wal.h
@@ -44,41 +44,41 @@ typedef struct {
EWalType walLevel; // wal level
} SWalCfg;
-typedef void * twalh; // WAL HANDLE
-typedef int32_t FWalWrite(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
+struct SWal;
+typedef struct SWal SWal; // WAL HANDLE
+typedef int32_t (*FWalWrite)(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
-//module initialization
-int32_t walInit();
-void walCleanUp();
+// module initialization
+int32_t walInit();
+void walCleanUp();
-//handle open and ctl
-twalh walOpen(char *path, SWalCfg *pCfg);
-int32_t walAlter(twalh, SWalCfg *pCfg);
-void walStop(twalh);
-void walClose(twalh);
+// handle open and ctl
+SWal *walOpen(char *path, SWalCfg *pCfg);
+int32_t walAlter(SWal *, SWalCfg *pCfg);
+void walClose(SWal *);
-//write
-//int64_t walWriteWithMsgType(twalh, int8_t msgType, void* body, int32_t bodyLen);
-int64_t walWrite(twalh, void* body, int32_t bodyLen);
-int64_t walWriteBatch(twalh, void** bodies, int32_t* bodyLen, int32_t batchSize);
+// write
+// int64_t walWriteWithMsgType(SWal*, int8_t msgType, void* body, int32_t bodyLen);
+int64_t walWrite(SWal *, int64_t index, void *body, int32_t bodyLen);
+int64_t walWriteBatch(SWal *, void **bodies, int32_t *bodyLen, int32_t batchSize);
-//apis for lifecycle management
-void walFsync(twalh, bool force);
-int32_t walCommit(twalh, int64_t ver);
-//truncate after
-int32_t walRollback(twalh, int64_t ver);
-//notify that previous log can be pruned safely
-int32_t walPrune(twalh, int64_t ver);
+// apis for lifecycle management
+void walFsync(SWal *, bool force);
+int32_t walCommit(SWal *, int64_t ver);
+// truncate after
+int32_t walRollback(SWal *, int64_t ver);
+// notify that previous log can be pruned safely
+int32_t walPrune(SWal *, int64_t ver);
-//read
-int32_t walRead(twalh, SWalHead **, int64_t ver);
-int32_t walReadWithFp(twalh, FWalWrite writeFp, int64_t verStart, int readNum);
+// read
+int32_t walRead(SWal *, SWalHead **, int64_t ver);
+int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum);
-//lifecycle check
-int32_t walFirstVer(twalh);
-int32_t walPersistedVer(twalh);
-int32_t walLastVer(twalh);
-//int32_t walDataCorrupted(twalh);
+// lifecycle check
+int32_t walFirstVer(SWal *);
+int32_t walPersistedVer(SWal *);
+int32_t walLastVer(SWal *);
+// int32_t walDataCorrupted(SWal*);
#ifdef __cplusplus
}
diff --git a/include/server/dnode/dnode.h b/include/server/dnode/dnode.h
index 3499913afa..bc0d1e89b0 100644
--- a/include/server/dnode/dnode.h
+++ b/include/server/dnode/dnode.h
@@ -67,6 +67,11 @@ void dnodeSendRedirectMsg(struct SRpcMsg *rpcMsg, bool forShell);
*/
void dnodeGetEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
+/**
+ * Report the startup progress.
+ */
+void dnodeReportStartup(char *name, char *desc);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/server/vnode/vnode.h b/include/server/vnode/vnode.h
index 00decfe338..ecb1412b06 100644
--- a/include/server/vnode/vnode.h
+++ b/include/server/vnode/vnode.h
@@ -46,6 +46,11 @@ typedef struct {
*/
void (*GetDnodeEp)(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
+ /**
+ * Report the startup progress.
+ */
+ void (*ReportStartup)(char *name, char *desc);
+
} SVnodeFp;
typedef struct {
diff --git a/include/util/taoserror.h b/include/util/taoserror.h
index cf8cd510c5..76c5f575a5 100644
--- a/include/util/taoserror.h
+++ b/include/util/taoserror.h
@@ -233,11 +233,11 @@ int32_t* taosGetErrno();
#define TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR TAOS_DEF_ERROR_CODE(0, 0x0507) //"Missing data file")
#define TSDB_CODE_VND_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0508) //"Out of memory")
#define TSDB_CODE_VND_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0509) //"Unexpected generic error in vnode")
-#define TSDB_CODE_VND_INVALID_VRESION_FILE TAOS_DEF_ERROR_CODE(0, 0x050A) //"Invalid version file")
-#define TSDB_CODE_VND_IS_FULL TAOS_DEF_ERROR_CODE(0, 0x050B) //"Database memory is full for commit failed")
-#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit")
+#define TSDB_CODE_VND_INVALID_CFG_FILE TAOS_DEF_ERROR_CODE(0, 0x050A) //"Invalid config file)
+#define TSDB_CODE_VND_INVALID_TERM_FILE TAOS_DEF_ERROR_CODE(0, 0x050B) //"Invalid term file")
+#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full")
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
-#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing")
+#define TSDB_CODE_VND_IS_UPDATING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is updating")
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing")
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
diff --git a/include/util/tdef.h b/include/util/tdef.h
index 21a70c9d91..80cd3cf8b8 100644
--- a/include/util/tdef.h
+++ b/include/util/tdef.h
@@ -303,7 +303,7 @@ do { \
#define TSDB_MAX_FIELD_LEN 16384
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
-#define PRIMARYKEY_TIMESTAMP_COL_INDEX 0
+#define PRIMARYKEY_TIMESTAMP_COL_ID 0
#define TSDB_MAX_RPC_THREADS 5
@@ -382,6 +382,9 @@ do { \
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
+enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED };
+enum { TRANS_OPER_INIT = 0, TRANS_OPER_EXECUTE, TRANS_OPER_ROLLBACK };
+
#ifdef __cplusplus
}
#endif
diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c
index 2686dcd205..6c795bb0cc 100644
--- a/source/common/src/ttime.c
+++ b/source/common/src/ttime.c
@@ -48,7 +48,7 @@
* An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
* tomorrow - (allowable under ISO 8601) is supported.
*/
-int64_t user_mktime64(const unsigned int year0, const unsigned int mon0,
+static int64_t user_mktime64(const unsigned int year0, const unsigned int mon0,
const unsigned int day, const unsigned int hour,
const unsigned int min, const unsigned int sec, int64_t time_zone)
{
@@ -79,19 +79,18 @@ void deltaToUtcInitOnce() {
(void)strptime("1970-01-01 00:00:00", (const char *)("%Y-%m-%d %H:%M:%S"), &tm);
m_deltaUtc = (int64_t)mktime(&tm);
//printf("====delta:%lld\n\n", seconds);
- return;
}
static int64_t parseFraction(char* str, char** end, int32_t timePrec);
static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec);
-static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec);
+static int32_t parseLocaltimeDst(char* timestr, int64_t* time, int32_t timePrec);
static char* forwardToTimeStringEnd(char* str);
static bool checkTzPresent(char *str, int32_t len);
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = {
parseLocaltime,
- parseLocaltimeWithDst
+ parseLocaltimeDst
};
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
@@ -116,8 +115,8 @@ bool checkTzPresent(char *str, int32_t len) {
}
c--;
}
- return false;
+ return false;
}
char* forwardToTimeStringEnd(char* str) {
@@ -344,7 +343,7 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) {
return 0;
}
-int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec) {
+int32_t parseLocaltimeDst(char* timestr, int64_t* time, int32_t timePrec) {
*time = 0;
struct tm tm = {0};
tm.tm_isdst = -1;
diff --git a/source/libs/function/CMakeLists.txt b/source/libs/function/CMakeLists.txt
index 9fbfc82e3c..a4aa7025e4 100644
--- a/source/libs/function/CMakeLists.txt
+++ b/source/libs/function/CMakeLists.txt
@@ -7,6 +7,6 @@ target_include_directories(
)
target_link_libraries(
- function
- PRIVATE os util common
+ function
+ PRIVATE os util common
)
\ No newline at end of file
diff --git a/source/libs/function/inc/taggfunction.h b/source/libs/function/inc/taggfunction.h
index 0ebba4cd8e..c5e7ea12a5 100644
--- a/source/libs/function/inc/taggfunction.h
+++ b/source/libs/function/inc/taggfunction.h
@@ -56,8 +56,6 @@ typedef struct SResultRowCellInfo {
#define QUERY_DESC_FORWARD_STEP -1
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
-
-#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
#define TOP_BOTTOM_QUERY_LIMIT 100
enum {
diff --git a/source/libs/function/src/taggfunction.c b/source/libs/function/src/taggfunction.c
index c130e6244b..c8585a7b64 100644
--- a/source/libs/function/src/taggfunction.c
+++ b/source/libs/function/src/taggfunction.c
@@ -513,7 +513,7 @@ static void count_func_merge(SQLFunctionCtx *pCtx) {
* @return
*/
int32_t countRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
- if (colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
+ if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
return BLK_DATA_NO_NEEDED;
} else {
return BLK_DATA_STATIS_NEEDED;
@@ -2303,10 +2303,10 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
tValuePair **tvp = pRes->res;
// user specify the order of output by sort the result according to timestamp
- if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
+ if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_ID) {
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
- } else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX)*/ {
+ } else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_ID)*/ {
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
}
diff --git a/source/libs/function/src/texpr.c b/source/libs/function/src/texpr.c
index 32fe3d2912..cfddb81683 100644
--- a/source/libs/function/src/texpr.c
+++ b/source/libs/function/src/texpr.c
@@ -128,18 +128,26 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
if (*pExpr == NULL) {
return;
}
-
- if ((*pExpr)->nodeType == TEXPR_BINARYEXPR_NODE) {
+
+ int32_t type = (*pExpr)->nodeType;
+ if (type == TEXPR_BINARYEXPR_NODE) {
doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
doExprTreeDestroy(&(*pExpr)->_node.pRight, fp);
if (fp != NULL) {
fp((*pExpr)->_node.info);
}
- } else if ((*pExpr)->nodeType == TEXPR_VALUE_NODE) {
+ } else if (type == TEXPR_UNARYEXPR_NODE) {
+ doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
+ if (fp != NULL) {
+ fp((*pExpr)->_node.info);
+ }
+
+ assert((*pExpr)->_node.pRight == NULL);
+ } else if (type == TEXPR_VALUE_NODE) {
taosVariantDestroy((*pExpr)->pVal);
free((*pExpr)->pVal);
- } else if ((*pExpr)->nodeType == TEXPR_COL_NODE) {
+ } else if (type == TEXPR_COL_NODE) {
free((*pExpr)->pSchema);
}
diff --git a/source/libs/function/src/tfunction.c b/source/libs/function/src/tfunction.c
index 7154c48d2a..0136bbf493 100644
--- a/source/libs/function/src/tfunction.c
+++ b/source/libs/function/src/tfunction.c
@@ -52,7 +52,7 @@ bool isTagsQuery(SArray* pFunctionIdList) {
int16_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
// "select count(tbname)" query
-// if (functId == FUNCTION_COUNT && pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
+// if (functId == FUNCTION_COUNT && pExpr->base.colpDesc->colId == TSDB_TBNAME_COLUMN_INDEX) {
// continue;
// }
@@ -80,19 +80,6 @@ bool isTagsQuery(SArray* pFunctionIdList) {
// return false;
//}
-bool isBlockInfoQuery(SArray* pFunctionIdList) {
- int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
- for (int32_t i = 0; i < num; ++i) {
- int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
-
- if (f == FUNCTION_BLKINFO) {
- return true;
- }
- }
-
- return false;
-}
-
bool isProjectionQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) {
@@ -101,8 +88,12 @@ bool isProjectionQuery(SArray* pFunctionIdList) {
continue;
}
- if (f != FUNCTION_PRJ && f != FUNCTION_TAGPRJ && f != FUNCTION_TAG &&
- f != FUNCTION_TS && f != FUNCTION_ARITHM && f != FUNCTION_DIFF &&
+ if (f != FUNCTION_PRJ &&
+ f != FUNCTION_TAGPRJ &&
+ f != FUNCTION_TAG &&
+ f != FUNCTION_TS &&
+ f != FUNCTION_ARITHM &&
+ f != FUNCTION_DIFF &&
f != FUNCTION_DERIVATIVE) {
return false;
}
@@ -111,7 +102,7 @@ bool isProjectionQuery(SArray* pFunctionIdList) {
return true;
}
-bool isDiffDerivQuery(SArray* pFunctionIdList) {
+bool isDiffDerivativeQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
@@ -127,7 +118,7 @@ bool isDiffDerivQuery(SArray* pFunctionIdList) {
return false;
}
-bool isPointInterpQuery(SArray* pFunctionIdList) {
+bool isInterpQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
@@ -264,8 +255,6 @@ bool needReverseScan(SArray* pFunctionIdList) {
}
bool isSimpleAggregateRv(SArray* pFunctionIdList) {
- assert(0);
-
// if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) {
// return false;
// }
@@ -380,33 +369,17 @@ bool isProjectionQueryOnSTable(SArray* pFunctionIdList, int32_t tableIndex) {
}
bool hasTagValOutput(SArray* pFunctionIdList) {
-// size_t numOfExprs = getNumOfExprs(pQueryInfo);
-// SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0);
-//
-// if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) {
+ size_t size = taosArrayGetSize(pFunctionIdList);
+
+ // if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) {
// return true;
-// }
-//
-// for (int32_t i = 0; i < numOfExprs; ++i) {
-// SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
-// if (pExpr == NULL) {
-// continue;
-// }
-//
-// // ts_comp column required the tag value for join filter
-// if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) {
-// return true;
-// }
// }
- return false;
-}
+ for (int32_t i = 0; i < size; ++i) {
+ int32_t functionId = *(int16_t*) taosArrayGet(pFunctionIdList, i);
-bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
- int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
- for (int32_t i = 0; i < num; ++i) {
- int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
- if (f == FUNCTION_TWA || f == FUNCTION_INTERP) {
+ // ts_comp column required the tag value for join filter
+ if (functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
return true;
}
}
@@ -414,8 +387,28 @@ bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
return false;
}
-//SQueryAttrInfo setQueryType(SArray* pFunctionIdList) {
-// assert(pFunctionIdList != NULL);
+//bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
+// int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
+// for (int32_t i = 0; i < num; ++i) {
+// int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
+// if (f == FUNCTION_TWA || f == FUNCTION_INTERP) {
+// return true;
+// }
+// }
//
-//
-//}
\ No newline at end of file
+// return false;
+//}
+
+void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc) {
+ assert(pFunctionIdList != NULL);
+
+
+ pDesc->blockDistribution = isBlockDistQuery(pFunctionIdList);
+ if (pDesc->blockDistribution) {
+ return;
+ }
+
+ pDesc->projectionQuery = isProjectionQuery(pFunctionIdList);
+ pDesc->onlyTagQuery = isTagsQuery(pFunctionIdList);
+ pDesc->interpQuery = isInterpQuery(pFunctionIdList);
+}
diff --git a/source/libs/parser/inc/astGenerator.h b/source/libs/parser/inc/astGenerator.h
index f7c7b9d6cc..829112baf3 100644
--- a/source/libs/parser/inc/astGenerator.h
+++ b/source/libs/parser/inc/astGenerator.h
@@ -298,7 +298,7 @@ void* destroyCreateTableSql(SCreateTableSql* pCreate);
void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken);
void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPath, SField *output, SToken* bufSize, int32_t funcType);
-void SqlInfoDestroy(SSqlInfo *pInfo);
+void destroySqlInfo(SSqlInfo *pInfo);
void setDCLSqlElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...);
void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken, SToken* existsCheck,int16_t dbType,int16_t tableType);
diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h
index 27c9140bcd..ca02165382 100644
--- a/source/libs/parser/inc/parserInt.h
+++ b/source/libs/parser/inc/parserInt.h
@@ -73,7 +73,9 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
-void initQueryInfo(SQueryStmtInfo* pQueryInfo);
+SQueryStmtInfo* createQueryInfo();
+
+void destroyQueryInfo(SQueryStmtInfo* pQueryInfo);
int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
@@ -87,6 +89,12 @@ int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
*/
int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen);
+/**
+ * Destroy the meta data request structure.
+ * @param pMetaInfo
+ */
+void qParserClearupMetaRequestInfo(SMetaReq* pMetaInfo);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/libs/parser/inc/queryInfoUtil.h b/source/libs/parser/inc/queryInfoUtil.h
index f1515189b7..fc892762cd 100644
--- a/source/libs/parser/inc/queryInfoUtil.h
+++ b/source/libs/parser/inc/queryInfoUtil.h
@@ -30,9 +30,7 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta);
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
-//SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
-void destroyExprInfoList();
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
@@ -42,9 +40,11 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
+int32_t getExprFunctionId(SExprInfo *pExprInfo);
void cleanupFieldInfo(SFieldInfo* pFieldInfo);
STableComInfo getTableInfo(const STableMeta* pTableMeta);
+SArray* extractFunctionIdList(SArray* pExprInfoList);
#ifdef __cplusplus
}
diff --git a/source/libs/parser/src/astGenerator.c b/source/libs/parser/src/astGenerator.c
index e9517758d1..6228212c4b 100644
--- a/source/libs/parser/src/astGenerator.c
+++ b/source/libs/parser/src/astGenerator.c
@@ -242,7 +242,6 @@ tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) {
}
void tSqlExprCompact(tSqlExpr **pExpr) {
-
if (*pExpr == NULL || tSqlExprIsParentOfLeaf(*pExpr)) {
return;
}
@@ -770,8 +769,11 @@ void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPa
}
}
-void SqlInfoDestroy(SSqlInfo *pInfo) {
- if (pInfo == NULL) return;;
+void destroySqlInfo(SSqlInfo *pInfo) {
+ if (pInfo == NULL) {
+ return;
+ }
+
taosArrayDestroy(pInfo->funcs);
if (pInfo->type == TSDB_SQL_SELECT) {
destroyAllSqlNode(pInfo->list);
diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c
index 9d5ee21f72..aaecf5c8a5 100644
--- a/source/libs/parser/src/astValidate.c
+++ b/source/libs/parser/src/astValidate.c
@@ -14,6 +14,7 @@
*/
#include
+#include
#include "astGenerator.h"
#include "function.h"
#include "parserInt.h"
@@ -28,6 +29,8 @@
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
#define VALID_COLUMN_INDEX(index) (((index).tableIndex >= 0) && ((index).columnIndex >= TSDB_TBNAME_COLUMN_INDEX))
+#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
+
// -1 is tbname column index, so here use the -2 as the initial value
#define COLUMN_INDEX_INITIAL_VAL (-2)
#define COLUMN_INDEX_INITIALIZER { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL }
@@ -213,7 +216,9 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) {
return meta;
}
-void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
+SQueryStmtInfo *createQueryInfo() {
+ SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo));
+
pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField));
pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
@@ -225,6 +230,58 @@ void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
pQueryInfo->slimit.offset = 0;
pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->window = TSWINDOW_INITIALIZER;
+
+ return pQueryInfo;
+}
+
+static void destroyQueryInfoImpl(SQueryStmtInfo* pQueryInfo) {
+ cleanupTagCond(&pQueryInfo->tagCond);
+ cleanupColumnCond(&pQueryInfo->colCond);
+ cleanupFieldInfo(&pQueryInfo->fieldsInfo);
+
+ dropAllExprInfo(pQueryInfo->exprList);
+ pQueryInfo->exprList = NULL;
+
+ if (pQueryInfo->exprList1 != NULL) {
+ dropAllExprInfo(pQueryInfo->exprList1);
+ pQueryInfo->exprList1 = NULL;
+ }
+
+ columnListDestroy(pQueryInfo->colList);
+ pQueryInfo->colList = NULL;
+
+ if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
+ taosArrayDestroy(pQueryInfo->groupbyExpr.columnInfo);
+ pQueryInfo->groupbyExpr.columnInfo = NULL;
+ }
+
+ pQueryInfo->fillType = 0;
+
+ tfree(pQueryInfo->fillVal);
+ tfree(pQueryInfo->buf);
+
+ taosArrayDestroy(pQueryInfo->pUpstream);
+ pQueryInfo->pUpstream = NULL;
+ pQueryInfo->bufLen = 0;
+}
+
+void destroyQueryInfo(SQueryStmtInfo* pQueryInfo) {
+ while (pQueryInfo != NULL) {
+ SQueryStmtInfo* p = pQueryInfo->sibling;
+
+ size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pUpstream);
+ for (int32_t i = 0; i < numOfUpstream; ++i) {
+ SQueryStmtInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pUpstream, i);
+ destroyQueryInfoImpl(pUpQueryInfo);
+ clearAllTableMetaInfo(pUpQueryInfo, false, 0);
+ tfree(pUpQueryInfo);
+ }
+
+ destroyQueryInfoImpl(pQueryInfo);
+ clearAllTableMetaInfo(pQueryInfo, false, 0);
+ tfree(pQueryInfo);
+ pQueryInfo = p;
+ }
}
static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
@@ -236,8 +293,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI
return buildInvalidOperationMsg(pMsgBuf, "not support union in subquery");
}
- SQueryStmtInfo* pSub = calloc(1, sizeof(SQueryStmtInfo));
- initQueryInfo(pSub);
+ SQueryStmtInfo* pSub = createQueryInfo();
SArray *pUdfInfo = NULL;
if (pQueryInfo->pUdfInfo) {
@@ -391,9 +447,9 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu
pIndex->type = TSDB_COL_TAG;
} else if (strlen(DEFAULT_PRIMARY_TIMESTAMP_COL_NAME) == pToken->n &&
strncasecmp(pToken->z, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME, pToken->n) == 0) {
- pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest
+ pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_ID; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest
} else if (pToken->n == 0) {
- pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest
+ pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_ID; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest
} else {
// not specify the table name, try to locate the table index by column name
if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) {
@@ -458,39 +514,32 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
- SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
+ SGroupbyExpr* pGroupExpr = &(pQueryInfo->groupbyExpr);
+ pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
if (pGroupExpr->columnInfo == NULL) {
- pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
- }
-
- if (pQueryInfo->colList == NULL) {
- pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
- }
-
- if (pGroupExpr->columnInfo == NULL || pQueryInfo->colList == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- int32_t numOfGroupCols = (int16_t) taosArrayGetSize(pList);
- if (numOfGroupCols > TSDB_MAX_TAGS) {
+ size_t num = taosArrayGetSize(pList);
+ if (num > TSDB_MAX_TAGS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
- SSchema *pSchema = NULL;
- int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
+ int32_t numOfGroupbyCols = 0;
+ SSchema *pSchema = NULL;
+ int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
- size_t num = taosArrayGetSize(pList);
for (int32_t i = 0; i < num; ++i) {
SListItem * pItem = taosArrayGet(pList, i);
SVariant* pVar = &pItem->pVar;
- SToken token = {pVar->nLen, pVar->nType, pVar->pz};
-
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ SToken token = {pVar->nLen, pVar->nType, pVar->pz};
if (getColumnIndexByName(&token, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
+ // Group by multiple tables is not supported.
if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
tableIndex = index.tableIndex;
} else if (tableIndex != index.tableIndex) {
@@ -506,9 +555,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
pSchema = getOneColumnSchema(pTableMeta, index.columnIndex);
}
- int32_t numOfCols = getNumOfColumns(pTableMeta);
- bool groupTag = (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols);
-
+ bool groupTag = TSDB_COL_IS_TAG(index.type);
if (groupTag) {
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
@@ -516,7 +563,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
int32_t relIndex = index.columnIndex;
if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
- relIndex -= numOfCols;
+ relIndex -= getNumOfColumns(pTableMeta);
}
SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, };
@@ -527,7 +574,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema);
} else {
// check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
- if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
+ if (pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
@@ -537,14 +584,15 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name));
taosArrayPush(pGroupExpr->columnInfo, &colIndex);
- pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
- numOfGroupCols++;
+
+ numOfGroupbyCols++;
+ pQueryInfo->info.groupbyColumn = true;
}
}
// 1. only one normal column allowed in the group by clause
- // 2. the normal column in the group by clause can only located in the end position
- if (numOfGroupCols > 1) {
+ // 2. the normal column in the group by clause can only located at the end position
+ if (numOfGroupbyCols > 1) {
return buildInvalidOperationMsg(pMsgBuf, msg7);
}
@@ -555,7 +603,8 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
}
}
- pQueryInfo->groupbyExpr.tableIndex = tableIndex;
+ pGroupExpr->orderType = TSDB_ORDER_ASC;
+ pGroupExpr->tableIndex = tableIndex;
return TSDB_CODE_SUCCESS;
}
@@ -589,18 +638,249 @@ int32_t validateWhereNode(SQueryStmtInfo *pQueryInfo, tSqlExpr* pWhereExpr, SMsg
return 0;
}
-// validate the interval info
-int32_t validateIntervalNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
- return 0;
+static int32_t parseIntervalOffset(SQueryStmtInfo* pQueryInfo, SToken* offsetToken, int32_t precision, SMsgBuf* pMsgBuf) {
+ const char* msg1 = "interval offset cannot be negative";
+ const char* msg2 = "interval offset should be shorter than interval";
+ const char* msg3 = "cannot use 'year' as offset when interval is 'month'";
+
+ SToken* t = offsetToken;
+ if (t->n == 0) {
+ pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
+ pQueryInfo->interval.offset = 0;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit, precision) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
+ if (pQueryInfo->interval.offset < 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.offsetUnit)) {
+ if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.intervalUnit)) {
+ if (pQueryInfo->interval.offset > pQueryInfo->interval.interval) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+ }
+ } else if (pQueryInfo->interval.offsetUnit == pQueryInfo->interval.intervalUnit) {
+ if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+ } else if (pQueryInfo->interval.intervalUnit == 'n' && pQueryInfo->interval.offsetUnit == 'y') {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ } else if (pQueryInfo->interval.intervalUnit == 'y' && pQueryInfo->interval.offsetUnit == 'n') {
+ if (pQueryInfo->interval.interval * 12 <= pQueryInfo->interval.offset) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+ } else {
+ // TODO: offset should be shorter than interval, but how to check
+ // conflicts like 30days offset and 1 month interval
+ }
+
+ return TSDB_CODE_SUCCESS;
}
-int32_t validateSessionNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
- return 0;
+static int32_t parseSlidingClause(SQueryStmtInfo* pQueryInfo, SToken* pSliding, int32_t precision, SMsgBuf* pMsgBuf) {
+ const char* msg1 = "sliding value no larger than the interval value";
+ const char* msg2 = "sliding value can not less than 1% of interval value";
+ const char* msg3 = "does not support sliding when interval is natural month/year";
+ const char* msg4 = "sliding value too small";
+
+ const static int32_t INTERVAL_SLIDING_FACTOR = 100;
+
+ SInterval* pInterval = &pQueryInfo->interval;
+ if (pSliding->n == 0) {
+ pInterval->slidingUnit = pInterval->intervalUnit;
+ pInterval->sliding = pInterval->interval;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ if (TIME_IS_VAR_DURATION(pInterval->intervalUnit)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ parseAbsoluteDuration(pSliding->z, pSliding->n, &pInterval->sliding, &pInterval->slidingUnit, precision);
+
+ // less than the threshold
+ if (pInterval->sliding < convertTimePrecision(tsMinSlidingTime, TSDB_TIME_PRECISION_MILLI, precision)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ if (pInterval->sliding > pInterval->interval) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ if ((pInterval->interval != 0) && (pInterval->interval/pInterval->sliding > INTERVAL_SLIDING_FACTOR)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+// validate the interval info
+int32_t validateIntervalNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
+ const char* msg1 = "sliding cannot be used without interval";
+ const char* msg2 = "only point interpolation query requires keyword EVERY";
+ const char* msg3 = "interval value is too small";
+
+ STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
+ STableComInfo tinfo = getTableInfo(pTableMetaInfo->pTableMeta);
+
+ if (!TPARSER_HAS_TOKEN(pSqlNode->interval.interval)) {
+ if (TPARSER_HAS_TOKEN(pSqlNode->sliding)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ } else {
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+
+ // orderby column not set yet, set it to be the primary timestamp column
+ if (pQueryInfo->order.orderColId == INT32_MIN) {
+ pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_ID;
+ }
+
+ // interval is not null
+ SToken *t = &pSqlNode->interval.interval;
+ if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval,
+ &pQueryInfo->interval.intervalUnit, tinfo.precision) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
+ if (pQueryInfo->interval.interval <= 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.intervalUnit)) {
+ // interval cannot be less than 10 milliseconds
+ if (convertTimePrecision(pQueryInfo->interval.interval, tinfo.precision, TSDB_TIME_PRECISION_MICRO) < tsMinIntervalTime) {
+ char msg[50] = {0};
+ snprintf(msg, 50, "interval time window can not be less than %d %s", tsMinIntervalTime, TSDB_TIME_PRECISION_MICRO_STR);
+ return buildInvalidOperationMsg(pMsgBuf, msg);
+ }
+ }
+
+ if (parseIntervalOffset(pQueryInfo, &pSqlNode->interval.offset, tinfo.precision, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
+ if (parseSlidingClause(pQueryInfo, &pSqlNode->sliding, tinfo.precision, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
+ // It is a time window query
+ pQueryInfo->info.timewindow = true;
+ return TSDB_CODE_SUCCESS;
+ // disable it temporarily
+// bool interpQuery = tscIsPointInterpQuery(pQueryInfo);
+// if ((pSqlNode->interval.token == TK_EVERY && (!interpQuery)) || (pSqlNode->interval.token == TK_INTERVAL && interpQuery)) {
+// return buildInvalidOperationMsg(pMsgBuf, msg4);
+// }
+
+ // The following part is used to check for the invalid query expression.
+// return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
+
+}
+
+int32_t validateSessionNode(SQueryStmtInfo *pQueryInfo, SSessionWindowVal* pSession, int32_t precision, SMsgBuf* pMsgBuf) {
+ const char* msg1 = "gap should be fixed time window";
+ const char* msg2 = "only one type time window allowed";
+ const char* msg3 = "invalid column name";
+ const char* msg4 = "invalid time window";
+
+ // no session window
+ if (!TPARSER_HAS_TOKEN(pSession->gap)) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SToken* col = &pSession->col;
+ SToken* gap = &pSession->gap;
+
+ char timeUnit = 0;
+ if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit, precision) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ if (TIME_IS_VAR_DURATION(timeUnit)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+
+ if (pQueryInfo->sessionWindow.gap == 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ if ((getColumnIndexByName(col, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_ID;
+ return TSDB_CODE_SUCCESS;
+ // The following part is used to check for the invalid query expression.
+// return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
}
// parse the window_state
-int32_t validateStateWindowNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
-return 0;
+int32_t validateStateWindowNode(SQueryStmtInfo *pQueryInfo, SWindowStateVal* pWindowState, SMsgBuf* pMsgBuf) {
+ const char* msg1 = "invalid column name";
+ const char* msg2 = "invalid column type";
+ const char* msg3 = "not support state_window with group by ";
+ const char* msg4 = "function not support for super table query";
+ const char* msg5 = "not support state_window on tag column";
+
+ SToken *col = &(pWindowState->col) ;
+ if (!TPARSER_HAS_TOKEN(*col)) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
+ if (taosArrayGetSize(pGroupExpr->columnInfo) > 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ if (getColumnIndexByName(col, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ STableMetaInfo *pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
+ STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
+
+ if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ if (TSDB_COL_IS_TAG(index.type)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg5);
+ }
+
+ if (pGroupExpr->columnInfo == NULL) {
+ pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
+ }
+
+ SSchema* pSchema = getOneColumnSchema(pTableMeta, index.columnIndex);
+ if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || IS_FLOAT_TYPE(pSchema->type)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+
+ columnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->uid, pSchema);
+ SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
+
+ //TODO use group by routine? state window query not support stable query.
+ taosArrayPush(pGroupExpr->columnInfo, &colIndex);
+ pGroupExpr->orderType = TSDB_ORDER_ASC;
+ pQueryInfo->info.stateWindow = true;
+
+ return TSDB_CODE_SUCCESS;
}
// parse the having clause in the first place
@@ -609,16 +889,533 @@ int32_t validateHavingNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgB
}
int32_t validateLimitNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
- return 0;
+ STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
+
+ const char* msg1 = "slimit/soffset only available for STable query";
+ const char* msg2 = "slimit/soffset can not apply to projection query";
+ const char* msg3 = "soffset/offset can not be less than 0";
+
+ // handle the limit offset value, validate the limit
+ pQueryInfo->limit = pSqlNode->limit;
+ pQueryInfo->slimit = pSqlNode->slimit;
+
+// tscDebug("0x%"PRIx64" limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql->self,
+// pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
+
+ if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ if (pQueryInfo->limit.limit == 0) {
+// tscDebug("0x%"PRIx64" limit 0, no output result", pSql->self);
+ pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
+// if (!tscQueryTags(pQueryInfo)) { // local handle the super table tag query
+// if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
+// if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
+// return buildInvalidOperationMsg(pMsgBuf, msg2);
+// }
+//
+// // for projection query on super table, all queries are subqueries
+// if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
+// !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY)) {
+// pQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY;
+// }
+// }
+// }
+
+ if (pQueryInfo->slimit.limit == 0) {
+// tscDebug("0x%"PRIx64" slimit 0, no output result", pSql->self);
+ pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ // No tables included. No results generated. Query results are empty.
+ if (pTableMetaInfo->vgroupList->numOfVgroups == 0) {
+// tscDebug("0x%"PRIx64" no table in super table, no output result", pSql->self);
+ pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
+ return TSDB_CODE_SUCCESS;
+ }
+ } else {
+ if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+ }
}
-// set order by info
+static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, int32_t outputIndex, int32_t tableIndex);
+
+
int32_t validateOrderbyNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
- return 0;
+ const char* msg1 = "invalid column name in orderby clause";
+ const char* msg2 = "too many order by columns";
+ const char* msg3 = "only one column allowed in orderby";
+ const char* msg4 = "invalid order by column index";
+
+ if (pSqlNode->pSortOrder == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
+ SArray* pSortOrder = pSqlNode->pSortOrder;
+
+ /*
+ * for table query, there is only one or none order option is allowed, which is the
+ * ts or values(top/bottom) order is supported.
+ *
+ * for super table query, the order option must be less than 3.
+ */
+ size_t size = taosArrayGetSize(pSortOrder);
+ if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) {
+ if (size > 1) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+ } else {
+ if (size > 2) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+ }
+
+ // handle the first part of order by
+ SVariant* pVar = taosArrayGet(pSortOrder, 0);
+ SSchema s = {0};
+ if (pVar->nType == TSDB_DATA_TYPE_BINARY) {
+ SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ SToken columnName = {pVar->nLen, pVar->nType, pVar->pz};
+ if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ s = *(SSchema*) getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
+ } else { // order by [1|2|3]
+ if (pVar->i64 > getNumOfExprs(pQueryInfo)) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ SExprInfo* pExprInfo = getExprInfo(pQueryInfo, pVar->i64);
+ s = pExprInfo->base.resSchema;
+ }
+
+ SListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->order.order = pItem->sortOrder;
+ pQueryInfo->order.orderColId = s.colId;
+
+ return TSDB_CODE_SUCCESS;
+}
+
+#if 0
+// set order by info
+int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
+ const char* msg0 = "only one column allowed in orderby";
+ const char* msg1 = "invalid column name in orderby clause";
+ const char* msg2 = "too many order by columns";
+ const char* msg3 = "only primary timestamp/tbname/first tag in groupby clause allowed";
+ const char* msg4 = "only tag in groupby clause allowed in order clause";
+ const char* msg5 = "only primary timestamp/column in top/bottom function allowed as order column";
+ const char* msg6 = "only primary timestamp allowed as the second order column";
+ const char* msg7 = "only primary timestamp/column in groupby clause allowed as order column";
+ const char* msg8 = "only column in groupby clause allowed as order column";
+ const char* msg9 = "orderby column must projected in subquery";
+ const char* msg10 = "not support distinct mixed with order by";
+
+// setDefaultOrderInfo(pQueryInfo);
+ STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
+ SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
+ int32_t numOfCols = getNumOfColumns(pTableMetaInfo->pTableMeta);
+
+ if (pSqlNode->pSortOrder == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SArray* pSortOrder = pSqlNode->pSortOrder;
+
+ /*
+ * for table query, there is only one or none order option is allowed, which is the
+ * ts or values(top/bottom) order is supported.
+ *
+ * for super table query, the order option must be less than 3.
+ */
+ size_t size = taosArrayGetSize(pSortOrder);
+ if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) {
+ if (size > 1) {
+ return buildInvalidOperationMsg(pMsgBuf, msg0);
+ }
+ } else {
+ if (size > 2) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+ }
+
+#if 0
+ if (size > 0 && pQueryInfo->distinct) {
+ return buildInvalidOperationMsg(pMsgBuf, msg10);
+ }
+#endif
+
+ // handle the first part of order by
+ SVariant* pVar = taosArrayGet(pSortOrder, 0);
+
+#if 0
+ // e.g., order by 1 asc, return directly with out further check.
+ if (pVar->nType >= TSDB_DATA_TYPE_TINYINT && pVar->nType <= TSDB_DATA_TYPE_BIGINT) {
+ return TSDB_CODE_SUCCESS;
+ }
+#endif
+
+ SToken columnName = {pVar->nLen, pVar->nType, pVar->pz};
+
+ SColumnIndex index = COLUMN_INDEX_INITIALIZER;
+ if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query
+ if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ bool orderByTags = false;
+ bool orderByTS = false;
+ bool orderByGroupbyCol = false;
+
+ if (TSDB_COL_IS_TAG(index.type) && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
+ // it is a tag column
+ if (pQueryInfo->groupbyExpr.columnInfo == NULL) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+
+ int32_t relTagIndex = index.columnIndex - numOfCols;
+ SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0);
+ if (relTagIndex == pColIndex->colIndex) {
+ orderByTags = true;
+ }
+ } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
+ orderByTags = true;
+ }
+
+ if (PRIMARYKEY_TIMESTAMP_COL_ID == index.columnIndex) {
+ orderByTS = true;
+ }
+
+ SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo;
+ if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) {
+ SColIndex* pColIndex = taosArrayGet(columnInfo, 0);
+ if (PRIMARYKEY_TIMESTAMP_COL_ID != index.columnIndex && pColIndex->colIndex == index.columnIndex) {
+ orderByGroupbyCol = true;
+ }
+ }
+
+ if (!(orderByTags || orderByTS || orderByGroupbyCol) /*&& !isTopBottomQuery(pQueryInfo)*/) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ } else { // order by top/bottom result value column is not supported in case of interval query.
+ assert(!(orderByTags && orderByTS && orderByGroupbyCol));
+ }
+
+ size_t s = taosArrayGetSize(pSortOrder);
+ if (s == 1) {
+ if (orderByTags) {
+ pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - numOfCols;
+
+ SListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
+ } else if (orderByGroupbyCol) {
+ SListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
+
+ pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
+ pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
+ } else if (isTopBottomQuery(pQueryInfo)) {
+ /* order of top/bottom query in interval is not valid */
+ int32_t pos = tscExprTopBottomIndex(pQueryInfo);
+ assert(pos > 0);
+
+ SExprInfo* pExpr = getExprInfo(pQueryInfo, pos - 1);
+// assert(getExprFunctionId(pExpr) == FUNCTION_TS);
+
+ pExpr = getExprInfo(pQueryInfo, pos);
+
+ // other tag are not allowed
+ if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
+ return buildInvalidOperationMsg(pMsgBuf, msg5);
+ }
+
+ SListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->order.order = p1->sortOrder;
+ pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
+ return TSDB_CODE_SUCCESS;
+ } else {
+ SListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
+
+ pQueryInfo->order.order = p1->sortOrder;
+ pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_ID;
+
+ // orderby ts query on super table
+ if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
+ bool found = false;
+ for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) {
+ SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
+ if (getExprFunctionId(pExpr) == FUNCTION_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found && pQueryInfo->pDownstream) {
+ return buildInvalidOperationMsg(pMsgBuf, msg9);
+ }
+
+ // this is a invisible output column, in order to used to sort the result.
+ setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, 0, index.tableIndex);
+ }
+ }
+ } else {
+ SListItem *pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
+ if (orderByTags) {
+ pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - numOfCols;
+ pQueryInfo->groupbyExpr.orderType = pItem->sortOrder;
+ } else if (orderByGroupbyCol) {
+ pQueryInfo->order.order = pItem->sortOrder;
+ pQueryInfo->order.orderColId = index.columnIndex;
+ } else {
+ pQueryInfo->order.order = pItem->sortOrder;
+ pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_ID;
+ }
+
+ pItem = taosArrayGet(pSqlNode->pSortOrder, 1);
+ SVariant* pVar2 = &pItem->pVar;
+ SToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz};
+ if (getColumnIndexByName(&cname, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
+ return buildInvalidOperationMsg(pMsgBuf, msg6);
+ } else {
+ SListItem* p1 = taosArrayGet(pSortOrder, 1);
+ pQueryInfo->order.order = p1->sortOrder;
+ pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_ID;
+ }
+ }
+
+ } else if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo)) { // check order by clause for normal table & temp table
+ if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID && !isTopBottomQuery(pQueryInfo)) {
+ bool validOrder = false;
+ SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo;
+ if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) {
+ SColIndex* pColIndex = taosArrayGet(columnInfo, 0);
+ validOrder = (pColIndex->colIndex == index.columnIndex);
+ }
+
+ if (!validOrder) {
+ return buildInvalidOperationMsg(pMsgBuf, msg7);
+ }
+
+ SListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->groupbyExpr.orderIndex = pSchema[index.columnIndex].colId;
+ pQueryInfo->groupbyExpr.orderType = p1->sortOrder;
+ }
+
+ if (isTopBottomQuery(pQueryInfo)) {
+ SArray *columnInfo = pQueryInfo->groupbyExpr.columnInfo;
+ if (columnInfo != NULL && taosArrayGetSize(columnInfo) > 0) {
+ SColIndex* pColIndex = taosArrayGet(columnInfo, 0);
+
+ if (pColIndex->colIndex == index.columnIndex) {
+ return buildInvalidOperationMsg(pMsgBuf, msg8);
+ }
+ } else {
+ int32_t pos = tscExprTopBottomIndex(pQueryInfo);
+ assert(pos > 0);
+ SExprInfo* pExpr = getExprInfo(pQueryInfo, pos - 1);
+ assert(getExprFunctionId(pExpr) == FUNCTION_TS);
+
+ pExpr = getExprInfo(pQueryInfo, pos);
+
+ if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
+ return buildInvalidOperationMsg(pMsgBuf, msg5);
+ }
+ }
+
+ SListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->order.order = pItem->sortOrder;
+
+ pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->order.order = pItem->sortOrder;
+ pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
+ } else {
+ // handle the temp table order by clause. You can order by any single column in case of the temp table, created by
+ // inner subquery.
+ assert(UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo) && taosArrayGetSize(pSqlNode->pSortOrder) == 1);
+
+ if (getColumnIndexByName(&columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ SListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0);
+ pQueryInfo->order.order = pItem->sortOrder;
+ pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId;
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+#endif
+
+static int32_t checkQueryRangeForFill(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
+ const char* msg3 = "start(end) time of time range required or time range too large";
+
+ if (pQueryInfo->interval.interval == 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
+ if (initialWindows) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+
+ int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
+
+ int64_t intervalRange = 0;
+ if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.intervalUnit)) {
+ intervalRange = pQueryInfo->interval.interval;
+
+ // number of result is not greater than 10,000,000
+ if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
+ return buildInvalidOperationMsg(pMsgBuf, msg3);
+ }
+ }
+
+ return TSDB_CODE_SUCCESS;
}
int32_t validateFillNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
- return 0;
+ SArray* pFillToken = pSqlNode->fillType;
+ if (pSqlNode->fillType == NULL) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ SListItem* pItem = taosArrayGet(pFillToken, 0);
+
+ const int32_t START_INTERPO_COL_IDX = 1;
+
+ const char* msg1 = "value is expected";
+ const char* msg2 = "invalid fill option";
+ const char* msg3 = "top/bottom not support fill";
+ const char* msg4 = "illegal value or data overflow";
+ const char* msg5 = "fill only available for interval query";
+ const char* msg6 = "not supported function now";
+
+// if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) {
+// return buildInvalidOperationMsg(pMsgBuf, msg5);
+// }
+
+ /*
+ * fill options are set at the end position, when all columns are set properly
+ * the columns may be increased due to group by operation
+ */
+ if (checkQueryRangeForFill(pQueryInfo, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
+
+ if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+
+ int32_t numOfFields = (int32_t) getNumOfFields(&pQueryInfo->fieldsInfo);
+
+ pQueryInfo->fillVal = calloc(numOfFields, sizeof(int64_t));
+ if (pQueryInfo->fillVal == NULL) {
+ return TSDB_CODE_TSC_OUT_OF_MEMORY;
+ }
+
+ pQueryInfo->numOfFillVal = (int32_t)numOfFields;
+ if (strncasecmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) {
+ pQueryInfo->fillType = TSDB_FILL_NONE;
+ } else if (strncasecmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4) {
+ pQueryInfo->fillType = TSDB_FILL_NULL;
+ for (int32_t i = START_INTERPO_COL_IDX; i < numOfFields; ++i) {
+ TAOS_FIELD* pField = &getInternalField(&pQueryInfo->fieldsInfo, i)->field;
+ setNull((char*)&pQueryInfo->fillVal[i], pField->type, pField->bytes);
+ }
+ } else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
+ pQueryInfo->fillType = TSDB_FILL_PREV;
+// if (pQueryInfo->info.interpQuery && pQueryInfo->order.order == TSDB_ORDER_DESC) {
+// return buildInvalidOperationMsg(pMsgBuf, msg6);
+// }
+ } else if (strncasecmp(pItem->pVar.pz, "next", 4) == 0 && pItem->pVar.nLen == 4) {
+ pQueryInfo->fillType = TSDB_FILL_NEXT;
+ } else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
+ pQueryInfo->fillType = TSDB_FILL_LINEAR;
+ } else if (strncasecmp(pItem->pVar.pz, "value", 5) == 0 && pItem->pVar.nLen == 5) {
+ pQueryInfo->fillType = TSDB_FILL_SET_VALUE;
+
+ size_t num = taosArrayGetSize(pFillToken);
+ if (num == 1) { // no actual value, return with error code
+ return buildInvalidOperationMsg(pMsgBuf, msg1);
+ }
+
+ int32_t startPos = 1;
+ int32_t numOfFillVal = (int32_t)(num - 1);
+
+ // for point interpolation query, we do not have the timestamp column
+ if (pQueryInfo->info.interpQuery) {
+ startPos = 0;
+ if (numOfFillVal > numOfFields) {
+ numOfFillVal = numOfFields;
+ }
+ } else {
+ numOfFillVal = MIN(num, numOfFields);
+ }
+
+ int32_t j = 1;
+
+ for (int32_t i = startPos; i < numOfFillVal; ++i, ++j) {
+ TAOS_FIELD* pField = &getInternalField(&pQueryInfo->fieldsInfo, i)->field;
+ if (pField->type == TSDB_DATA_TYPE_BINARY || pField->type == TSDB_DATA_TYPE_NCHAR) {
+ setVardataNull((char*) &pQueryInfo->fillVal[i], pField->type);
+ continue;
+ }
+
+ SVariant* p = taosArrayGet(pFillToken, j);
+ int32_t ret = taosVariantDump(p, (char*)&pQueryInfo->fillVal[i], pField->type, true);
+ if (ret != TSDB_CODE_SUCCESS) {
+ return buildInvalidOperationMsg(pMsgBuf, msg4);
+ }
+ }
+
+ if ((num < numOfFields) || ((num - 1 < numOfFields) && (pQueryInfo->info.interpQuery))) {
+ SListItem* lastItem = taosArrayGetLast(pFillToken);
+
+ for (int32_t i = numOfFillVal; i < numOfFields; ++i) {
+ TAOS_FIELD* pField = &getInternalField(&pQueryInfo->fieldsInfo, i)->field;
+
+ if (pField->type == TSDB_DATA_TYPE_BINARY || pField->type == TSDB_DATA_TYPE_NCHAR) {
+ setVardataNull((char*) &pQueryInfo->fillVal[i], pField->type);
+ } else {
+ taosVariantDump(&lastItem->pVar, (char*)&pQueryInfo->fillVal[i], pField->type, true);
+ }
+ }
+ }
+ } else {
+ return buildInvalidOperationMsg(pMsgBuf, msg2);
+ }
+
+// for(int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) {
+// SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
+//
+// int32_t functionId = pExpr->pExpr->_node.functionId;
+// if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) {
+// return buildInvalidOperationMsg(pMsgBuf, msg3);
+// }
+// }
+
+ return TSDB_CODE_SUCCESS;
}
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
@@ -679,6 +1476,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta;
SSchema* pSchema = getOneColumnSchema(pTableMeta, 0);
+ int32_t precision = pTableMeta->tableInfo.precision;
if (pSchema->type != TSDB_DATA_TYPE_TIMESTAMP) {
int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo);
@@ -708,32 +1506,19 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
if (validateIntervalNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else {
- if (validateSessionNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ if (validateSessionNode(pQueryInfo, &pSqlNode->sessionVal, precision, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// parse the window_state
- if (validateStateWindowNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ if (validateStateWindowNode(pQueryInfo, &pSqlNode->windowstateVal, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
-
-// if (isTimeWindowQuery(pQueryInfo)) {
-// // check if the first column of the nest query result is timestamp column
-// SColumn* pCol = taosArrayGetP(pQueryInfo->colList, 0);
-// if (pCol->info.type != TSDB_DATA_TYPE_TIMESTAMP) {
-// return buildInvalidOperationMsg(pMsgBuf, msg4);
-// }
-//
-// if (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
-// return TSDB_CODE_TSC_INVALID_OPERATION;
-// }
-// }
}
// parse the having clause in the first place
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
- if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
- TSDB_CODE_SUCCESS) {
+ if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
@@ -758,6 +1543,8 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
}
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
+ int32_t precision = pTableMetaInfo->pTableMeta->tableInfo.precision;
+
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
@@ -767,14 +1554,12 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
- pQueryInfo->onlyHasTagCond = true;
// set where info
if (pSqlNode->pWhere != NULL) {
if (validateWhereNode(pQueryInfo, pSqlNode->pWhere, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
- pSqlNode->pWhere = NULL;
} else {
if (taosArrayGetSize(pSqlNode->from->list) > 1) { // Cross join not allowed yet
return buildInvalidOperationMsg(pMsgBuf, "cross join not supported yet");
@@ -786,18 +1571,13 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
return TSDB_CODE_TSC_INVALID_OPERATION;
}
- if (isSTable && (pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) {
- return TSDB_CODE_TSC_INVALID_OPERATION;
- }
-
// parse the window_state
- if (validateStateWindowNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ if (validateStateWindowNode(pQueryInfo, &pSqlNode->windowstateVal, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// set order by info
- if (validateOrderbyNode(pQueryInfo, pSqlNode, pMsgBuf) !=
- TSDB_CODE_SUCCESS) {
+ if (validateOrderbyNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
@@ -807,8 +1587,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
}
// parse the having clause in the first place
- if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
- TSDB_CODE_SUCCESS) {
+ if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
@@ -816,7 +1595,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
* transfer sql functions that need secondary merge into another format
* in dealing with super table queries such as: count/first/last
*/
- if (validateSessionNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ if (validateSessionNode(pQueryInfo, &pSqlNode->sessionVal, precision, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
@@ -839,18 +1618,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
}
}
- // set the query info
- SExprInfo** p = NULL;
- int32_t numOfExpr = 0;
- STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
- code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr);
- if (pQueryInfo->exprList1 == NULL) {
- pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
- }
-
- taosArrayAddBatch(pQueryInfo->exprList1, (void*) p, numOfExpr);
- tfree(p);
-
return TSDB_CODE_SUCCESS; // Does not build query message here
}
@@ -947,7 +1714,7 @@ void doAddSourceColumnAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* ind
}
static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, int32_t functionId,
- int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult, SMsgBuf* pMsgBuf) {
+ int32_t outputColIndex, SColumnIndex* pColIndex, tExprNode* pNode, bool finalResult, SMsgBuf* pMsgBuf) {
const char* msg1 = "not support column types";
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
@@ -967,7 +1734,7 @@ static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, i
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false);
SSchema resultSchema = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), name);
- doAddOneExprInfo(pQueryInfo, resColIdx, functionId, pColIndex, pSchema, &resultSchema, NULL, resInfo.intermediateBytes, name);
+ doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, pColIndex, pSchema, &resultSchema, pNode, resInfo.intermediateBytes, name);
return TSDB_CODE_SUCCESS;
}
@@ -1005,7 +1772,7 @@ static int64_t getTickPerSecond(SVariant* pVariant, int32_t precision, int64_t*
// set the first column ts for top/bottom query
static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, int32_t outputIndex, int32_t tableIndex) {
- SColumnIndex indexTS = {.tableIndex = tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL};
+ SColumnIndex indexTS = {.tableIndex = tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_ID, .type = TSDB_COL_NORMAL};
SSchema s = createSchema(TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, NULL, &s, TSDB_KEYSIZE);
@@ -1038,7 +1805,7 @@ static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SC
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
- index->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX;
+ index->columnIndex = PRIMARYKEY_TIMESTAMP_COL_ID;
} else {
// count the number of table created according to the super table
if (getColumnIndexByName(pToken, pQueryInfo, index, pMsgBuf) != TSDB_CODE_SUCCESS) {
@@ -1046,7 +1813,7 @@ static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SC
}
}
} else { // count(*) is equalled to count(primary_timestamp_key)
- *index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
+ *index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_ID, false};
}
return TSDB_CODE_SUCCESS;
@@ -1057,7 +1824,7 @@ static int32_t doAddAllColumnExprInSelectClause(SQueryStmtInfo *pQueryInfo, STab
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
SColumnIndex index = {.tableIndex = tableIndex, .columnIndex = i, .type = TSDB_COL_NORMAL};
- if (addOneExprInfo(pQueryInfo, pItem, functionId, *colIndex, &index, finalResult, pMsgBuf) != 0) {
+ if (addOneExprInfo(pQueryInfo, pItem, functionId, *colIndex, &index, NULL, finalResult, pMsgBuf) != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
@@ -1102,7 +1869,7 @@ static int32_t doHandleOneParam(SQueryStmtInfo *pQueryInfo, tSqlExprItem* pItem,
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
- if (addOneExprInfo(pQueryInfo, pItem, functionId, (*outputIndex)++, &index, finalResult, pMsgBuf) != 0) {
+ if (addOneExprInfo(pQueryInfo, pItem, functionId, (*outputIndex)++, &index, pNode, finalResult, pMsgBuf) != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
@@ -1156,6 +1923,8 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId
pIndex->tableIndex = 0;
multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf);
+ taosArrayDestroy(colList);
+ taosArrayDestroy(pColumnList);
} else {
assert(0);
}
@@ -1421,7 +2190,6 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
-
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false);
/*
@@ -2129,13 +2897,11 @@ static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex,
char* c = tbufGetData(&bw, false);
// set the serialized binary string as the parameter of arithmetic expression
- SColumnIndex* index1 = taosArrayGet(pColumnList, 0);
addExprInfoParam(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
addResColumnInfo(pQueryInfo, exprIndex, &pExpr->base.resSchema, pExpr);
tbufCloseWriter(&bw);
taosArrayDestroy(colList);
- tExprTreeDestroy(pNode, NULL);
} else {
SColumnIndex columnIndex = {0};
@@ -2174,6 +2940,7 @@ static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex,
// tbufCloseWriter(&bw); // TODO there is a memory leak
}
+ taosArrayDestroy(pColumnList);
return TSDB_CODE_SUCCESS;
}
@@ -2756,6 +3523,9 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
validateSqlNode(p, pQueryInfo, &buf);
}
+ SArray* functionList = extractFunctionIdList(pQueryInfo->exprList);
+ extractFunctionDesc(functionList, &pQueryInfo->info);
+
if ((code = checkForInvalidExpr(pQueryInfo, &buf)) != TSDB_CODE_SUCCESS) {
return code;
}
diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c
index ff48f9c749..051d19ccbf 100644
--- a/source/libs/parser/src/parser.c
+++ b/source/libs/parser/src/parser.c
@@ -185,4 +185,13 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
}
return code;
-}
\ No newline at end of file
+}
+
+void qParserClearupMetaRequestInfo(SMetaReq* pMetaReq) {
+ if (pMetaReq == NULL) {
+ return;
+ }
+
+ taosArrayDestroy(pMetaReq->pTableName);
+ taosArrayDestroy(pMetaReq->pUdf);
+}
diff --git a/source/libs/parser/src/parserUtil.c b/source/libs/parser/src/parserUtil.c
index bb473e9a73..c970283ca7 100644
--- a/source/libs/parser/src/parserUtil.c
+++ b/source/libs/parser/src/parserUtil.c
@@ -576,13 +576,6 @@ TAOS_FIELD* getFieldInfo(SFieldInfo* pFieldInfo, int32_t index) {
return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field;
}
-int16_t getFieldInfoOffset(SQueryStmtInfo* pQueryInfo, int32_t index) {
- SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, index);
- assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL);
- return 0;
-// return pInfo->pExpr->base.offset;
-}
-
int32_t fieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) {
assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
@@ -780,8 +773,8 @@ SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid
}
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) {
- SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
- return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s);
+ SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_ID};
+ return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_ID, tableUid, &s);
}
void columnCopy(SColumn* pDest, const SColumn* pSrc);
diff --git a/source/libs/parser/src/queryInfoUtil.c b/source/libs/parser/src/queryInfoUtil.c
index 4dd45fd54c..8abbb14e78 100644
--- a/source/libs/parser/src/queryInfoUtil.c
+++ b/source/libs/parser/src/queryInfoUtil.c
@@ -1,4 +1,5 @@
#include "queryInfoUtil.h"
+#include
#include "astGenerator.h"
#include "function.h"
#include "os.h"
@@ -55,7 +56,6 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
}
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) {
-
if (pColumnNode == NULL) {
pColumnNode = calloc(1, sizeof(tExprNode));
pColumnNode->nodeType = TEXPR_COL_NODE;
@@ -167,6 +167,10 @@ SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
void destroyExprInfo(SExprInfo* pExprInfo) {
tExprTreeDestroy(pExprInfo->pExpr, NULL);
+
+ for(int32_t i = 0; i < pExprInfo->base.numOfParams; ++i) {
+ taosVariantDestroy(&pExprInfo->base.param[i]);
+ }
tfree(pExprInfo);
}
@@ -192,6 +196,11 @@ void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt
assert(pExpr->numOfParams <= 3);
}
+int32_t getExprFunctionId(SExprInfo *pExprInfo) {
+ assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
+ return pExprInfo->pExpr->_node.functionId;
+}
+
void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
assert(dst != NULL && src != NULL);
@@ -284,62 +293,11 @@ int32_t getResRowLength(SArray* pExprList) {
return size;
}
-static void freeQueryInfoImpl(SQueryStmtInfo* pQueryInfo) {
- cleanupTagCond(&pQueryInfo->tagCond);
- cleanupColumnCond(&pQueryInfo->colCond);
- cleanupFieldInfo(&pQueryInfo->fieldsInfo);
-
- dropAllExprInfo(pQueryInfo->exprList);
- pQueryInfo->exprList = NULL;
-
- if (pQueryInfo->exprList1 != NULL) {
- dropAllExprInfo(pQueryInfo->exprList1);
- pQueryInfo->exprList1 = NULL;
- }
-
- columnListDestroy(pQueryInfo->colList);
- pQueryInfo->colList = NULL;
-
- if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
- taosArrayDestroy(pQueryInfo->groupbyExpr.columnInfo);
- pQueryInfo->groupbyExpr.columnInfo = NULL;
- }
-
- pQueryInfo->fillType = 0;
-
- tfree(pQueryInfo->fillVal);
- tfree(pQueryInfo->buf);
-
- taosArrayDestroy(pQueryInfo->pUpstream);
- pQueryInfo->pUpstream = NULL;
- pQueryInfo->bufLen = 0;
-}
-
-void freeQueryInfo(SQueryStmtInfo* pQueryInfo, bool removeCachedMeta, uint64_t id) {
- while(pQueryInfo != NULL) {
- SQueryStmtInfo* p = pQueryInfo->sibling;
-
- size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pUpstream);
- for(int32_t i = 0; i < numOfUpstream; ++i) {
- SQueryStmtInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pUpstream, i);
- freeQueryInfoImpl(pUpQueryInfo);
- clearAllTableMetaInfo(pUpQueryInfo, removeCachedMeta, id);
- tfree(pUpQueryInfo);
- }
-
- freeQueryInfoImpl(pQueryInfo);
- clearAllTableMetaInfo(pQueryInfo, removeCachedMeta, id);
-
- tfree(pQueryInfo);
- pQueryInfo = p;
- }
-}
-
SArray* extractFunctionIdList(SArray* pExprInfoList) {
assert(pExprInfoList != NULL);
size_t len = taosArrayGetSize(pExprInfoList);
- SArray* p = taosArrayInit(len, sizeof(int16_t));
+ SArray* p = taosArrayInit(len, sizeof(int32_t));
for(int32_t i = 0; i < len; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
taosArrayPush(p, &pExprInfo->pExpr->_node.functionId);
diff --git a/source/libs/parser/test/CMakeLists.txt b/source/libs/parser/test/CMakeLists.txt
index 184d44a53b..7c90cab6d9 100644
--- a/source/libs/parser/test/CMakeLists.txt
+++ b/source/libs/parser/test/CMakeLists.txt
@@ -5,14 +5,14 @@ MESSAGE(STATUS "build parser unit test")
SET(CMAKE_CXX_STANDARD 11)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
-ADD_EXECUTABLE(astTest ${SOURCE_LIST})
+ADD_EXECUTABLE(parserTest ${SOURCE_LIST})
TARGET_LINK_LIBRARIES(
- astTest
- PUBLIC os util common parser catalog transport gtest
+ parserTest
+ PUBLIC os util common parser catalog transport gtest function
)
TARGET_INCLUDE_DIRECTORIES(
- astTest
+ parserTest
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/parser/"
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/inc"
)
diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp
index 1f4203e9bf..d02df60498 100644
--- a/source/libs/parser/test/parserTests.cpp
+++ b/source/libs/parser/test/parserTests.cpp
@@ -13,6 +13,7 @@
* along with this program. If not, see .
*/
+#include
#include
#include
#pragma GCC diagnostic ignored "-Wwrite-strings"
@@ -65,61 +66,64 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
}
}
-//TEST(testCase, validateAST_test) {
-// SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where tsexprList;
-// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
-//
-// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
-// ASSERT_EQ(p1->base.uid, 110);
-// ASSERT_EQ(p1->base.numOfParams, 0);
-// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
-// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
-// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
+TEST(testCase, validateAST_test) {
+ SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where tsexprList;
+ ASSERT_EQ(taosArrayGetSize(pExprList), 3);
+
+ SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
+ ASSERT_EQ(p1->base.uid, 110);
+ ASSERT_EQ(p1->base.numOfParams, 0);
+ ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
+ ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
+ ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
+ ASSERT_EQ(p1->base.colInfo.colId, 1);
+ ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
+ ASSERT_STRCASEEQ(p1->base.token, "a");
+
+ ASSERT_EQ(taosArrayGetSize(pExprList), 3);
+
+ SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
+ ASSERT_EQ(p2->base.uid, 0);
+ ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
+ ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
+ ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
+
+// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
// ASSERT_EQ(p1->base.colInfo.colId, 1);
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
-// ASSERT_STRCASEEQ(p1->base.token, "a");
-//
-// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
-//
-// SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
-// ASSERT_EQ(p2->base.uid, 0);
-// ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
-// ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
-// ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
-//
-//// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
-//// ASSERT_EQ(p1->base.colInfo.colId, 1);
-//// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
-// ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
-//
-// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
-// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
-//}
-//
+ ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
+
+ ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
+ ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
+
+ destroyQueryInfo(pQueryInfo);
+ qParserClearupMetaRequestInfo(&req);
+ destroySqlInfo(&info1);
+}
+
//TEST(testCase, function_Test) {
// SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
@@ -138,8 +142,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
-// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
-// initQueryInfo(pQueryInfo);
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@@ -161,6 +164,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test2) {
@@ -181,8 +188,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
-// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
-// initQueryInfo(pQueryInfo);
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@@ -204,6 +210,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test3) {
@@ -224,8 +234,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
-// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
-// initQueryInfo(pQueryInfo);
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@@ -246,6 +255,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(p1->base.interBytes, 24);
//
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test4) {
@@ -266,8 +279,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
-// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
-// initQueryInfo(pQueryInfo);
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@@ -289,6 +301,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test5) {
@@ -309,8 +325,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
-// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
-// initQueryInfo(pQueryInfo);
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@@ -333,46 +348,63 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
//}
-
-TEST(testCase, function_Test6) {
- SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc`");
- ASSERT_EQ(info1.valid, true);
-
- char msg[128] = {0};
- SMsgBuf buf;
- buf.len = 128;
- buf.buf = msg;
-
- SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
- int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
- ASSERT_EQ(code, 0);
-
- SMetaReq req = {0};
- int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
- ASSERT_EQ(ret, 0);
- ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
-
- SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
- initQueryInfo(pQueryInfo);
- setTableMetaInfo(pQueryInfo, &req);
-
- SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
- ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
- ASSERT_EQ(ret, 0);
-
- SArray* pExprList = pQueryInfo->exprList;
- ASSERT_EQ(taosArrayGetSize(pExprList), 2);
-
- SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
- ASSERT_EQ(p1->base.uid, 110);
- ASSERT_EQ(p1->base.numOfParams, 0);
- ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
- ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
- ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
- ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
- ASSERT_EQ(p1->base.interBytes, 16);
-
- ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
- ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
-}
\ No newline at end of file
+//
+//TEST(testCase, function_Test6) {
+// SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc` interval(10s, 1s)");
+// ASSERT_EQ(info1.valid, true);
+//
+// char msg[128] = {0};
+// SMsgBuf buf;
+// buf.len = 128;
+// buf.buf = msg;
+//
+// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
+// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
+// ASSERT_EQ(code, 0);
+//
+// SMetaReq req = {0};
+// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
+// ASSERT_EQ(ret, 0);
+// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
+//
+// SQueryStmtInfo* pQueryInfo = createQueryInfo();
+// setTableMetaInfo(pQueryInfo, &req);
+//
+// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
+// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
+// ASSERT_EQ(ret, 0);
+//
+// SArray* pExprList = pQueryInfo->exprList;
+// ASSERT_EQ(taosArrayGetSize(pExprList), 2);
+//
+// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
+// ASSERT_EQ(p1->base.uid, 110);
+// ASSERT_EQ(p1->base.numOfParams, 0);
+// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
+// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
+// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
+// ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
+// ASSERT_EQ(p1->base.interBytes, 16);
+// ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
+// ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_SUM);
+// ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
+//
+// tExprNode* pParam = p1->pExpr->_node.pLeft;
+//
+// ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
+// ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD);
+// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE);
+// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE);
+//
+// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
+// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
+//
+// destroyQueryInfo(pQueryInfo);
+// qParserClearupMetaRequestInfo(&req);
+// destroySqlInfo(&info1);
+//}
\ No newline at end of file
diff --git a/source/libs/parser/test/tokenizerTest.cpp b/source/libs/parser/test/tokenizerTest.cpp
index 3527e27eb4..2296ede80b 100644
--- a/source/libs/parser/test/tokenizerTest.cpp
+++ b/source/libs/parser/test/tokenizerTest.cpp
@@ -667,51 +667,59 @@ TEST(testCase, isValidNumber_test) {
EXPECT_EQ(tGetNumericStringType(&t1), TK_FLOAT);
}
-TEST(testCase, generateAST_test) {
- SSqlInfo info = doGenerateAST("select * from t1 where ts < now");
- ASSERT_EQ(info.valid, true);
-
- SSqlInfo info1 = doGenerateAST("select * from `t.1abc` where tsname, name, strlen(startup->name));
tstrncpy(startup->desc, desc, strlen(startup->desc));
@@ -58,6 +58,7 @@ static int32_t dnodeInitVnode() {
para.fp.GetDnodeEp = dnodeGetEp;
para.fp.SendMsgToDnode = dnodeSendMsgToDnode;
para.fp.SendMsgToMnode = dnodeSendMsgToMnode;
+ para.fp.ReportStartup = dnodeReportStartup;
return vnodeInit(para);
}
diff --git a/source/server/mnode/inc/mnodeInt.h b/source/server/mnode/inc/mnodeInt.h
index 42d3c53fa2..0ce47cbe36 100644
--- a/source/server/mnode/inc/mnodeInt.h
+++ b/source/server/mnode/inc/mnodeInt.h
@@ -24,7 +24,7 @@ extern "C" {
tmr_h mnodeGetTimer();
int32_t mnodeGetDnodeId();
-char *mnodeGetClusterId();
+int64_t mnodeGetClusterId();
EMnStatus mnodeGetStatus();
void mnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg);
diff --git a/source/server/mnode/src/mnodeTelem.c b/source/server/mnode/src/mnodeTelem.c
index cb292342c7..8b8e4f9ce0 100644
--- a/source/server/mnode/src/mnodeTelem.c
+++ b/source/server/mnode/src/mnodeTelem.c
@@ -202,12 +202,13 @@ static void mnodeSendTelemetryReport() {
return;
}
- char clusterId[TSDB_CLUSTER_ID_LEN] = {0};
- mnodeGetClusterId(clusterId);
+ int64_t clusterId = mnodeGetClusterId();
+ char clusterIdStr[20] = {0};
+ snprintf(clusterIdStr, sizeof(clusterIdStr), "%" PRId64, clusterId);
SBufferWriter bw = tbufInitWriter(NULL, false);
mnodeBeginObject(&bw);
- mnodeAddStringField(&bw, "instanceId", clusterId);
+ mnodeAddStringField(&bw, "instanceId", clusterIdStr);
mnodeAddIntField(&bw, "reportVersion", 1);
mnodeAddOsInfo(&bw);
mnodeAddCpuInfo(&bw);
diff --git a/source/server/mnode/src/mondeInt.c b/source/server/mnode/src/mondeInt.c
index 37af26f604..343384ba67 100644
--- a/source/server/mnode/src/mondeInt.c
+++ b/source/server/mnode/src/mondeInt.c
@@ -39,7 +39,7 @@
static struct {
int32_t state;
int32_t dnodeId;
- char clusterId[TSDB_CLUSTER_ID_LEN];
+ int64_t clusterId;
tmr_h timer;
SMnodeFp fp;
SSteps * steps1;
@@ -50,7 +50,7 @@ tmr_h mnodeGetTimer() { return tsMint.timer; }
int32_t mnodeGetDnodeId() { return tsMint.dnodeId; }
-char *mnodeGetClusterId() { return tsMint.clusterId; }
+int64_t mnodeGetClusterId() { return tsMint.clusterId; }
EMnStatus mnodeGetStatus() { return tsMint.state; }
@@ -71,12 +71,14 @@ int32_t mnodeGetStatistics(SMnodeStat *stat) { return 0; }
static int32_t mnodeSetPara(SMnodePara para) {
tsMint.fp = para.fp;
tsMint.dnodeId = para.dnodeId;
- strncpy(tsMint.clusterId, para.clusterId, TSDB_CLUSTER_ID_LEN);
+ tsMint.clusterId = para.clusterId;
if (tsMint.fp.SendMsgToDnode == NULL) return -1;
if (tsMint.fp.SendMsgToMnode == NULL) return -1;
if (tsMint.fp.SendRedirectMsg == NULL) return -1;
+ if (tsMint.fp.GetDnodeEp == NULL) return -1;
if (tsMint.dnodeId < 0) return -1;
+ if (tsMint.clusterId < 0) return -1;
return 0;
}
@@ -141,7 +143,7 @@ static void mnodeCleanupStep2() { taosStepCleanup(tsMint.steps2); }
static bool mnodeNeedDeploy() {
if (tsMint.dnodeId > 0) return false;
- if (tsMint.clusterId[0] != 0) return false;
+ if (tsMint.clusterId > 0) return false;
if (strcmp(tsFirst, tsLocalEp) != 0) return false;
return true;
}
@@ -154,7 +156,7 @@ int32_t mnodeDeploy() {
tsMint.state = MN_STATUS_INIT;
}
- if (tsMint.dnodeId <= 0 || tsMint.clusterId[0] == 0) {
+ if (tsMint.dnodeId <= 0 || tsMint.clusterId <= 0) {
mError("failed to deploy mnode since cluster not ready");
return TSDB_CODE_MND_NOT_READY;
}
diff --git a/source/server/vnode/inc/vnodeCfg.h b/source/server/vnode/inc/vnodeFile.h
similarity index 77%
rename from source/server/vnode/inc/vnodeCfg.h
rename to source/server/vnode/inc/vnodeFile.h
index 342d801f44..bea28324ee 100644
--- a/source/server/vnode/inc/vnodeCfg.h
+++ b/source/server/vnode/inc/vnodeFile.h
@@ -21,8 +21,10 @@ extern "C" {
#endif
#include "vnodeInt.h"
-int32_t vnodeReadCfg(SVnode *pVnode);
-int32_t vnodeWriteCfg(SCreateVnodeMsg *pVnodeCfg);
+int32_t vnodeReadCfg(int32_t vgId, SVnodeCfg *pCfg);
+int32_t vnodeWriteCfg(int32_t vgId, SVnodeCfg *pCfg);
+int32_t vnodeReadState(int32_t vgId, SSyncServerState *pState);
+int32_t vnodeSaveState(int32_t vgid, SSyncServerState *pState);
#ifdef __cplusplus
}
diff --git a/source/server/vnode/inc/vnodeInt.h b/source/server/vnode/inc/vnodeInt.h
index 8188cb56a3..90d9e7105e 100644
--- a/source/server/vnode/inc/vnodeInt.h
+++ b/source/server/vnode/inc/vnodeInt.h
@@ -16,11 +16,12 @@
#ifndef _TD_VNODE_INT_H_
#define _TD_VNODE_INT_H_
+#include "os.h"
#include "amalloc.h"
#include "meta.h"
-#include "os.h"
#include "sync.h"
#include "taosmsg.h"
+#include "tglobal.h"
#include "tlog.h"
#include "tq.h"
#include "tqueue.h"
@@ -43,57 +44,70 @@ extern int32_t vDebugFlag;
#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
+typedef struct STsdbCfg {
+ int32_t cacheBlockSize; // MB
+ int32_t totalBlocks;
+ int32_t daysPerFile;
+ int32_t daysToKeep0;
+ int32_t daysToKeep1;
+ int32_t daysToKeep2;
+ int32_t minRowsPerFileBlock;
+ int32_t maxRowsPerFileBlock;
+ uint8_t precision; // time resolution
+ int8_t compression;
+ int8_t cacheLastRow;
+ int8_t update;
+} STsdbCfg;
+
+typedef struct SMetaCfg {
+} SMetaCfg;
+
+typedef struct SVnodeCfg {
+ char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
+ int8_t dropped;
+ int8_t quorum;
+ SWalCfg wal;
+ STsdbCfg tsdb;
+ SMetaCfg meta;
+ SSyncCluster sync;
+} SVnodeCfg;
+
typedef struct {
- int32_t vgId; // global vnode group ID
- int32_t refCount; // reference count
- SMemAllocator *allocator;
- SMeta *pMeta;
- STsdb *pTsdb;
- STQ *pTQ;
- twalh pWal;
- SyncNodeId syncNode;
- taos_queue pWriteQ; // write queue
- taos_queue pQueryQ; // read query queue
- taos_queue pFetchQ; // read fetch/cancel queue
- SWalCfg walCfg;
- SSyncCluster syncCfg;
- char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
- int64_t queuedWMsgSize;
- int32_t queuedWMsg;
- int32_t queuedRMsg;
- int32_t numOfQHandle; // current initialized and existed query handle in current dnode
- int8_t status;
- int8_t role;
- int8_t accessState;
- int8_t dropped;
- pthread_mutex_t statusMutex;
+ int32_t vgId; // global vnode group ID
+ int32_t refCount; // reference count
+ SMemAllocator *allocator;
+ SMeta *pMeta;
+ STsdb *pTsdb;
+ STQ *pTQ;
+ SWal *pWal;
+ void *pQuery;
+ SSyncNode *pSync;
+ taos_queue pWriteQ; // write queue
+ taos_queue pQueryQ; // read query queue
+ taos_queue pFetchQ; // read fetch/cancel queue
+ SVnodeCfg cfg;
+ SSyncServerState term;
+ int64_t queuedWMsgSize;
+ int32_t queuedWMsg;
+ int32_t queuedRMsg;
+ int32_t numOfQHandle; // current initialized and existed query handle in current dnode
+ int8_t role;
+ int8_t accessState;
+ int8_t dropped;
+ int8_t status;
+ pthread_mutex_t statusMutex;
} SVnode;
typedef struct {
int32_t len;
- void * rsp;
- void * qhandle; // used by query and retrieve msg
+ void *rsp;
+ void *qhandle; // used by query and retrieve msg
} SVnRsp;
void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg);
void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg);
void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
-
-int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
-int32_t vnodeDrop(int32_t vgId);
-int32_t vnodeOpen(int32_t vgId);
-int32_t vnodeAlter(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg);
-int32_t vnodeSync(int32_t vgId);
-int32_t vnodeClose(int32_t vgId);
-void vnodeCleanUp(SVnode *pVnode);
-void vnodeDestroy(SVnode *pVnode);
-int32_t vnodeCompact(int32_t vgId);
-void vnodeBackup(int32_t vgId);
-void vnodeGetStatus(struct SStatusMsg *status);
-
-SVnode *vnodeAcquire(int32_t vgId);
-SVnode *vnodeAcquireNotClose(int32_t vgId);
-void vnodeRelease(SVnode *pVnode);
+void vnodeReportStartup(char *name, char *desc);
#ifdef __cplusplus
}
diff --git a/source/server/vnode/inc/vnodeMgmtMsg.h b/source/server/vnode/inc/vnodeMain.h
similarity index 59%
rename from source/server/vnode/inc/vnodeMgmtMsg.h
rename to source/server/vnode/inc/vnodeMain.h
index 4d5533f2fe..d0d84792e8 100644
--- a/source/server/vnode/inc/vnodeMgmtMsg.h
+++ b/source/server/vnode/inc/vnodeMain.h
@@ -13,23 +13,30 @@
* along with this program. If not, see .
*/
-#ifndef _TD_VNODE_MGMT_MSG_H_
-#define _TD_VNODE_MGMT_MSG_H_
+#ifndef _TD_VNODE_MAIN_H_
+#define _TD_VNODE_MAIN_H_
+
+#include "vnodeInt.h"
#ifdef __cplusplus
extern "C" {
#endif
-#include "vnodeInt.h"
-int32_t vnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg);
-int32_t vnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg);
-int32_t vnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg);
-int32_t vnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg);
-int32_t vnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg);
-int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg);
+int32_t vnodeInitMain();
+void vnodeCleanupMain();
+
+SVnode *vnodeAcquireInAllState(int32_t vgId);
+SVnode *vnodeAcquire(int32_t vgId);
+void vnodeRelease(SVnode *pVnode);
+
+int32_t vnodeCreateVnode(int32_t vgId, SVnodeCfg *pCfg);
+int32_t vnodeAlterVnode(SVnode *pVnode, SVnodeCfg *pCfg);
+int32_t vnodeDropVnode(SVnode *pVnode);
+int32_t vnodeSyncVnode(SVnode *pVnode);
+int32_t vnodeCompactVnode(SVnode *pVnode);
#ifdef __cplusplus
}
#endif
-#endif /*_TD_VNODE_MGMT_H_*/
+#endif /*_TD_VNODE_MAIN_H_*/
diff --git a/source/server/vnode/inc/vnodeMgmt.h b/source/server/vnode/inc/vnodeMgmt.h
index 23dc826db7..ccd1b28b61 100644
--- a/source/server/vnode/inc/vnodeMgmt.h
+++ b/source/server/vnode/inc/vnodeMgmt.h
@@ -21,6 +21,14 @@ extern "C" {
#endif
#include "vnodeInt.h"
+
+typedef struct {
+ SVnode *pVnode;
+ SRpcMsg rpcMsg;
+ char pCont[];
+} SVnMgmtMsg;
+
+
int32_t vnodeInitMgmt();
void vnodeCleanupMgmt();
void vnodeProcessMgmtMsg(SRpcMsg *pMsg);
diff --git a/source/server/vnode/inc/vnodeStatus.h b/source/server/vnode/inc/vnodeStatus.h
deleted file mode 100644
index c7f1b4c96d..0000000000
--- a/source/server/vnode/inc/vnodeStatus.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#ifndef _TD_VNODE_STATUS_H_
-#define _TD_VNODE_STATUS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "vnodeInt.h"
-
-typedef enum _VN_STATUS {
- TAOS_VN_STATUS_INIT = 0,
- TAOS_VN_STATUS_READY = 1,
- TAOS_VN_STATUS_CLOSING = 2,
- TAOS_VN_STATUS_UPDATING = 3
-} EVnodeStatus;
-
-// vnodeStatus
-extern char* vnodeStatus[];
-
-bool vnodeSetInitStatus(SVnode* pVnode);
-bool vnodeSetReadyStatus(SVnode* pVnode);
-bool vnodeSetClosingStatus(SVnode* pVnode);
-bool vnodeSetUpdatingStatus(SVnode* pVnode);
-
-bool vnodeInInitStatus(SVnode* pVnode);
-bool vnodeInReadyStatus(SVnode* pVnode);
-bool vnodeInClosingStatus(SVnode* pVnode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_TD_VNODE_STATUS_H_*/
\ No newline at end of file
diff --git a/source/server/vnode/inc/vnodeVersion.h b/source/server/vnode/inc/vnodeVersion.h
deleted file mode 100644
index 81e6758559..0000000000
--- a/source/server/vnode/inc/vnodeVersion.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#ifndef _TD_VNODE_VERSION_H_
-#define _TD_VNODE_VERSION_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "vnodeInt.h"
-
-int32_t vnodeReadVersion(SVnode *pVnode);
-int32_t vnodeSaveVersion(SVnode *pVnode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_TD_VNODE_VERSION_H_*/
diff --git a/source/server/vnode/inc/vnodeWorker.h b/source/server/vnode/inc/vnodeWorker.h
deleted file mode 100644
index eea35011a8..0000000000
--- a/source/server/vnode/inc/vnodeWorker.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#ifndef _TD_VNODE_WORKER_H_
-#define _TD_VNODE_WORKER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "vnodeInt.h"
-
-int32_t vnodeInitWorker();
-void vnodeCleanupWorker();
-void vnodeProcessCleanupTask(SVnode *pVnode);
-void vnodeProcessDestroyTask(SVnode *pVnode);
-void vnodeProcessBackupTask(SVnode *pVnode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_TD_VNODE_WORKER_H_*/
\ No newline at end of file
diff --git a/source/server/vnode/src/vnodeCfg.c b/source/server/vnode/src/vnodeCfg.c
deleted file mode 100644
index 9c01a47f8f..0000000000
--- a/source/server/vnode/src/vnodeCfg.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-#include "cJSON.h"
-#include "tglobal.h"
-#include "vnodeCfg.h"
-
-static void vnodeLoadCfg(SVnode *pVnode, SCreateVnodeMsg *vnodeMsg) {
-#if 0
- tstrncpy(pVnode->db, vnodeMsg->db, sizeof(pVnode->db));
- pVnode->dbCfgVersion = vnodeMsg->cfg.dbCfgVersion;
- pVnode->vgCfgVersion = vnodeMsg->cfg.vgCfgVersion;
- pVnode->tsdbCfg.cacheBlockSize = vnodeMsg->cfg.cacheBlockSize;
- pVnode->tsdbCfg.totalBlocks = vnodeMsg->cfg.totalBlocks;
- pVnode->tsdbCfg.daysPerFile = vnodeMsg->cfg.daysPerFile;
- pVnode->tsdbCfg.keep = vnodeMsg->cfg.daysToKeep;
- pVnode->tsdbCfg.keep1 = vnodeMsg->cfg.daysToKeep1;
- pVnode->tsdbCfg.keep2 = vnodeMsg->cfg.daysToKeep2;
- pVnode->tsdbCfg.minRowsPerFileBlock = vnodeMsg->cfg.minRowsPerFileBlock;
- pVnode->tsdbCfg.maxRowsPerFileBlock = vnodeMsg->cfg.maxRowsPerFileBlock;
- pVnode->tsdbCfg.precision = vnodeMsg->cfg.precision;
- pVnode->tsdbCfg.compression = vnodeMsg->cfg.compression;
- pVnode->tsdbCfg.update = vnodeMsg->cfg.update;
- pVnode->tsdbCfg.cacheLastRow = vnodeMsg->cfg.cacheLastRow;
- pVnode->walCfg.walLevel = vnodeMsg->cfg.walLevel;
- pVnode->walCfg.fsyncPeriod = vnodeMsg->cfg.fsyncPeriod;
- pVnode->walCfg.keep = TAOS_WAL_NOT_KEEP;
- pVnode->syncCfg.replica = vnodeMsg->cfg.vgReplica;
- pVnode->syncCfg.quorum = vnodeMsg->cfg.quorum;
- pVnode->dbReplica = vnodeMsg->cfg.dbReplica;
- pVnode->dbType = vnodeMsg->cfg.dbType;
-
- for (int i = 0; i < pVnode->syncCfg.replica; ++i) {
- SVnodeDesc *node = &vnodeMsg->nodes[i];
- pVnode->syncCfg.nodeInfo[i].nodeId = node->nodeId;
- taosGetFqdnPortFromEp(node->nodeEp, pVnode->syncCfg.nodeInfo[i].nodeFqdn, &pVnode->syncCfg.nodeInfo[i].nodePort);
- pVnode->syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
- }
-
- vInfo("vgId:%d, load vnode cfg successfully, replcia:%d", pVnode->vgId, pVnode->syncCfg.replica);
- for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
- SNodeInfo *node = &pVnode->syncCfg.nodeInfo[i];
- vInfo("vgId:%d, dnode:%d, %s:%u", pVnode->vgId, node->nodeId, node->nodeFqdn, node->nodePort);
- }
-#endif
-}
-
-int32_t vnodeReadCfg(SVnode *pVnode) {
-#if 0
- int32_t ret = TSDB_CODE_VND_APP_ERROR;
- int32_t len = 0;
- int maxLen = 1000;
- char * content = calloc(1, maxLen + 1);
- cJSON * root = NULL;
- FILE * fp = NULL;
- bool nodeChanged = false;
-
- SCreateVnodeMsg vnodeMsg;
-
- char file[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pVnode->vgId);
-
- vnodeMsg.cfg.vgId = pVnode->vgId;
-
- fp = fopen(file, "r");
- if (!fp) {
- vError("vgId:%d, failed to open vnode cfg file:%s to read, error:%s", pVnode->vgId, file, strerror(errno));
- ret = TAOS_SYSTEM_ERROR(errno);
- goto PARSE_VCFG_ERROR;
- }
-
- len = (int32_t)fread(content, 1, maxLen, fp);
- if (len <= 0) {
- vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
-
- content[len] = 0;
- root = cJSON_Parse(content);
- if (root == NULL) {
- vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
-
- cJSON *db = cJSON_GetObjectItem(root, "db");
- if (!db || db->type != cJSON_String || db->valuestring == NULL) {
- vError("vgId:%d, failed to read %s, db not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- tstrncpy(vnodeMsg.db, db->valuestring, sizeof(vnodeMsg.db));
-
- cJSON *dbCfgVersion = cJSON_GetObjectItem(root, "cfgVersion");
- if (!dbCfgVersion || dbCfgVersion->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, cfgVersion not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.dbCfgVersion = (int32_t)dbCfgVersion->valueint;
-
- cJSON *vgCfgVersion = cJSON_GetObjectItem(root, "vgCfgVersion");
- if (!vgCfgVersion || vgCfgVersion->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, vgCfgVersion not found", pVnode->vgId, file);
- vnodeMsg.cfg.vgCfgVersion = 0;
- } else {
- vnodeMsg.cfg.vgCfgVersion = (int32_t)vgCfgVersion->valueint;
- }
-
- cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
- if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, cacheBlockSize not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.cacheBlockSize = (int32_t)cacheBlockSize->valueint;
-
- cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
- if (!totalBlocks || totalBlocks->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, totalBlocks not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.totalBlocks = (int32_t)totalBlocks->valueint;
-
- cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
- if (!daysPerFile || daysPerFile->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, daysPerFile not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.daysPerFile = (int32_t)daysPerFile->valueint;
-
- cJSON *daysToKeep = cJSON_GetObjectItem(root, "daysToKeep");
- if (!daysToKeep || daysToKeep->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, daysToKeep not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.daysToKeep = (int32_t)daysToKeep->valueint;
-
- cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
- if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, daysToKeep1 not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.daysToKeep1 = (int32_t)daysToKeep1->valueint;
-
- cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
- if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, daysToKeep2 not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.daysToKeep2 = (int32_t)daysToKeep2->valueint;
-
- cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
- if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, minRowsPerFileBlock not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.minRowsPerFileBlock = (int32_t)minRowsPerFileBlock->valueint;
-
- cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
- if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, maxRowsPerFileBlock not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.maxRowsPerFileBlock = (int32_t)maxRowsPerFileBlock->valueint;
-
- cJSON *precision = cJSON_GetObjectItem(root, "precision");
- if (!precision || precision->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, precision not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.precision = (int8_t)precision->valueint;
-
- cJSON *compression = cJSON_GetObjectItem(root, "compression");
- if (!compression || compression->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, compression not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.compression = (int8_t)compression->valueint;
-
- cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
- if (!walLevel || walLevel->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, walLevel not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.walLevel = (int8_t)walLevel->valueint;
-
- cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsync");
- if (!walLevel || walLevel->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, fsyncPeriod not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.fsyncPeriod = (int32_t)fsyncPeriod->valueint;
-
- cJSON *wals = cJSON_GetObjectItem(root, "wals");
- if (!wals || wals->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, wals not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.wals = (int8_t)wals->valueint;
-
- cJSON *vgReplica = cJSON_GetObjectItem(root, "replica");
- if (!vgReplica || vgReplica->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, replica not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.vgReplica = (int8_t)vgReplica->valueint;
-
- cJSON *dbReplica = cJSON_GetObjectItem(root, "dbReplica");
- if (!dbReplica || dbReplica->type != cJSON_Number) {
- vWarn("vgId:%d, failed to read %s, dbReplica not found", pVnode->vgId, file);
- vnodeMsg.cfg.dbReplica = vnodeMsg.cfg.vgReplica;
- vnodeMsg.cfg.vgCfgVersion = 0;
- } else {
- vnodeMsg.cfg.dbReplica = (int8_t)dbReplica->valueint;
- }
-
- cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
- if (!quorum || quorum->type != cJSON_Number) {
- vError("vgId: %d, failed to read %s, quorum not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- vnodeMsg.cfg.quorum = (int8_t)quorum->valueint;
-
- cJSON *update = cJSON_GetObjectItem(root, "update");
- if (!update || update->type != cJSON_Number) {
- vWarn("vgId: %d, failed to read %s, update not found", pVnode->vgId, file);
- vnodeMsg.cfg.update = 0;
- vnodeMsg.cfg.vgCfgVersion = 0;
- } else {
- vnodeMsg.cfg.update = (int8_t)update->valueint;
- }
-
- cJSON *cacheLastRow = cJSON_GetObjectItem(root, "cacheLastRow");
- if (!cacheLastRow || cacheLastRow->type != cJSON_Number) {
- vWarn("vgId: %d, failed to read %s, cacheLastRow not found", pVnode->vgId, file);
- vnodeMsg.cfg.cacheLastRow = 0;
- vnodeMsg.cfg.vgCfgVersion = 0;
- } else {
- vnodeMsg.cfg.cacheLastRow = (int8_t)cacheLastRow->valueint;
- }
-
- cJSON *dbType = cJSON_GetObjectItem(root, "dbType");
- if (!dbType || dbType->type != cJSON_Number) {
- vWarn("vgId: %d, failed to read %s, dbType not found", pVnode->vgId, file);
- vnodeMsg.cfg.dbType = 0;
- } else {
- vnodeMsg.cfg.dbType = (int8_t)dbType->valueint;
- }
-
- cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
- if (!nodeInfos || nodeInfos->type != cJSON_Array) {
- vError("vgId:%d, failed to read %s, nodeInfos not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
-
- int size = cJSON_GetArraySize(nodeInfos);
- if (size != vnodeMsg.cfg.vgReplica) {
- vError("vgId:%d, failed to read %s, nodeInfos size not matched", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
-
- for (int i = 0; i < size; ++i) {
- cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
- if (nodeInfo == NULL) continue;
- SVnodeDesc *node = &vnodeMsg.nodes[i];
-
- cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
- if (!nodeId || nodeId->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, nodeId not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- node->nodeId = (int32_t)nodeId->valueint;
-
- cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
- if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
- vError("vgId:%d, failed to read %s, nodeFqdn not found", pVnode->vgId, file);
- goto PARSE_VCFG_ERROR;
- }
- tstrncpy(node->nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
-
- char nodeEpStr[TSDB_EP_LEN];
- vnodeGetDnodeEp(node->nodeId, nodeEpStr, NULL, NULL);
- bool changed = (strcmp(node->nodeEp, nodeEpStr) != 0);
- if (changed) {
- tstrncpy(node->nodeEp, nodeEpStr, TSDB_EP_LEN);
- nodeChanged = changed;
- }
- }
-
- ret = TSDB_CODE_SUCCESS;
-
-PARSE_VCFG_ERROR:
- if (content != NULL) free(content);
- if (root != NULL) cJSON_Delete(root);
- if (fp != NULL) fclose(fp);
-
- if (nodeChanged) {
- vnodeWriteCfg(&vnodeMsg);
- }
-
- if (ret == TSDB_CODE_SUCCESS) {
- vnodeLoadCfg(pVnode, &vnodeMsg);
- }
-
- terrno = 0;
- return ret;
-}
-
-int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) {
- char file[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pMsg->cfg.vgId);
-
- FILE *fp = fopen(file, "w");
- if (!fp) {
- vError("vgId:%d, failed to write %s error:%s", pMsg->cfg.vgId, file, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- }
-
- int32_t len = 0;
- int32_t maxLen = 1000;
- char * content = calloc(1, maxLen + 1);
-
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pMsg->db);
- len += snprintf(content + len, maxLen - len, " \"cfgVersion\": %d,\n", pMsg->cfg.dbCfgVersion);
- len += snprintf(content + len, maxLen - len, " \"vgCfgVersion\": %d,\n", pMsg->cfg.vgCfgVersion);
- len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pMsg->cfg.cacheBlockSize);
- len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pMsg->cfg.totalBlocks);
- len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pMsg->cfg.daysPerFile);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep\": %d,\n", pMsg->cfg.daysToKeep);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pMsg->cfg.daysToKeep1);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pMsg->cfg.daysToKeep2);
- len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pMsg->cfg.minRowsPerFileBlock);
- len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pMsg->cfg.maxRowsPerFileBlock);
- len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pMsg->cfg.precision);
- len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pMsg->cfg.compression);
- len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pMsg->cfg.walLevel);
- len += snprintf(content + len, maxLen - len, " \"fsync\": %d,\n", pMsg->cfg.fsyncPeriod);
- len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pMsg->cfg.vgReplica);
- len += snprintf(content + len, maxLen - len, " \"dbReplica\": %d,\n", pMsg->cfg.dbReplica);
- len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pMsg->cfg.wals);
- len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pMsg->cfg.quorum);
- len += snprintf(content + len, maxLen - len, " \"update\": %d,\n", pMsg->cfg.update);
- len += snprintf(content + len, maxLen - len, " \"cacheLastRow\": %d,\n", pMsg->cfg.cacheLastRow);
- len += snprintf(content + len, maxLen - len, " \"dbType\": %d,\n", pMsg->cfg.dbType);
- len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
- for (int32_t i = 0; i < pMsg->cfg.vgReplica; i++) {
- SVnodeDesc *node = &pMsg->nodes[i];
- vnodeGetDnodeEp(node->nodeId, node->nodeEp, NULL, NULL);
- len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", node->nodeId);
- len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", node->nodeEp);
- if (i < pMsg->cfg.vgReplica - 1) {
- len += snprintf(content + len, maxLen - len, " },{\n");
- } else {
- len += snprintf(content + len, maxLen - len, " }]\n");
- }
- }
- len += snprintf(content + len, maxLen - len, "}\n");
-
- fwrite(content, 1, len, fp);
- taosFsync(fileno(fp));
- fclose(fp);
- free(content);
- terrno = 0;
-
- vInfo("vgId:%d, successed to write %s", pMsg->cfg.vgId, file);
-#endif
- return TSDB_CODE_SUCCESS;
-}
diff --git a/source/server/vnode/src/vnodeFile.c b/source/server/vnode/src/vnodeFile.c
new file mode 100644
index 0000000000..ddcbd2689d
--- /dev/null
+++ b/source/server/vnode/src/vnodeFile.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "cJSON.h"
+#include "vnodeFile.h"
+
+int32_t vnodeReadCfg(int32_t vgId, SVnodeCfg *pCfg) {
+ int32_t ret = TSDB_CODE_VND_APP_ERROR;
+ int32_t len = 0;
+ int maxLen = 1000;
+ char *content = calloc(1, maxLen + 1);
+ cJSON *root = NULL;
+ FILE *fp = NULL;
+
+ char file[PATH_MAX + 30] = {0};
+ sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, vgId);
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ vError("vgId:%d, failed to open vnode cfg file:%s to read since %s", vgId, file, strerror(errno));
+ ret = TAOS_SYSTEM_ERROR(errno);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ len = (int32_t)fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ vError("vgId:%d, failed to read %s since content is null", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ content[len] = 0;
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ vError("vgId:%d, failed to read %s since invalid json format", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ cJSON *db = cJSON_GetObjectItem(root, "db");
+ if (!db || db->type != cJSON_String || db->valuestring == NULL) {
+ vError("vgId:%d, failed to read %s since db not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ tstrncpy(pCfg->db, db->valuestring, sizeof(pCfg->db));
+
+ cJSON *dropped = cJSON_GetObjectItem(root, "dropped");
+ if (!dropped || dropped->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since dropped not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->dropped = (int32_t)dropped->valueint;
+
+ cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
+ if (!quorum || quorum->type != cJSON_Number) {
+ vError("vgId: %d, failed to read %s, quorum not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->quorum = (int8_t)quorum->valueint;
+
+ cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
+ if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since cacheBlockSize not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.cacheBlockSize = (int32_t)cacheBlockSize->valueint;
+
+ cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
+ if (!totalBlocks || totalBlocks->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since totalBlocks not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.totalBlocks = (int32_t)totalBlocks->valueint;
+
+ cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
+ if (!daysPerFile || daysPerFile->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since daysPerFile not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.daysPerFile = (int32_t)daysPerFile->valueint;
+
+ cJSON *daysToKeep0 = cJSON_GetObjectItem(root, "daysToKeep0");
+ if (!daysToKeep0 || daysToKeep0->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since daysToKeep0 not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.daysToKeep0 = (int32_t)daysToKeep0->valueint;
+
+ cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
+ if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since daysToKeep1 not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.daysToKeep1 = (int32_t)daysToKeep1->valueint;
+
+ cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
+ if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since daysToKeep2 not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.daysToKeep2 = (int32_t)daysToKeep2->valueint;
+
+ cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
+ if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since minRowsPerFileBlock not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.minRowsPerFileBlock = (int32_t)minRowsPerFileBlock->valueint;
+
+ cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
+ if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since maxRowsPerFileBlock not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.maxRowsPerFileBlock = (int32_t)maxRowsPerFileBlock->valueint;
+
+ cJSON *precision = cJSON_GetObjectItem(root, "precision");
+ if (!precision || precision->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since precision not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.precision = (int8_t)precision->valueint;
+
+ cJSON *compression = cJSON_GetObjectItem(root, "compression");
+ if (!compression || compression->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since compression not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.compression = (int8_t)compression->valueint;
+
+ cJSON *update = cJSON_GetObjectItem(root, "update");
+ if (!update || update->type != cJSON_Number) {
+ vError("vgId: %d, failed to read %s since update not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.update = (int8_t)update->valueint;
+
+ cJSON *cacheLastRow = cJSON_GetObjectItem(root, "cacheLastRow");
+ if (!cacheLastRow || cacheLastRow->type != cJSON_Number) {
+ vError("vgId: %d, failed to read %s since cacheLastRow not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->tsdb.cacheLastRow = (int8_t)cacheLastRow->valueint;
+
+ cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
+ if (!walLevel || walLevel->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since walLevel not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->wal.walLevel = (int8_t)walLevel->valueint;
+
+ cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsyncPeriod");
+ if (!walLevel || walLevel->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since fsyncPeriod not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->wal.fsyncPeriod = (int32_t)fsyncPeriod->valueint;
+
+ cJSON *selfIndex = cJSON_GetObjectItem(root, "selfIndex");
+ if (!selfIndex || selfIndex->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since selfIndex not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->sync.selfIndex = selfIndex->valueint;
+
+ cJSON *replica = cJSON_GetObjectItem(root, "replica");
+ if (!replica || replica->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since replica not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ pCfg->sync.replica = replica->valueint;
+
+ cJSON *nodes = cJSON_GetObjectItem(root, "nodes");
+ if (!nodes || nodes->type != cJSON_Array) {
+ vError("vgId:%d, failed to read %s, nodes not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ int size = cJSON_GetArraySize(nodes);
+ if (size != pCfg->sync.replica) {
+ vError("vgId:%d, failed to read %s since nodes size not matched", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ for (int i = 0; i < size; ++i) {
+ cJSON *nodeInfo = cJSON_GetArrayItem(nodes, i);
+ if (nodeInfo == NULL) continue;
+ SNodeInfo *node = &pCfg->sync.nodeInfo[i];
+
+ cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "id");
+ if (!nodeId || nodeId->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s since nodeId not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ node->nodeId = nodeId->valueint;
+
+ cJSON *nodePort = cJSON_GetObjectItem(nodeInfo, "port");
+ if (!nodePort || nodePort->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s sincenodePort not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ node->nodePort = (uint16_t)nodePort->valueint;
+
+ cJSON *nodeFqdn = cJSON_GetObjectItem(nodeInfo, "fqdn");
+ if (!nodeFqdn || nodeFqdn->type != cJSON_String || nodeFqdn->valuestring == NULL) {
+ vError("vgId:%d, failed to read %s since nodeFqdn not found", vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ tstrncpy(node->nodeFqdn, nodeFqdn->valuestring, TSDB_FQDN_LEN);
+ }
+
+ ret = TSDB_CODE_SUCCESS;
+
+PARSE_VCFG_ERROR:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+
+ terrno = 0;
+ return ret;
+}
+
+int32_t vnodeWriteCfg(int32_t vgId, SVnodeCfg *pCfg) {
+ int32_t code = 0;
+ char file[PATH_MAX + 30] = {0};
+ sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, vgId);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ vError("vgId:%d, failed to write %s error:%s", vgId, file, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ return terrno;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 1000;
+ char *content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ // vnode
+ len += snprintf(content + len, maxLen - len, " \"vgId\": %d,\n", vgId);
+ len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pCfg->db);
+ len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pCfg->dropped);
+ len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pCfg->quorum);
+ // tsdb
+ len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pCfg->tsdb.cacheBlockSize);
+ len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pCfg->tsdb.totalBlocks);
+ len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pCfg->tsdb.daysPerFile);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep0\": %d,\n", pCfg->tsdb.daysToKeep0);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pCfg->tsdb.daysToKeep1);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pCfg->tsdb.daysToKeep2);
+ len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pCfg->tsdb.minRowsPerFileBlock);
+ len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pCfg->tsdb.maxRowsPerFileBlock);
+ len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pCfg->tsdb.precision);
+ len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pCfg->tsdb.compression);
+ len += snprintf(content + len, maxLen - len, " \"cacheLastRow\": %d,\n", pCfg->tsdb.cacheLastRow);
+ len += snprintf(content + len, maxLen - len, " \"update\": %d,\n", pCfg->tsdb.update);
+ // wal
+ len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pCfg->wal.walLevel);
+ len += snprintf(content + len, maxLen - len, " \"fsyncPeriod\": %d,\n", pCfg->wal.fsyncPeriod);
+ // sync
+ len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pCfg->sync.replica);
+ len += snprintf(content + len, maxLen - len, " \"selfIndex\": %d,\n", pCfg->sync.selfIndex);
+ len += snprintf(content + len, maxLen - len, " \"nodes\": [{\n");
+ for (int32_t i = 0; i < pCfg->sync.replica; i++) {
+ SNodeInfo *node = &pCfg->sync.nodeInfo[i];
+ len += snprintf(content + len, maxLen - len, " \"id\": %d,\n", node->nodeId);
+ len += snprintf(content + len, maxLen - len, " \"port\": %u,\n", node->nodePort);
+ len += snprintf(content + len, maxLen - len, " \"fqdn\": \"%s\"\n", node->nodeFqdn);
+ if (i < pCfg->sync.replica - 1) {
+ len += snprintf(content + len, maxLen - len, " },{\n");
+ } else {
+ len += snprintf(content + len, maxLen - len, " }]\n");
+ }
+ }
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ taosFsyncFile(fileno(fp));
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ vInfo("vgId:%d, successed to write %s", vgId, file);
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t vnodeReadState(int32_t vgId, SSyncServerState *pState) {
+ int32_t ret = TSDB_CODE_VND_APP_ERROR;
+ int32_t len = 0;
+ int32_t maxLen = 100;
+ char *content = calloc(1, maxLen + 1);
+ cJSON *root = NULL;
+ FILE *fp = NULL;
+
+ char file[PATH_MAX + 30] = {0};
+ sprintf(file, "%s/vnode%d/state.json", tsVnodeDir, vgId);
+
+ len = (int32_t)fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ vError("vgId:%d, failed to read %s since content is null", vgId, file);
+ goto PARSE_TERM_ERROR;
+ }
+
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ vError("vgId:%d, failed to read %s since invalid json format", vgId, file);
+ goto PARSE_TERM_ERROR;
+ }
+
+ cJSON *term = cJSON_GetObjectItem(root, "term");
+ if (!term || term->type != cJSON_String) {
+ vError("vgId:%d, failed to read %s since term not found", vgId, file);
+ goto PARSE_TERM_ERROR;
+ }
+ pState->term = atoll(term->valuestring);
+
+ cJSON *voteFor = cJSON_GetObjectItem(root, "voteFor");
+ if (!voteFor || voteFor->type != cJSON_String) {
+ vError("vgId:%d, failed to read %s since voteFor not found", vgId, file);
+ goto PARSE_TERM_ERROR;
+ }
+ pState->voteFor = atoi(voteFor->valuestring);
+
+ vInfo("vgId:%d, read %s success, voteFor:%d, term:%" PRIu64, vgId, file, pState->voteFor, pState->term);
+
+PARSE_TERM_ERROR:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+
+ return ret;
+}
+
+int32_t vnodeSaveState(int32_t vgId, SSyncServerState *pState) {
+ char file[PATH_MAX + 30] = {0};
+ sprintf(file, "%s/vnode%d/state.json", tsVnodeDir, vgId);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ vError("vgId:%d, failed to write %s since %s", vgId, file, strerror(errno));
+ return -1;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 100;
+ char *content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"term\": \"%" PRIu64 "\",\n", pState->term);
+ len += snprintf(content + len, maxLen - len, " \"voteFor\": \"%d\"\n", pState->voteFor);
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ taosFsyncFile(fileno(fp));
+ fclose(fp);
+ free(content);
+
+ vInfo("vgId:%d, write %s success, voteFor:%d, term:%" PRIu64, vgId, file, pState->voteFor, pState->term);
+ return TSDB_CODE_SUCCESS;
+}
\ No newline at end of file
diff --git a/source/server/vnode/src/vnodeInt.c b/source/server/vnode/src/vnodeInt.c
index 7ec5200e5d..9e1739a68e 100644
--- a/source/server/vnode/src/vnodeInt.c
+++ b/source/server/vnode/src/vnodeInt.c
@@ -14,935 +14,78 @@
*/
#define _DEFAULT_SOURCE
-#include "tglobal.h"
-#include "ttimer.h"
-#include "thash.h"
-// #include "query.h"
-#include "vnodeCfg.h"
-#include "vnodeMgmt.h"
-#include "vnodeRead.h"
-#include "vnodeStatus.h"
-#include "vnodeVersion.h"
-#include "vnodeWorker.h"
-#include "vnodeWrite.h"
+#include "os.h"
#include "tstep.h"
+#include "vnodeMain.h"
#include "vnodeMgmt.h"
#include "vnodeRead.h"
-#include "vnodeWorker.h"
#include "vnodeWrite.h"
-typedef struct {
- pthread_t thread;
- int32_t threadIndex;
- int32_t failed;
- int32_t opened;
- int32_t vnodeNum;
- int32_t * vnodeList;
-} SOpenVnodeThread;
-
static struct {
SSteps *steps;
SVnodeFp fp;
- void * timer;
- SHashObj *hash;
- int32_t openVnodes;
- int32_t totalVnodes;
void (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
-} tsVnode;
+} tsVint;
void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port) {
- return (*tsVnode.fp.GetDnodeEp)(dnodeId, ep, fqdn, port);
+ return (*tsVint.fp.GetDnodeEp)(dnodeId, ep, fqdn, port);
}
void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg) {
- (*tsVnode.fp.SendMsgToDnode)(epSet, rpcMsg);
+ (*tsVint.fp.SendMsgToDnode)(epSet, rpcMsg);
}
-void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg) { return (*tsVnode.fp.SendMsgToMnode)(rpcMsg); }
+void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg) { return (*tsVint.fp.SendMsgToMnode)(rpcMsg); }
-static void vnodeIncRef(void *ptNode) {
- assert(ptNode != NULL);
-
- SVnode **ppVnode = (SVnode **)ptNode;
- assert(ppVnode);
- assert(*ppVnode);
-
- SVnode *pVnode = *ppVnode;
- atomic_add_fetch_32(&pVnode->refCount, 1);
- vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
-}
-
-SVnode *vnodeAcquire(int32_t vgId) {
- SVnode *pVnode = NULL;
-
- // taosHashGetClone(tsVnode.hash, &vgId, sizeof(int32_t), vnodeIncRef, (void*)&pVnode);
- if (pVnode == NULL) {
- terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
- vDebug("vgId:%d, not exist", vgId);
- return NULL;
- }
-
- return pVnode;
-}
-
-SVnode *vnodeAcquireNotClose(int32_t vgId) {
- // SVnode *pVnode = vnodeAcquire(vgId);
- // if (pVnode != NULL && pVnode->preClose == 1) {
- // vnodeRelease(pVnode);
- // terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
- // vDebug("vgId:%d, not exist, pre closing", vgId);
- // return NULL;
- // }
-
- // return pVnode;
- return NULL;
-}
-
-void vnodeRelease(SVnode *pVnode) {
- if (pVnode == NULL) return;
-
- int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
- int32_t vgId = pVnode->vgId;
-
- vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", vgId, refCount, pVnode);
- assert(refCount >= 0);
-
- if (refCount <= 0) {
- vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", vgId, refCount, pVnode);
- vnodeProcessDestroyTask(pVnode);
- int32_t count = taosHashGetSize(tsVnode.hash);
- vDebug("vgId:%d, vnode is destroyed, vnodes:%d", vgId, count);
- }
-}
-
-static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
-
-int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
- int32_t code;
-
- SVnode *pVnode = vnodeAcquire(pVnodeCfg->cfg.vgId);
- if (pVnode != NULL) {
- vDebug("vgId:%d, vnode already exist, refCount:%d pVnode:%p", pVnodeCfg->cfg.vgId, pVnode->refCount, pVnode);
- vnodeRelease(pVnode);
- return TSDB_CODE_SUCCESS;
- }
-
-#if 0
- if (tfsMkdir("vnode") < 0) {
- vError("vgId:%d, failed to create vnode dir, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
- return terrno;
- }
-
- char vnodeDir[TSDB_FILENAME_LEN] = "\0";
- snprintf(vnodeDir, TSDB_FILENAME_LEN, "/vnode/vnode%d", pVnodeCfg->cfg.vgId);
- if (tfsMkdir(vnodeDir) < 0) {
- vError("vgId:%d, failed to create vnode dir %s, reason:%s", pVnodeCfg->cfg.vgId, vnodeDir, strerror(errno));
- return terrno;
- }
-
- code = vnodeWriteCfg(pVnodeCfg);
- if (code != TSDB_CODE_SUCCESS) {
- vError("vgId:%d, failed to save vnode cfg, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(code));
- return code;
- }
-
- if (tsdbCreateRepo(pVnodeCfg->cfg.vgId) < 0) {
- vError("vgId:%d, failed to create tsdb in vnode, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
- return TSDB_CODE_VND_INIT_FAILED;
- }
-#endif
- vInfo("vgId:%d, vnode dir is created, walLevel:%d fsyncPeriod:%d", pVnodeCfg->cfg.vgId, pVnodeCfg->cfg.walLevel,
- pVnodeCfg->cfg.fsyncPeriod);
- code = vnodeOpen(pVnodeCfg->cfg.vgId);
-
- return code;
-}
-
-int32_t vnodeSync(int32_t vgId) {
-#if 0
- SVnode *pVnode = vnodeAcquireNotClose(vgId);
- if (pVnode == NULL) {
- vDebug("vgId:%d, failed to sync, vnode not find", vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
-
- if (pVnode->role == TAOS_SYNC_ROLE_SLAVE) {
- vInfo("vgId:%d, vnode will sync, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
-
- pVnode->version = 0;
- pVnode->fversion = 0;
- walResetVersion(pVnode->wal, pVnode->fversion);
-
- syncRecover(pVnode->sync);
- }
-
- vnodeRelease(pVnode);
-#endif
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t vnodeDrop(int32_t vgId) {
- SVnode *pVnode = vnodeAcquireNotClose(vgId);
- if (pVnode == NULL) {
- vDebug("vgId:%d, failed to drop, vnode not find", vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
- if (pVnode->dropped) {
- vnodeRelease(pVnode);
- return TSDB_CODE_SUCCESS;
- }
-
- vInfo("vgId:%d, vnode will be dropped, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
- pVnode->dropped = 1;
-
- vnodeRelease(pVnode);
- vnodeProcessCleanupTask(pVnode);
-
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t vnodeCompact(int32_t vgId) {
-#if 0
- SVnode *pVnode = vnodeAcquire(vgId);
- if (pVnode != NULL) {
- vDebug("vgId:%d, compact vnode msg is received", vgId);
- // not care success or not
- tsdbCompact(((SVnode *)pVnode)->tsdb);
- vnodeRelease(pVnode);
- } else {
- vInfo("vgId:%d, vnode not exist, can't compact it", vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
-#endif
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t vnodeAlterImp(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg) {
-#if 0
- STsdbCfg tsdbCfg = pVnode->tsdbCfg;
- SSyncCfg syncCfg = pVnode->syncCfg;
- int32_t dbCfgVersion = pVnode->dbCfgVersion;
- int32_t vgCfgVersion = pVnode->vgCfgVersion;
-
- int32_t code = vnodeWriteCfg(pVnodeCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- return code;
- }
-
- code = vnodeReadCfg(pVnode);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- return code;
- }
-
- code = walAlter(pVnode->wal, &pVnode->walCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- return code;
- }
-
- bool tsdbCfgChanged = (memcmp(&tsdbCfg, &pVnode->tsdbCfg, sizeof(STsdbCfg)) != 0);
- bool syncCfgChanged = (memcmp(&syncCfg, &pVnode->syncCfg, sizeof(SSyncCfg)) != 0);
-
- vDebug("vgId:%d, tsdbchanged:%d syncchanged:%d while alter vnode", pVnode->vgId, tsdbCfgChanged, syncCfgChanged);
-
- if (tsdbCfgChanged || syncCfgChanged) {
- // vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
- // dbCfgVersion can be corrected by status msg
- if (syncCfgChanged) {
- if (!vnodeSetUpdatingStatus(pVnode)) {
- vDebug("vgId:%d, vnode is not ready, do alter operation later", pVnode->vgId);
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- return TSDB_CODE_SUCCESS;
- }
-
- code = syncReconfig(pVnode->sync, &pVnode->syncCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- vnodeSetReadyStatus(pVnode);
- return code;
- }
- }
-
- if (tsdbCfgChanged && pVnode->tsdb) {
- code = tsdbConfigRepo(pVnode->tsdb, &pVnode->tsdbCfg);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->dbCfgVersion = dbCfgVersion;
- pVnode->vgCfgVersion = vgCfgVersion;
- pVnode->syncCfg = syncCfg;
- pVnode->tsdbCfg = tsdbCfg;
- vnodeSetReadyStatus(pVnode);
- return code;
- }
- }
-
- vnodeSetReadyStatus(pVnode);
- }
-#endif
- return 0;
-}
-
-int32_t vnodeAlter(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg) {
-#if 0
- vDebug("vgId:%d, current dbCfgVersion:%d vgCfgVersion:%d, input dbCfgVersion:%d vgCfgVersion:%d", pVnode->vgId,
- pVnode->dbCfgVersion, pVnode->vgCfgVersion, pVnodeCfg->cfg.dbCfgVersion, pVnodeCfg->cfg.vgCfgVersion);
-
- if (pVnode->dbCfgVersion == pVnodeCfg->cfg.dbCfgVersion && pVnode->vgCfgVersion == pVnodeCfg->cfg.vgCfgVersion) {
- vDebug("vgId:%d, cfg not change", pVnode->vgId);
- return TSDB_CODE_SUCCESS;
- }
-
- int32_t code = vnodeAlterImp(pVnode, pVnodeCfg);
-
- if (code != 0) {
- vError("vgId:%d, failed to alter vnode, code:0x%x", pVnode->vgId, code);
- } else {
- vDebug("vgId:%d, vnode is altered", pVnode->vgId);
- }
-
- return code;
-#endif
- return 0;
-}
-
-static void vnodeFindWalRootDir(int32_t vgId, char *walRootDir) {
-#if 0
- char vnodeDir[TSDB_FILENAME_LEN] = "\0";
- snprintf(vnodeDir, TSDB_FILENAME_LEN, "/vnode/vnode%d/wal", vgId);
-
- TDIR *tdir = tfsOpendir(vnodeDir);
- if (!tdir) return;
-
- const TFILE *tfile = tfsReaddir(tdir);
- if (!tfile) {
- tfsClosedir(tdir);
- return;
- }
-
- sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(tfile->level, tfile->id), vgId);
-
- tfsClosedir(tdir);
-#endif
-}
-
-int32_t vnodeOpen(int32_t vgId) {
-#if 0
- char temp[TSDB_FILENAME_LEN * 3];
- char rootDir[TSDB_FILENAME_LEN * 2];
- char walRootDir[TSDB_FILENAME_LEN * 2] = {0};
- snprintf(rootDir, TSDB_FILENAME_LEN * 2, "%s/vnode%d", tsVnodeDir, vgId);
-
- SVnode *pVnode = calloc(sizeof(SVnode), 1);
- if (pVnode == NULL) {
- vError("vgId:%d, failed to open vnode since no enough memory", vgId);
- return TAOS_SYSTEM_ERROR(errno);
- }
-
- atomic_add_fetch_32(&pVnode->refCount, 1);
-
- pVnode->vgId = vgId;
- pVnode->fversion = 0;
- pVnode->version = 0;
- pVnode->tsdbCfg.tsdbId = pVnode->vgId;
- pVnode->rootDir = strdup(rootDir);
- pVnode->accessState = TSDB_VN_ALL_ACCCESS;
- tsem_init(&pVnode->sem, 0, 0);
- pthread_mutex_init(&pVnode->statusMutex, NULL);
- vnodeSetInitStatus(pVnode);
-
- tsdbIncCommitRef(pVnode->vgId);
-
- int32_t code = vnodeReadCfg(pVnode);
- if (code != TSDB_CODE_SUCCESS) {
- vError("vgId:%d, failed to read config file, set cfgVersion to 0", pVnode->vgId);
- vnodeCleanUp(pVnode);
- return 0;
- }
-
- code = vnodeReadVersion(pVnode);
- if (code != TSDB_CODE_SUCCESS) {
- pVnode->version = 0;
- vError("vgId:%d, failed to read file version, generate it from data file", pVnode->vgId);
- // Allow vnode start even when read file version fails, set file version as wal version or zero
- // vnodeCleanUp(pVnode);
- // return code;
- }
-
- pVnode->fversion = pVnode->version;
-
- pVnode->pWriteQ = vnodeAllocWriteQueue(pVnode);
- pVnode->pQueryQ = vnodeAllocQueryQueue(pVnode);
- pVnode->pFetchQ = vnodeAllocFetchQueue(pVnode);
- if (pVnode->pWriteQ == NULL || pVnode->pQueryQ == NULL || pVnode->pFetchQ == NULL) {
- vnodeCleanUp(pVnode);
- return terrno;
- }
-
- STsdbAppH appH = {0};
- appH.appH = (void *)pVnode;
- appH.notifyStatus = vnodeProcessTsdbStatus;
- appH.cqH = pVnode->cq;
- appH.cqCreateFunc = cqCreate;
- appH.cqDropFunc = cqDrop;
-
- terrno = 0;
- pVnode->tsdb = tsdbOpenRepo(&(pVnode->tsdbCfg), &appH);
- if (pVnode->tsdb == NULL) {
- vnodeCleanUp(pVnode);
- return terrno;
- } else if (tsdbGetState(pVnode->tsdb) != TSDB_STATE_OK) {
- vError("vgId:%d, failed to open tsdb(state: %d), replica:%d reason:%s", pVnode->vgId, tsdbGetState(pVnode->tsdb),
- pVnode->syncCfg.replica, tstrerror(terrno));
- if (pVnode->syncCfg.replica <= 1) {
- vnodeCleanUp(pVnode);
- return TSDB_CODE_VND_INVALID_TSDB_STATE;
- } else {
- pVnode->fversion = 0;
- pVnode->version = 0;
- }
- }
-
- // walRootDir for wal & syncInfo.path (not empty dir of /vnode/vnode{pVnode->vgId}/wal)
- vnodeFindWalRootDir(pVnode->vgId, walRootDir);
- if (walRootDir[0] == 0) {
- int level = -1, id = -1;
-
- tfsAllocDisk(TFS_PRIMARY_LEVEL, &level, &id);
- if (level < 0 || id < 0) {
- vnodeCleanUp(pVnode);
- return terrno;
- }
-
- sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(level, id), vgId);
- }
-
- sprintf(temp, "%s/wal", walRootDir);
- pVnode->walCfg.vgId = pVnode->vgId;
- pVnode->wal = walOpen(temp, &pVnode->walCfg);
- if (pVnode->wal == NULL) {
- vnodeCleanUp(pVnode);
- return terrno;
- }
-
- walRestore(pVnode->wal, pVnode, (FWalWrite)vnodeProcessWalMsg);
- if (pVnode->version == 0) {
- pVnode->fversion = 0;
- pVnode->version = walGetVersion(pVnode->wal);
- }
-
- code = tsdbSyncCommit(pVnode->tsdb);
- if (code != 0) {
- vError("vgId:%d, failed to commit after restore from wal since %s", pVnode->vgId, tstrerror(code));
- vnodeCleanUp(pVnode);
- return code;
- }
-
- walRemoveAllOldFiles(pVnode->wal);
- walRenew(pVnode->wal);
-
- pVnode->qMgmt = qOpenQueryMgmt(pVnode->vgId);
- if (pVnode->qMgmt == NULL) {
- vnodeCleanUp(pVnode);
- return terrno;
- }
-
- pVnode->events = NULL;
-
- vDebug("vgId:%d, vnode is opened in %s - %s, pVnode:%p", pVnode->vgId, rootDir, walRootDir, pVnode);
-
- taosHashPut(tsVnode.hash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnode *));
-
- vnodeSetReadyStatus(pVnode);
- pVnode->role = TAOS_SYNC_ROLE_MASTER;
-#endif
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t vnodeClose(int32_t vgId) {
- SVnode *pVnode = vnodeAcquireNotClose(vgId);
- if (pVnode == NULL) return 0;
- if (pVnode->dropped) {
- vnodeRelease(pVnode);
- return 0;
- }
-
- // pVnode->preClose = 1;
-
- vDebug("vgId:%d, vnode will be closed, pVnode:%p", pVnode->vgId, pVnode);
- vnodeRelease(pVnode);
- vnodeCleanUp(pVnode);
-
- return 0;
-}
-
-void vnodeDestroy(SVnode *pVnode) {
-#if 0
- int32_t code = 0;
- int32_t vgId = pVnode->vgId;
-
- if (pVnode->qMgmt) {
- qCleanupQueryMgmt(pVnode->qMgmt);
- pVnode->qMgmt = NULL;
- }
-
- if (pVnode->wal) {
- walStop(pVnode->wal);
- }
-
- if (pVnode->tsdb) {
- // the deleted vnode does not need to commit, so as to speed up the deletion
- int toCommit = 1;
- if (pVnode->dropped) toCommit = 0;
-
- code = tsdbCloseRepo(pVnode->tsdb, toCommit);
- pVnode->tsdb = NULL;
- }
-
- // stop continuous query
- if (pVnode->cq) {
- void *cq = pVnode->cq;
- pVnode->cq = NULL;
- cqClose(cq);
- }
-
- if (pVnode->wal) {
- if (code != 0) {
- vError("vgId:%d, failed to commit while close tsdb repo, keep wal", pVnode->vgId);
- } else {
- walRemoveAllOldFiles(pVnode->wal);
- }
- walClose(pVnode->wal);
- pVnode->wal = NULL;
- }
-
- if (pVnode->pWriteQ) {
- vnodeFreeWriteQueue(pVnode->pWriteQ);
- pVnode->pWriteQ = NULL;
- }
-
- if (pVnode->pQueryQ) {
- vnodeFreeQueryQueue(pVnode->pQueryQ);
- pVnode->pQueryQ = NULL;
- }
-
- if (pVnode->pFetchQ) {
- vnodeFreeFetchQueue(pVnode->pFetchQ);
- pVnode->pFetchQ = NULL;
- }
-
- tfree(pVnode->rootDir);
-
- if (pVnode->dropped) {
- char rootDir[TSDB_FILENAME_LEN] = {0};
- char stagingDir[TSDB_FILENAME_LEN] = {0};
- sprintf(rootDir, "%s/vnode%d", "vnode", vgId);
- sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
-
- tfsRename(rootDir, stagingDir);
-
- vnodeProcessBackupTask(pVnode);
-
- // dnodeSendStatusMsgToMnode();
- }
-
- tsem_destroy(&pVnode->sem);
- pthread_mutex_destroy(&pVnode->statusMutex);
- free(pVnode);
- tsdbDecCommitRef(vgId);
-#endif
-}
-
-void vnodeCleanUp(SVnode *pVnode) {
-#if 0
- vDebug("vgId:%d, vnode will cleanup, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
-
- vnodeSetClosingStatus(pVnode);
-
- taosHashRemove(tsVnode.hash, &pVnode->vgId, sizeof(int32_t));
-
- // stop replication module
- if (pVnode->sync > 0) {
- int64_t sync = pVnode->sync;
- pVnode->sync = -1;
- syncStop(sync);
- }
-
- vDebug("vgId:%d, vnode is cleaned, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
- vnodeRelease(pVnode);
-#endif
-}
-
-#if 0
-static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) {
- SVnode *pVnode = arg;
-
- if (eno != TSDB_CODE_SUCCESS) {
- vError("vgId:%d, failed to commit since %s, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, tstrerror(eno),
- pVnode->fversion, pVnode->version);
- pVnode->isCommiting = 0;
- pVnode->isFull = 1;
- return 0;
- }
-
- if (status == TSDB_STATUS_COMMIT_START) {
- pVnode->isCommiting = 1;
- pVnode->cversion = pVnode->version;
- vInfo("vgId:%d, start commit, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
- if (!vnodeInInitStatus(pVnode)) {
- return walRenew(pVnode->wal);
- }
- return 0;
- }
-
- if (status == TSDB_STATUS_COMMIT_OVER) {
- pVnode->isCommiting = 0;
- pVnode->isFull = 0;
- pVnode->fversion = pVnode->cversion;
- vInfo("vgId:%d, commit over, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
- if (!vnodeInInitStatus(pVnode)) {
- walRemoveOneOldFile(pVnode->wal);
- }
- return vnodeSaveVersion(pVnode);
- }
-
- // timer thread callback
- if (status == TSDB_STATUS_COMMIT_NOBLOCK) {
- qSolveCommitNoBlock(pVnode->tsdb, pVnode->qMgmt);
- }
-
- return 0;
-}
-#endif
-
-static void *vnodeOpenVnode(void *param) {
- SOpenVnodeThread *pThread = param;
-
- vDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
- setThreadName("vnodeOpenVnode");
-
- for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
- int32_t vgId = pThread->vnodeList[v];
-
- char stepDesc[TSDB_STEP_DESC_LEN] = {0};
- snprintf(stepDesc, TSDB_STEP_DESC_LEN, "vgId:%d, start to restore, %d of %d have been opened", vgId,
- tsVnode.openVnodes, tsVnode.totalVnodes);
- // (*vnodeInst()->fp.ReportStartup)("open-vnodes", stepDesc);
-
- if (vnodeOpen(vgId) < 0) {
- vError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
- pThread->failed++;
- } else {
- vDebug("vgId:%d, is opened by thread:%d", vgId, pThread->threadIndex);
- pThread->opened++;
- }
-
- atomic_add_fetch_32(&tsVnode.openVnodes, 1);
- }
-
- vDebug("thread:%d, total vnodes:%d, opened:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
- pThread->failed);
- return NULL;
-}
-
-static int32_t vnodeGetVnodeListFromDisk(int32_t vnodeList[], int32_t *numOfVnodes) {
-#if 0
- DIR *dir = opendir(tsVnodeDir);
- if (dir == NULL) return TSDB_CODE_DND_NO_WRITE_ACCESS;
-
- *numOfVnodes = 0;
- struct dirent *de = NULL;
- while ((de = readdir(dir)) != NULL) {
- if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
- if (de->d_type & DT_DIR) {
- if (strncmp("vnode", de->d_name, 5) != 0) continue;
- int32_t vnode = atoi(de->d_name + 5);
- if (vnode == 0) continue;
-
- (*numOfVnodes)++;
-
- if (*numOfVnodes >= TSDB_MAX_VNODES) {
- vError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
- closedir(dir);
- return TSDB_CODE_DND_TOO_MANY_VNODES;
- } else {
- vnodeList[*numOfVnodes - 1] = vnode;
- }
- }
- }
- closedir(dir);
-#endif
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t vnodeOpenVnodes() {
- int32_t vnodeList[TSDB_MAX_VNODES] = {0};
- int32_t numOfVnodes = 0;
- int32_t status = vnodeGetVnodeListFromDisk(vnodeList, &numOfVnodes);
-
- if (status != TSDB_CODE_SUCCESS) {
- vInfo("failed to get vnode list from disk since code:%d", status);
- return status;
- }
-
- tsVnode.totalVnodes = numOfVnodes;
-
- int32_t threadNum = tsNumOfCores;
- int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
-
- SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
- for (int32_t t = 0; t < threadNum; ++t) {
- threads[t].threadIndex = t;
- threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
- }
-
- for (int32_t v = 0; v < numOfVnodes; ++v) {
- int32_t t = v % threadNum;
- SOpenVnodeThread *pThread = &threads[t];
- pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
- }
-
- vInfo("start %d threads to open %d vnodes", threadNum, numOfVnodes);
-
- for (int32_t t = 0; t < threadNum; ++t) {
- SOpenVnodeThread *pThread = &threads[t];
- if (pThread->vnodeNum == 0) continue;
-
- pthread_attr_t thAttr;
- pthread_attr_init(&thAttr);
- pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
- if (pthread_create(&pThread->thread, &thAttr, vnodeOpenVnode, pThread) != 0) {
- vError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
- }
-
- pthread_attr_destroy(&thAttr);
- }
-
- int32_t openVnodes = 0;
- int32_t failedVnodes = 0;
- for (int32_t t = 0; t < threadNum; ++t) {
- SOpenVnodeThread *pThread = &threads[t];
- if (pThread->vnodeNum > 0 && taosCheckPthreadValid(pThread->thread)) {
- pthread_join(pThread->thread, NULL);
- }
- openVnodes += pThread->opened;
- failedVnodes += pThread->failed;
- free(pThread->vnodeList);
- }
-
- free(threads);
- vInfo("there are total vnodes:%d, opened:%d", numOfVnodes, openVnodes);
-
- if (failedVnodes != 0) {
- vError("there are total vnodes:%d, failed:%d", numOfVnodes, failedVnodes);
- return -1;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
- void *pIter = taosHashIterate(tsVnode.hash, NULL);
- while (pIter) {
- SVnode **pVnode = pIter;
- if (*pVnode) {
- (*numOfVnodes)++;
- if (*numOfVnodes >= TSDB_MAX_VNODES) {
- vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
- continue;
- } else {
- vnodeList[*numOfVnodes - 1] = (*pVnode)->vgId;
- }
- }
-
- pIter = taosHashIterate(tsVnode.hash, pIter);
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-static void vnodeCleanupVnodes() {
- int32_t vnodeList[TSDB_MAX_VNODES] = {0};
- int32_t numOfVnodes = 0;
-
- int32_t code = vnodeGetVnodeList(vnodeList, &numOfVnodes);
-
- if (code != TSDB_CODE_SUCCESS) {
- vInfo("failed to get dnode list since code %d", code);
- return;
- }
-
- for (int32_t i = 0; i < numOfVnodes; ++i) {
- vnodeClose(vnodeList[i]);
- }
-
- vInfo("total vnodes:%d are all closed", numOfVnodes);
-}
-
-static void vnodeInitMsgFp() {
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessMgmtMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_SUBMIT] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = vnodeProcessWriteMsg;
- //mq related
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_ACK] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_RESET] = vnodeProcessWriteMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_QUERY] = vnodeProcessReadMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = vnodeProcessReadMsg;
- //mq related end
- tsVnode.msgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessReadMsg;
- tsVnode.msgFp[TSDB_MSG_TYPE_FETCH] = vnodeProcessReadMsg;
-}
+void vnodeReportStartup(char *name, char *desc) { (*tsVint.fp.ReportStartup)(name, desc); }
void vnodeProcessMsg(SRpcMsg *pMsg) {
- if (tsVnode.msgFp[pMsg->msgType]) {
- (*tsVnode.msgFp[pMsg->msgType])(pMsg);
+ if (tsVint.msgFp[pMsg->msgType]) {
+ (*tsVint.msgFp[pMsg->msgType])(pMsg);
} else {
assert(0);
}
}
-int32_t vnodeInitMain() {
- vnodeInitMsgFp();
-
- tsVnode.timer = taosTmrInit(100, 200, 60000, "VND-TIMER");
- if (tsVnode.timer == NULL) {
- vError("failed to init vnode timer");
- return -1;
- }
-
- tsVnode.hash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
- if (tsVnode.hash == NULL) {
- taosTmrCleanUp(tsVnode.timer);
- vError("failed to init vnode mgmt");
- return -1;
- }
-
- vInfo("vnode main is initialized");
- return vnodeOpenVnodes();
-}
-
-void vnodeCleanupMain() {
- taosTmrCleanUp(tsVnode.timer);
- tsVnode.timer = NULL;
-
- vnodeCleanupVnodes();
-
- taosHashCleanup(tsVnode.hash);
- tsVnode.hash = NULL;
-}
-
-static void vnodeBuildVloadMsg(SVnode *pVnode, SStatusMsg *pStatus) {
-#if 0
- int64_t totalStorage = 0;
- int64_t compStorage = 0;
- int64_t pointsWritten = 0;
-
- if (vnodeInClosingStatus(pVnode)) return;
- if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
-
- if (pVnode->tsdb) {
- tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
- }
-
- SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
- pLoad->vgId = htonl(pVnode->vgId);
- pLoad->dbCfgVersion = htonl(pVnode->dbCfgVersion);
- pLoad->vgCfgVersion = htonl(pVnode->vgCfgVersion);
- pLoad->totalStorage = htobe64(totalStorage);
- pLoad->compStorage = htobe64(compStorage);
- pLoad->pointsWritten = htobe64(pointsWritten);
- pLoad->vnodeVersion = htobe64(pVnode->version);
- pLoad->status = pVnode->status;
- pLoad->role = pVnode->role;
- pLoad->replica = pVnode->syncCfg.replica;
- pLoad->compact = (pVnode->tsdb != NULL) ? tsdbGetCompactState(pVnode->tsdb) : 0;
-#endif
-}
-
-void vnodeGetStatus(struct SStatusMsg *pStatus) {
- void *pIter = taosHashIterate(tsVnode.hash, NULL);
- while (pIter) {
- SVnode **pVnode = pIter;
- if (*pVnode) {
- vnodeBuildVloadMsg(*pVnode, pStatus);
- }
- pIter = taosHashIterate(tsVnode.hash, pIter);
- }
-}
-
-void vnodeSetAccess(struct SVgroupAccess *pAccess, int32_t numOfVnodes) {
- for (int32_t i = 0; i < numOfVnodes; ++i) {
- pAccess[i].vgId = htonl(pAccess[i].vgId);
- SVnode *pVnode = vnodeAcquireNotClose(pAccess[i].vgId);
- if (pVnode != NULL) {
- pVnode->accessState = pAccess[i].accessState;
- if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
- vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
- }
- vnodeRelease(pVnode);
- }
- }
-}
-
-void vnodeBackup(int32_t vgId) {
- char newDir[TSDB_FILENAME_LEN] = {0};
- char stagingDir[TSDB_FILENAME_LEN] = {0};
-
- sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId);
- sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
-
-#if 0
- if (tsEnableVnodeBak) {
- tfsRmdir(newDir);
- tfsRename(stagingDir, newDir);
- } else {
- vInfo("vgId:%d, vnode backup not enabled", vgId);
-
- tfsRmdir(stagingDir);
- }
-#endif
+static void vnodeInitMsgFp() {
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessMgmtMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_SUBMIT] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = vnodeProcessWriteMsg;
+ // mq related
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_ACK] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_RESET] = vnodeProcessWriteMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_QUERY] = vnodeProcessReadMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = vnodeProcessReadMsg;
+ // mq related end
+ tsVint.msgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessReadMsg;
+ tsVint.msgFp[TSDB_MSG_TYPE_FETCH] = vnodeProcessReadMsg;
}
int32_t vnodeInit(SVnodePara para) {
- tsVnode.fp = para.fp;
+ vnodeInitMsgFp();
+ tsVint.fp = para.fp;
struct SSteps *steps = taosStepInit(8, NULL);
if (steps == NULL) return -1;
taosStepAdd(steps, "vnode-main", vnodeInitMain, vnodeCleanupMain);
- taosStepAdd(steps, "vnode-worker", vnodeInitWorker, vnodeCleanupWorker);
taosStepAdd(steps, "vnode-read", vnodeInitRead, vnodeCleanupRead);
taosStepAdd(steps, "vnode-mgmt", vnodeInitMgmt, vnodeCleanupMgmt);
taosStepAdd(steps, "vnode-write", vnodeInitWrite, vnodeCleanupWrite);
- tsVnode.steps = steps;
- return taosStepExec(tsVnode.steps);
+ tsVint.steps = steps;
+ return taosStepExec(tsVint.steps);
}
-void vnodeCleanup() { taosStepCleanup(tsVnode.steps); }
+void vnodeCleanup() { taosStepCleanup(tsVint.steps); }
diff --git a/source/server/vnode/src/vnodeMain.c b/source/server/vnode/src/vnodeMain.c
new file mode 100644
index 0000000000..ced93ea6a7
--- /dev/null
+++ b/source/server/vnode/src/vnodeMain.c
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "thash.h"
+#include "tthread.h"
+#include "vnodeFile.h"
+#include "vnodeMain.h"
+#include "vnodeMgmt.h"
+#include "vnodeRead.h"
+#include "vnodeWrite.h"
+
+typedef enum _VN_STATUS {
+ TAOS_VN_STATUS_INIT = 0,
+ TAOS_VN_STATUS_READY = 1,
+ TAOS_VN_STATUS_CLOSING = 2,
+ TAOS_VN_STATUS_UPDATING = 3
+} EVnodeStatus;
+
+char *vnodeStatus[] = {"init", "ready", "closing", "updating"};
+
+typedef struct {
+ pthread_t *threadId;
+ int32_t threadIndex;
+ int32_t failed;
+ int32_t opened;
+ int32_t vnodeNum;
+ int32_t *vnodeList;
+} SOpenVnodeThread;
+
+static struct {
+ SHashObj *hash;
+ int32_t openVnodes;
+ int32_t totalVnodes;
+} tsVnode;
+
+static bool vnodeSetInitStatus(SVnode *pVnode) {
+ pthread_mutex_lock(&pVnode->statusMutex);
+ pVnode->status = TAOS_VN_STATUS_INIT;
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return true;
+}
+
+static bool vnodeSetReadyStatus(SVnode *pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_UPDATING) {
+ pVnode->status = TAOS_VN_STATUS_READY;
+ set = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+static bool vnodeSetUpdatingStatus(SVnode *pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_READY) {
+ pVnode->status = TAOS_VN_STATUS_UPDATING;
+ set = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+static bool vnodeSetClosingStatus(SVnode *pVnode) {
+ bool set = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_READY) {
+ pVnode->status = TAOS_VN_STATUS_CLOSING;
+ set = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return set;
+}
+
+static bool vnodeInStatus(SVnode *pVnode, EVnodeStatus status) {
+ bool in = false;
+ pthread_mutex_lock(&pVnode->statusMutex);
+
+ if (pVnode->status == status) {
+ in = true;
+ }
+
+ pthread_mutex_unlock(&pVnode->statusMutex);
+ return in;
+}
+
+static void vnodeDestroyVnode(SVnode *pVnode) {
+ int32_t code = 0;
+ int32_t vgId = pVnode->vgId;
+
+ if (pVnode->pSync != NULL) {
+ syncStop(pVnode->pSync);
+ pVnode->pSync = NULL;
+ }
+
+ if (pVnode->pQuery) {
+ // todo
+ }
+
+ if (pVnode->pMeta) {
+ // todo
+ }
+
+ if (pVnode->pTsdb) {
+ // todo
+ }
+
+ if (pVnode->pTQ) {
+ // todo
+ }
+
+ if (pVnode->pWal) {
+ walClose(pVnode->pWal);
+ pVnode->pWal = NULL;
+ }
+
+ if (pVnode->allocator) {
+ // todo
+ }
+
+ if (pVnode->pWriteQ) {
+ vnodeFreeWriteQueue(pVnode->pWriteQ);
+ pVnode->pWriteQ = NULL;
+ }
+
+ if (pVnode->pQueryQ) {
+ vnodeFreeQueryQueue(pVnode->pQueryQ);
+ pVnode->pQueryQ = NULL;
+ }
+
+ if (pVnode->pFetchQ) {
+ vnodeFreeFetchQueue(pVnode->pFetchQ);
+ pVnode->pFetchQ = NULL;
+ }
+
+ if (pVnode->dropped) {
+ // todo
+ }
+
+ pthread_mutex_destroy(&pVnode->statusMutex);
+ free(pVnode);
+}
+
+static void vnodeCleanupVnode(SVnode *pVnode) {
+ vnodeSetClosingStatus(pVnode);
+ taosHashRemove(tsVnode.hash, &pVnode->vgId, sizeof(int32_t));
+ vnodeRelease(pVnode);
+}
+
+static inline int32_t vnodeLogWrite(struct SSyncLogStore *logStore, SyncIndex index, SSyncBuffer *pBuf) {
+ SVnode *pVnode = logStore->pData; // vnode status can be checked here
+ return walWrite(pVnode->pWal, index, pBuf->data, (int32_t)pBuf->len);
+}
+
+static inline int32_t vnodeLogCommit(struct SSyncLogStore *logStore, SyncIndex index) {
+ SVnode *pVnode = logStore->pData; // vnode status can be checked here
+ return walCommit(pVnode->pWal, index);
+}
+
+static inline int32_t vnodeLogPrune(struct SSyncLogStore *logStore, SyncIndex index) {
+ SVnode *pVnode = logStore->pData; // vnode status can be checked here
+ return walPrune(pVnode->pWal, index);
+}
+
+static inline int32_t vnodeLogRollback(struct SSyncLogStore *logStore, SyncIndex index) {
+ SVnode *pVnode = logStore->pData; // vnode status can be checked here
+ return walRollback(pVnode->pWal, index);
+}
+
+static inline int32_t vnodeSaveServerState(struct SStateManager *stateMng, SSyncServerState *pState) {
+ SVnode *pVnode = stateMng->pData;
+ return vnodeSaveState(pVnode->vgId, pState);
+}
+
+static inline int32_t vnodeReadServerState(struct SStateManager *stateMng, SSyncServerState *pState) {
+ SVnode *pVnode = stateMng->pData;
+ return vnodeSaveState(pVnode->vgId, pState);
+}
+
+static inline int32_t vnodeApplyLog(struct SSyncFSM *fsm, SyncIndex index, const SSyncBuffer *buf, void *pData) {
+ return 0;
+}
+
+static inline int32_t vnodeOnClusterChanged(struct SSyncFSM *fsm, const SSyncCluster *cluster, void *pData) { return 0; }
+
+static inline int32_t vnodeGetSnapshot(struct SSyncFSM *fsm, SSyncBuffer **ppBuf, int32_t *objId, bool *isLast) {
+ return 0;
+}
+
+static inline int32_t vnodeApplySnapshot(struct SSyncFSM *fsm, SSyncBuffer *pBuf, int32_t objId, bool isLast) {
+ return 0;
+}
+
+static inline int32_t vnodeOnRestoreDone(struct SSyncFSM *fsm) { return 0; }
+
+static inline void vnodeOnRollback(struct SSyncFSM *fsm, SyncIndex index, const SSyncBuffer *buf) {}
+
+static inline void vnodeOnRoleChanged(struct SSyncFSM *fsm, const SNodesRole *pRole) {}
+
+static int32_t vnodeOpenVnode(int32_t vgId) {
+ int32_t code = 0;
+
+ SVnode *pVnode = calloc(sizeof(SVnode), 1);
+ if (pVnode == NULL) {
+ vError("vgId:%d, failed to open vnode since no enough memory", vgId);
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+
+ pVnode->vgId = vgId;
+ pVnode->accessState = TAOS_VN_STATUS_INIT;
+ pVnode->status = TSDB_VN_ALL_ACCCESS;
+ pVnode->refCount = 1;
+ pVnode->role = TAOS_SYNC_ROLE_CANDIDATE;
+ pthread_mutex_init(&pVnode->statusMutex, NULL);
+
+ vDebug("vgId:%d, vnode is opened", pVnode->vgId);
+ taosHashPut(tsVnode.hash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnode *));
+
+ code = vnodeReadCfg(vgId, &pVnode->cfg);
+ if (code != TSDB_CODE_SUCCESS) {
+ vError("vgId:%d, failed to read config file, set cfgVersion to 0", pVnode->vgId);
+ pVnode->cfg.dropped = 1;
+ vnodeCleanupVnode(pVnode);
+ return 0;
+ }
+
+ code = vnodeSaveState(vgId, &pVnode->term);
+ if (code != TSDB_CODE_SUCCESS) {
+ vError("vgId:%d, failed to read term file since %s", pVnode->vgId, tstrerror(code));
+ pVnode->cfg.dropped = 1;
+ vnodeCleanupVnode(pVnode);
+ return code;
+ }
+
+ pVnode->pWriteQ = vnodeAllocWriteQueue(pVnode);
+ pVnode->pQueryQ = vnodeAllocQueryQueue(pVnode);
+ pVnode->pFetchQ = vnodeAllocFetchQueue(pVnode);
+ if (pVnode->pWriteQ == NULL || pVnode->pQueryQ == NULL || pVnode->pFetchQ == NULL) {
+ vnodeCleanupVnode(pVnode);
+ return terrno;
+ }
+
+ char path[PATH_MAX + 20];
+ snprintf(path, sizeof(path), "%s/vnode%d/wal", tsVnodeDir, vgId);
+ pVnode->pWal = walOpen(path, &pVnode->cfg.wal);
+ if (pVnode->pWal == NULL) {
+ vnodeCleanupVnode(pVnode);
+ return terrno;
+ }
+
+ // create sync node
+ SSyncInfo syncInfo = {0};
+ syncInfo.vgId = vgId;
+ syncInfo.snapshotIndex = 0; // todo, from tsdb
+ memcpy(&syncInfo.syncCfg, &pVnode->cfg.sync, sizeof(SSyncCluster));
+ syncInfo.fsm.pData = pVnode;
+ syncInfo.fsm.applyLog = vnodeApplyLog;
+ syncInfo.fsm.onClusterChanged = vnodeOnClusterChanged;
+ syncInfo.fsm.getSnapshot = vnodeGetSnapshot;
+ syncInfo.fsm.applySnapshot = vnodeApplySnapshot;
+ syncInfo.fsm.onRestoreDone = vnodeOnRestoreDone;
+ syncInfo.fsm.onRollback = vnodeOnRollback;
+ syncInfo.fsm.onRoleChanged = vnodeOnRoleChanged;
+ syncInfo.logStore.pData = pVnode;
+ syncInfo.logStore.logWrite = vnodeLogWrite;
+ syncInfo.logStore.logCommit = vnodeLogCommit;
+ syncInfo.logStore.logPrune = vnodeLogPrune;
+ syncInfo.logStore.logRollback = vnodeLogRollback;
+ syncInfo.stateManager.pData = pVnode;
+ syncInfo.stateManager.saveServerState = vnodeSaveServerState;
+ syncInfo.stateManager.readServerState = vnodeReadServerState;
+
+ pVnode->pSync = syncStart(&syncInfo);
+ if (pVnode->pSync == NULL) {
+ vnodeCleanupVnode(pVnode);
+ return terrno;
+ }
+
+ vnodeSetReadyStatus(pVnode);
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t vnodeCreateVnode(int32_t vgId, SVnodeCfg *pCfg) {
+ int32_t code = 0;
+ char path[PATH_MAX + 20] = {0};
+
+ snprintf(path, sizeof(path), "%s/vnode%d", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ snprintf(path, sizeof(path), "%s/vnode%d/cfg", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ snprintf(path, sizeof(path), "%s/vnode%d/wal", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ snprintf(path, sizeof(path), "%s/vnode%d/tq", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ snprintf(path, sizeof(path), "%s/vnode%d/tsdb", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ snprintf(path, sizeof(path), "%s/vnode%d/meta", tsVnodeDir, vgId);
+ if (taosMkDir(path) < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ code = vnodeWriteCfg(vgId, pCfg);
+ if (code != 0) {
+ vError("vgId:%d, failed to save vnode cfg since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ return vnodeOpenVnode(vgId);
+}
+
+int32_t vnodeAlterVnode(SVnode * pVnode, SVnodeCfg *pCfg) {
+ int32_t code = 0;
+ int32_t vgId = pVnode->vgId;
+
+ bool walChanged = (memcmp(&pCfg->wal, &pVnode->cfg.wal, sizeof(SWalCfg)) != 0);
+ bool tsdbChanged = (memcmp(&pCfg->tsdb, &pVnode->cfg.tsdb, sizeof(STsdbCfg)) != 0);
+ bool metaChanged = (memcmp(&pCfg->meta, &pVnode->cfg.meta, sizeof(SMetaCfg)) != 0);
+ bool syncChanged = (memcmp(&pCfg->sync, &pVnode->cfg.sync, sizeof(SSyncCluster)) != 0);
+
+ if (!walChanged && !tsdbChanged && !metaChanged && !syncChanged) {
+ vDebug("vgId:%d, nothing changed", vgId);
+ vnodeRelease(pVnode);
+ return code;
+ }
+
+ code = vnodeWriteCfg(pVnode->vgId, pCfg);
+ if (code != 0) {
+ vError("vgId:%d, failed to write alter msg to file since %s", vgId, tstrerror(code));
+ vnodeRelease(pVnode);
+ return code;
+ }
+
+ pVnode->cfg = *pCfg;
+
+ if (walChanged) {
+ code = walAlter(pVnode->pWal, &pVnode->cfg.wal);
+ if (code != 0) {
+ vDebug("vgId:%d, failed to alter wal since %s", vgId, tstrerror(code));
+ vnodeRelease(pVnode);
+ return code;
+ }
+ }
+
+ if (tsdbChanged) {
+ // todo
+ }
+
+ if (metaChanged) {
+ // todo
+ }
+
+ if (syncChanged) {
+ syncReconfig(pVnode->pSync, &pVnode->cfg.sync);
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+int32_t vnodeDropVnode(SVnode *pVnode) {
+ if (pVnode->cfg.dropped) {
+ vInfo("vgId:%d, already set drop flag, ref:%d", pVnode->vgId, pVnode->refCount);
+ vnodeRelease(pVnode);
+ return TSDB_CODE_SUCCESS;
+ }
+
+ pVnode->cfg.dropped = 1;
+ int32_t code = vnodeWriteCfg(pVnode->vgId, &pVnode->cfg);
+ if (code == 0) {
+ vInfo("vgId:%d, set drop flag, ref:%d", pVnode->vgId, pVnode->refCount);
+ vnodeCleanupVnode(pVnode);
+ } else {
+ vError("vgId:%d, failed to set drop flag since %s", pVnode->vgId, tstrerror(code));
+ pVnode->cfg.dropped = 0;
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+int32_t vnodeSyncVnode(SVnode *pVnode) {
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t vnodeCompactVnode(SVnode *pVnode) {
+ return TSDB_CODE_SUCCESS;
+}
+
+static void *vnodeOpenVnodeFunc(void *param) {
+ SOpenVnodeThread *pThread = param;
+
+ vDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
+ setThreadName("vnodeOpenVnode");
+
+ for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
+ int32_t vgId = pThread->vnodeList[v];
+
+ char stepDesc[TSDB_STEP_DESC_LEN] = {0};
+ snprintf(stepDesc, TSDB_STEP_DESC_LEN, "vgId:%d, start to restore, %d of %d have been opened", vgId,
+ tsVnode.openVnodes, tsVnode.totalVnodes);
+ // (*vnodeInst()->fp.ReportStartup)("open-vnodes", stepDesc);
+
+ if (vnodeOpenVnode(vgId) < 0) {
+ vError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
+ pThread->failed++;
+ } else {
+ vDebug("vgId:%d, is opened by thread:%d", vgId, pThread->threadIndex);
+ pThread->opened++;
+ }
+
+ atomic_add_fetch_32(&tsVnode.openVnodes, 1);
+ }
+
+ vDebug("thread:%d, total vnodes:%d, opened:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
+ pThread->failed);
+ return NULL;
+}
+
+static int32_t vnodeGetVnodeListFromDisk(int32_t vnodeList[], int32_t *numOfVnodes) {
+#if 0
+ DIR *dir = opendir(tsVnodeDir);
+ if (dir == NULL) return TSDB_CODE_DND_NO_WRITE_ACCESS;
+
+ *numOfVnodes = 0;
+ struct dirent *de = NULL;
+ while ((de = readdir(dir)) != NULL) {
+ if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
+ if (de->d_type & DT_DIR) {
+ if (strncmp("vnode", de->d_name, 5) != 0) continue;
+ int32_t vnode = atoi(de->d_name + 5);
+ if (vnode == 0) continue;
+
+ (*numOfVnodes)++;
+
+ if (*numOfVnodes >= TSDB_MAX_VNODES) {
+ vError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
+ closedir(dir);
+ return TSDB_CODE_DND_TOO_MANY_VNODES;
+ } else {
+ vnodeList[*numOfVnodes - 1] = vnode;
+ }
+ }
+ }
+ closedir(dir);
+#endif
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t vnodeOpenVnodes() {
+ int32_t vnodeList[TSDB_MAX_VNODES] = {0};
+ int32_t numOfVnodes = 0;
+ int32_t status = vnodeGetVnodeListFromDisk(vnodeList, &numOfVnodes);
+
+ if (status != TSDB_CODE_SUCCESS) {
+ vInfo("failed to get vnode list from disk since code:%d", status);
+ return status;
+ }
+
+ tsVnode.totalVnodes = numOfVnodes;
+
+ int32_t threadNum = tsNumOfCores;
+ int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
+
+ SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
+ for (int32_t t = 0; t < threadNum; ++t) {
+ threads[t].threadIndex = t;
+ threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
+ }
+
+ for (int32_t v = 0; v < numOfVnodes; ++v) {
+ int32_t t = v % threadNum;
+ SOpenVnodeThread *pThread = &threads[t];
+ pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
+ }
+
+ vInfo("start %d threads to open %d vnodes", threadNum, numOfVnodes);
+
+ for (int32_t t = 0; t < threadNum; ++t) {
+ SOpenVnodeThread *pThread = &threads[t];
+ if (pThread->vnodeNum == 0) continue;
+
+ pThread->threadId = taosCreateThread(vnodeOpenVnodeFunc, pThread);
+ if (pThread->threadId == NULL) {
+ vError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
+ }
+ }
+
+ int32_t openVnodes = 0;
+ int32_t failedVnodes = 0;
+ for (int32_t t = 0; t < threadNum; ++t) {
+ SOpenVnodeThread *pThread = &threads[t];
+ taosDestoryThread(pThread->threadId);
+ pThread->threadId = NULL;
+
+ openVnodes += pThread->opened;
+ failedVnodes += pThread->failed;
+ free(pThread->vnodeList);
+ }
+
+ free(threads);
+ vInfo("there are total vnodes:%d, opened:%d", numOfVnodes, openVnodes);
+
+ if (failedVnodes != 0) {
+ vError("there are total vnodes:%d, failed:%d", numOfVnodes, failedVnodes);
+ return -1;
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t vnodeGetVnodeList(SVnode *vnodeList[], int32_t *numOfVnodes) {
+ void *pIter = taosHashIterate(tsVnode.hash, NULL);
+ while (pIter) {
+ SVnode **pVnode = pIter;
+ if (*pVnode) {
+ (*numOfVnodes)++;
+ if (*numOfVnodes >= TSDB_MAX_VNODES) {
+ vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
+ continue;
+ } else {
+ vnodeList[*numOfVnodes - 1] = (*pVnode);
+ }
+ }
+
+ pIter = taosHashIterate(tsVnode.hash, pIter);
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static void vnodeCleanupVnodes() {
+ SVnode* vnodeList[TSDB_MAX_VNODES] = {0};
+ int32_t numOfVnodes = 0;
+
+ int32_t code = vnodeGetVnodeList(vnodeList, &numOfVnodes);
+
+ if (code != TSDB_CODE_SUCCESS) {
+ vInfo("failed to get dnode list since code %d", code);
+ return;
+ }
+
+ for (int32_t i = 0; i < numOfVnodes; ++i) {
+ vnodeCleanupVnode(vnodeList[i]);
+ }
+
+ vInfo("total vnodes:%d are all closed", numOfVnodes);
+}
+
+static void vnodeIncRef(void *ptNode) {
+ assert(ptNode != NULL);
+
+ SVnode **ppVnode = (SVnode **)ptNode;
+ assert(ppVnode);
+ assert(*ppVnode);
+
+ SVnode *pVnode = *ppVnode;
+ atomic_add_fetch_32(&pVnode->refCount, 1);
+ vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
+}
+
+SVnode *vnodeAcquireInAllState(int32_t vgId) {
+ SVnode *pVnode = NULL;
+
+ // taosHashGetClone(tsVnode.hash, &vgId, sizeof(int32_t), vnodeIncRef, (void*)&pVnode);
+ if (pVnode == NULL) {
+ vDebug("vgId:%d, can't accquire since not exist", vgId);
+ terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
+ return NULL;
+ }
+
+ return pVnode;
+}
+
+SVnode *vnodeAcquire(int32_t vgId) {
+ SVnode *pVnode = vnodeAcquireInAllState(vgId);
+ if (pVnode == NULL) return NULL;
+
+ if (vnodeInStatus(pVnode, TAOS_VN_STATUS_READY)) {
+ return pVnode;
+ } else {
+ vDebug("vgId:%d, can't accquire since not in ready status", vgId);
+ vnodeRelease(pVnode);
+ terrno = TSDB_CODE_VND_INVALID_TSDB_STATE;
+ return NULL;
+ }
+}
+
+void vnodeRelease(SVnode *pVnode) {
+ if (pVnode == NULL) return;
+
+ int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
+ int32_t vgId = pVnode->vgId;
+
+ vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", vgId, refCount, pVnode);
+ assert(refCount >= 0);
+
+ if (refCount <= 0) {
+ vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", vgId, refCount, pVnode);
+ vnodeDestroyVnode(pVnode);
+ int32_t count = taosHashGetSize(tsVnode.hash);
+ vDebug("vgId:%d, vnode is destroyed, vnodes:%d", vgId, count);
+ }
+}
+
+int32_t vnodeInitMain() {
+ tsVnode.hash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
+ if (tsVnode.hash == NULL) {
+ vError("failed to init vnode mgmt");
+ return -1;
+ }
+
+ vInfo("vnode main is initialized");
+ return vnodeOpenVnodes();
+}
+
+void vnodeCleanupMain() {
+ vnodeCleanupVnodes();
+ taosHashCleanup(tsVnode.hash);
+ tsVnode.hash = NULL;
+}
+
+static void vnodeBuildVloadMsg(SVnode *pVnode, SStatusMsg *pStatus) {
+ int64_t totalStorage = 0;
+ int64_t compStorage = 0;
+ int64_t pointsWritten = 0;
+
+ if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
+
+ // if (pVnode->tsdb) {
+ // tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
+ // }
+
+ SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
+ pLoad->vgId = htonl(pVnode->vgId);
+ pLoad->totalStorage = htobe64(totalStorage);
+ pLoad->compStorage = htobe64(compStorage);
+ pLoad->pointsWritten = htobe64(pointsWritten);
+ pLoad->status = pVnode->status;
+ pLoad->role = pVnode->role;
+}
+
+void vnodeGetStatus(SStatusMsg *pStatus) {
+ void *pIter = taosHashIterate(tsVnode.hash, NULL);
+ while (pIter) {
+ SVnode **pVnode = pIter;
+ if (*pVnode) {
+ vnodeBuildVloadMsg(*pVnode, pStatus);
+ }
+ pIter = taosHashIterate(tsVnode.hash, pIter);
+ }
+}
+
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) {
+ for (int32_t i = 0; i < numOfVnodes; ++i) {
+ pAccess[i].vgId = htonl(pAccess[i].vgId);
+ SVnode *pVnode = vnodeAcquire(pAccess[i].vgId);
+ if (pVnode != NULL) {
+ pVnode->accessState = pAccess[i].accessState;
+ if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
+ vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
+ }
+ vnodeRelease(pVnode);
+ }
+ }
+}
diff --git a/source/server/vnode/src/vnodeMgmt.c b/source/server/vnode/src/vnodeMgmt.c
index 8662e5a920..e0e76d5b56 100644
--- a/source/server/vnode/src/vnodeMgmt.c
+++ b/source/server/vnode/src/vnodeMgmt.c
@@ -15,21 +15,185 @@
#define _DEFAULT_SOURCE
#include "os.h"
-
+#include "vnodeMain.h"
#include "vnodeMgmt.h"
-#include "vnodeMgmtMsg.h"
-
-typedef struct {
- SRpcMsg rpcMsg;
- char pCont[];
-} SVnMgmtMsg;
static struct {
- SWorkerPool pool;
- taos_queue pQueue;
+ SWorkerPool createPool;
+ taos_queue createQueue;
+ SWorkerPool workerPool;
+ taos_queue workerQueue;
int32_t (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
} tsVmgmt = {0};
+static int32_t vnodeParseCreateVnodeReq(SRpcMsg *rpcMsg, int32_t *vgId, SVnodeCfg *pCfg) {
+ SCreateVnodeMsg *pCreate = rpcMsg->pCont;
+ *vgId = htonl(pCreate->vgId);
+
+ pCfg->dropped = 0;
+ pCfg->quorum = pCreate->quorum;
+ tstrncpy(pCfg->db, pCreate->db, sizeof(pCfg->db));
+
+ pCfg->tsdb.cacheBlockSize = htonl(pCreate->cacheBlockSize);
+ pCfg->tsdb.totalBlocks = htonl(pCreate->totalBlocks);
+ pCfg->tsdb.daysPerFile = htonl(pCreate->daysPerFile);
+ pCfg->tsdb.daysToKeep1 = htonl(pCreate->daysToKeep1);
+ pCfg->tsdb.daysToKeep2 = htonl(pCreate->daysToKeep2);
+ pCfg->tsdb.daysToKeep0 = htonl(pCreate->daysToKeep0);
+ pCfg->tsdb.minRowsPerFileBlock = htonl(pCreate->minRowsPerFileBlock);
+ pCfg->tsdb.maxRowsPerFileBlock = htonl(pCreate->maxRowsPerFileBlock);
+ pCfg->tsdb.precision = pCreate->precision;
+ pCfg->tsdb.compression = pCreate->compression;
+ pCfg->tsdb.cacheLastRow = pCreate->cacheLastRow;
+ pCfg->tsdb.update = pCreate->update;
+
+ pCfg->wal.fsyncPeriod = htonl(pCreate->fsyncPeriod);
+ pCfg->wal.walLevel = pCreate->walLevel;
+
+ pCfg->sync.replica = pCreate->replica;
+ pCfg->sync.selfIndex = pCreate->selfIndex;
+
+ for (int32_t j = 0; j < pCreate->replica; ++j) {
+ pCfg->sync.nodeInfo[j].nodePort = htons(pCreate->nodes[j].port);
+ tstrncpy(pCfg->sync.nodeInfo[j].nodeFqdn, pCreate->nodes[j].fqdn, TSDB_FQDN_LEN);
+ }
+
+ return 0;
+}
+
+static int32_t vnodeProcessCreateVnodeReq(SRpcMsg *rpcMsg) {
+ SVnodeCfg vnodeCfg = {0};
+ int32_t vgId = 0;
+
+ int32_t code = vnodeParseCreateVnodeReq(rpcMsg, &vgId, &vnodeCfg);
+ if (code != 0) {
+ vError("failed to parse create vnode msg since %s", tstrerror(code));
+ }
+
+ vDebug("vgId:%d, create vnode req is received", vgId);
+
+ SVnode *pVnode = vnodeAcquireInAllState(vgId);
+ if (pVnode != NULL) {
+ vDebug("vgId:%d, already exist, return success", vgId);
+ vnodeRelease(pVnode);
+ return code;
+ }
+
+ code = vnodeCreateVnode(vgId, &vnodeCfg);
+ if (code != 0) {
+ vError("vgId:%d, failed to create vnode since %s", vgId, tstrerror(code));
+ }
+
+ return code;
+}
+
+static int32_t vnodeProcessAlterVnodeReq(SRpcMsg *rpcMsg) {
+ SVnodeCfg vnodeCfg = {0};
+ int32_t vgId = 0;
+
+ int32_t code = vnodeParseCreateVnodeReq(rpcMsg, &vgId, &vnodeCfg);
+ if (code != 0) {
+ vError("failed to parse create vnode msg since %s", tstrerror(code));
+ }
+
+ vDebug("vgId:%d, alter vnode req is received", vgId);
+
+ SVnode *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ code = terrno;
+ vDebug("vgId:%d, failed to alter vnode since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ code = vnodeAlterVnode(pVnode, &vnodeCfg);
+ if (code != 0) {
+ vError("vgId:%d, failed to alter vnode since %s", vgId, tstrerror(code));
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+static SDropVnodeMsg *vnodeParseDropVnodeReq(SRpcMsg *rpcMsg) {
+ SDropVnodeMsg *pDrop = rpcMsg->pCont;
+ pDrop->vgId = htonl(pDrop->vgId);
+ return pDrop;
+}
+
+static int32_t vnodeProcessSyncVnodeReq(SRpcMsg *rpcMsg) {
+ SSyncVnodeMsg *pSync = (SSyncVnodeMsg *)vnodeParseDropVnodeReq(rpcMsg);
+
+ int32_t code = 0;
+ int32_t vgId = pSync->vgId;
+ vDebug("vgId:%d, sync vnode req is received", vgId);
+
+ SVnode *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ code = terrno;
+ vDebug("vgId:%d, failed to sync since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ code = vnodeSyncVnode(pVnode);
+ if (code != 0) {
+ vError("vgId:%d, failed to compact vnode since %s", vgId, tstrerror(code));
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+static int32_t vnodeProcessCompactVnodeReq(SRpcMsg *rpcMsg) {
+ SCompactVnodeMsg *pCompact = (SCompactVnodeMsg *)vnodeParseDropVnodeReq(rpcMsg);
+
+ int32_t code = 0;
+ int32_t vgId = pCompact->vgId;
+ vDebug("vgId:%d, compact vnode req is received", vgId);
+
+ SVnode *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ code = terrno;
+ vDebug("vgId:%d, failed to compact since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ code = vnodeCompactVnode(pVnode);
+ if (code != 0) {
+ vError("vgId:%d, failed to compact vnode since %s", vgId, tstrerror(code));
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+static int32_t vnodeProcessDropVnodeReq(SRpcMsg *rpcMsg) {
+ SDropVnodeMsg *pDrop = vnodeParseDropVnodeReq(rpcMsg);
+
+ int32_t code = 0;
+ int32_t vgId = pDrop->vgId;
+ vDebug("vgId:%d, drop vnode req is received", vgId);
+
+ SVnode *pVnode = vnodeAcquire(vgId);
+ if (pVnode == NULL) {
+ code = terrno;
+ vDebug("vgId:%d, failed to drop since %s", vgId, tstrerror(code));
+ return code;
+ }
+
+ code = vnodeDropVnode(pVnode);
+ if (code != 0) {
+ vError("vgId:%d, failed to drop vnode since %s", vgId, tstrerror(code));
+ }
+
+ vnodeRelease(pVnode);
+ return code;
+}
+
+static int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg) {
+ vError("alter stream msg not processed");
+ return TSDB_CODE_VND_MSG_NOT_PROCESSED;
+}
+
static int32_t vnodeProcessMgmtStart(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype) {
SRpcMsg *pMsg = &pMgmt->rpcMsg;
int32_t msgType = pMsg->msgType;
@@ -43,27 +207,21 @@ static int32_t vnodeProcessMgmtStart(void *unused, SVnMgmtMsg *pMgmt, int32_t qt
}
}
-static void vnodeSendMgmtEnd(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype, int32_t code) {
+static void vnodeProcessMgmtEnd(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype, int32_t code) {
SRpcMsg *pMsg = &pMgmt->rpcMsg;
- SRpcMsg rsp = {0};
+ vTrace("msg:%p, is processed, result:%s", pMgmt, tstrerror(code));
- rsp.code = code;
- vTrace("msg:%p, is processed, code:0x%x", pMgmt, rsp.code);
- if (rsp.code != TSDB_CODE_DND_ACTION_IN_PROGRESS) {
- rsp.handle = pMsg->handle;
- rsp.pCont = NULL;
- rpcSendResponse(&rsp);
- }
-
- taosFreeQitem(pMsg);
+ SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
+ rpcSendResponse(&rsp);
+ taosFreeQitem(pMgmt);
}
static void vnodeInitMgmtReqFp() {
- tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessCreateVnodeMsg;
- tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessAlterVnodeMsg;
- tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessSyncVnodeMsg;
- tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE]= vnodeProcessCompactVnodeMsg;
- tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessDropVnodeMsg;
+ tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessCreateVnodeReq;
+ tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessAlterVnodeReq;
+ tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessSyncVnodeReq;
+ tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessCompactVnodeReq;
+ tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessDropVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessAlterStreamReq;
}
@@ -75,14 +233,18 @@ static int32_t vnodeWriteToMgmtQueue(SRpcMsg *pMsg) {
pMgmt->rpcMsg = *pMsg;
pMgmt->rpcMsg.pCont = pMgmt->pCont;
memcpy(pMgmt->pCont, pMsg->pCont, pMsg->contLen);
- taosWriteQitem(tsVmgmt.pQueue, TAOS_QTYPE_RPC, pMgmt);
- return TSDB_CODE_SUCCESS;
+ if (pMsg->msgType == TSDB_MSG_TYPE_MD_CREATE_VNODE) {
+ return taosWriteQitem(tsVmgmt.createQueue, TAOS_QTYPE_RPC, pMgmt);
+ } else {
+ return taosWriteQitem(tsVmgmt.workerQueue, TAOS_QTYPE_RPC, pMgmt);
+ }
}
void vnodeProcessMgmtMsg(SRpcMsg *pMsg) {
int32_t code = vnodeWriteToMgmtQueue(pMsg);
if (code != TSDB_CODE_SUCCESS) {
+ vError("msg, ahandle:%p type:%s not processed since %s", pMsg->ahandle, taosMsg[pMsg->msgType], tstrerror(code));
SRpcMsg rsp = {.handle = pMsg->handle, .code = code};
rpcSendResponse(&rsp);
}
@@ -93,25 +255,41 @@ void vnodeProcessMgmtMsg(SRpcMsg *pMsg) {
int32_t vnodeInitMgmt() {
vnodeInitMgmtReqFp();
- SWorkerPool *pPool = &tsVmgmt.pool;
- pPool->name = "vmgmt";
+ SWorkerPool *pPool = &tsVmgmt.createPool;
+ pPool->name = "vnode-mgmt-create";
pPool->startFp = (ProcessStartFp)vnodeProcessMgmtStart;
- pPool->endFp = (ProcessEndFp)vnodeSendMgmtEnd;
+ pPool->endFp = (ProcessEndFp)vnodeProcessMgmtEnd;
pPool->min = 1;
pPool->max = 1;
if (tWorkerInit(pPool) != 0) {
return TSDB_CODE_VND_OUT_OF_MEMORY;
}
- tsVmgmt.pQueue = tWorkerAllocQueue(pPool, NULL);
+ tsVmgmt.createQueue = tWorkerAllocQueue(pPool, NULL);
- vInfo("vmgmt is initialized, max worker %d", pPool->max);
+ pPool = &tsVmgmt.workerPool;
+ pPool->name = "vnode-mgmt-worker";
+ pPool->startFp = (ProcessStartFp)vnodeProcessMgmtStart;
+ pPool->endFp = (ProcessEndFp)vnodeProcessMgmtEnd;
+ pPool->min = 1;
+ pPool->max = 1;
+ if (tWorkerInit(pPool) != 0) {
+ return TSDB_CODE_VND_OUT_OF_MEMORY;
+ }
+
+ tsVmgmt.workerQueue = tWorkerAllocQueue(pPool, NULL);
+
+ vInfo("vmgmt is initialized");
return TSDB_CODE_SUCCESS;
}
void vnodeCleanupMgmt() {
- tWorkerFreeQueue(&tsVmgmt.pool, tsVmgmt.pQueue);
- tWorkerCleanup(&tsVmgmt.pool);
- tsVmgmt.pQueue = NULL;
+ tWorkerFreeQueue(&tsVmgmt.createPool, tsVmgmt.createQueue);
+ tWorkerCleanup(&tsVmgmt.createPool);
+ tsVmgmt.createQueue = NULL;
+
+ tWorkerFreeQueue(&tsVmgmt.workerPool, tsVmgmt.workerQueue);
+ tWorkerCleanup(&tsVmgmt.workerPool);
+ tsVmgmt.createQueue = NULL;
vInfo("vmgmt is closed");
}
diff --git a/source/server/vnode/src/vnodeMgmtMsg.c b/source/server/vnode/src/vnodeMgmtMsg.c
deleted file mode 100644
index 3b3fc530d2..0000000000
--- a/source/server/vnode/src/vnodeMgmtMsg.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-
-#include "vnodeMgmtMsg.h"
-
-static SCreateVnodeMsg* vnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
- SCreateVnodeMsg *pCreate = rpcMsg->pCont;
- pCreate->cfg.vgId = htonl(pCreate->cfg.vgId);
- pCreate->cfg.dbCfgVersion = htonl(pCreate->cfg.dbCfgVersion);
- pCreate->cfg.vgCfgVersion = htonl(pCreate->cfg.vgCfgVersion);
- pCreate->cfg.maxTables = htonl(pCreate->cfg.maxTables);
- pCreate->cfg.cacheBlockSize = htonl(pCreate->cfg.cacheBlockSize);
- pCreate->cfg.totalBlocks = htonl(pCreate->cfg.totalBlocks);
- pCreate->cfg.daysPerFile = htonl(pCreate->cfg.daysPerFile);
- pCreate->cfg.daysToKeep1 = htonl(pCreate->cfg.daysToKeep1);
- pCreate->cfg.daysToKeep2 = htonl(pCreate->cfg.daysToKeep2);
- pCreate->cfg.daysToKeep = htonl(pCreate->cfg.daysToKeep);
- pCreate->cfg.minRowsPerFileBlock = htonl(pCreate->cfg.minRowsPerFileBlock);
- pCreate->cfg.maxRowsPerFileBlock = htonl(pCreate->cfg.maxRowsPerFileBlock);
- pCreate->cfg.fsyncPeriod = htonl(pCreate->cfg.fsyncPeriod);
- pCreate->cfg.commitTime = htonl(pCreate->cfg.commitTime);
-
- for (int32_t j = 0; j < pCreate->cfg.vgReplica; ++j) {
- pCreate->nodes[j].nodeId = htonl(pCreate->nodes[j].nodeId);
- }
-
- return pCreate;
-}
-
-int32_t vnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
- SCreateVnodeMsg *pCreate = vnodeParseVnodeMsg(rpcMsg);
- SVnode *pVnode = vnodeAcquire(pCreate->cfg.vgId);
- if (pVnode != NULL) {
- vDebug("vgId:%d, already exist, return success", pCreate->cfg.vgId);
- vnodeRelease(pVnode);
- return TSDB_CODE_SUCCESS;
- } else {
- vDebug("vgId:%d, create vnode msg is received", pCreate->cfg.vgId);
- return vnodeCreate(pCreate);
- }
-}
-
-int32_t vnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
- SAlterVnodeMsg *pAlter = vnodeParseVnodeMsg(rpcMsg);
-
- void *pVnode = vnodeAcquireNotClose(pAlter->cfg.vgId);
- if (pVnode != NULL) {
- vDebug("vgId:%d, alter vnode msg is received", pAlter->cfg.vgId);
- int32_t code = vnodeAlter(pVnode, pAlter);
- vnodeRelease(pVnode);
- return code;
- } else {
- vInfo("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId);
- return TSDB_CODE_VND_INVALID_VGROUP_ID;
- }
-}
-
-int32_t vnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) {
- SSyncVnodeMsg *pSyncVnode = rpcMsg->pCont;
- pSyncVnode->vgId = htonl(pSyncVnode->vgId);
-
- return vnodeSync(pSyncVnode->vgId);
-}
-
-int32_t vnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
- SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont;
- pCompactVnode->vgId = htonl(pCompactVnode->vgId);
- return vnodeCompact(pCompactVnode->vgId);
-}
-
-int32_t vnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
- SDropVnodeMsg *pDrop = rpcMsg->pCont;
- pDrop->vgId = htonl(pDrop->vgId);
-
- return vnodeDrop(pDrop->vgId);
-}
-
-int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg) { return 0; }
diff --git a/source/server/vnode/src/vnodeRead.c b/source/server/vnode/src/vnodeRead.c
index dd3b2a7aa0..2ca2a81739 100644
--- a/source/server/vnode/src/vnodeRead.c
+++ b/source/server/vnode/src/vnodeRead.c
@@ -14,14 +14,9 @@
*/
#define _DEFAULT_SOURCE
-#include "os.h"
-#include "taosmsg.h"
-#include "tglobal.h"
-// #include "query.h"
-
+#include "vnodeMain.h"
#include "vnodeRead.h"
#include "vnodeReadMsg.h"
-#include "vnodeStatus.h"
static struct {
SWorkerPool query;
@@ -50,11 +45,6 @@ static int32_t vnodeWriteToRQueue(SVnode *pVnode, void *pCont, int32_t contLen,
}
#endif
- if (!vnodeInReadyStatus(pVnode)) {
- vDebug("vgId:%d, failed to write into vread queue, vnode status is %s", pVnode->vgId, vnodeStatus[pVnode->status]);
- return TSDB_CODE_APP_NOT_READY;
- }
-
int32_t size = sizeof(SReadMsg) + contLen;
SReadMsg *pRead = taosAllocateQitem(size);
if (pRead == NULL) {
@@ -119,7 +109,7 @@ void vnodeProcessReadMsg(SRpcMsg *pMsg) {
pHead->contLen = htonl(pHead->contLen);
assert(pHead->contLen > 0);
- SVnode *pVnode = vnodeAcquireNotClose(pHead->vgId);
+ SVnode *pVnode = vnodeAcquire(pHead->vgId);
if (pVnode != NULL) {
code = vnodeWriteToRQueue(pVnode, pCont, pHead->contLen, TAOS_QTYPE_RPC, pMsg);
if (code == TSDB_CODE_SUCCESS) queuedMsgNum++;
diff --git a/source/server/vnode/src/vnodeReadMsg.c b/source/server/vnode/src/vnodeReadMsg.c
index 3626626791..58dfe4116a 100644
--- a/source/server/vnode/src/vnodeReadMsg.c
+++ b/source/server/vnode/src/vnodeReadMsg.c
@@ -14,11 +14,7 @@
*/
#define _DEFAULT_SOURCE
-#include "os.h"
-#include "taosmsg.h"
-#include "tglobal.h"
-// #include "query.h"
-#include "vnodeStatus.h"
+#include "vnodeMain.h"
#include "vnodeRead.h"
#include "vnodeReadMsg.h"
diff --git a/source/server/vnode/src/vnodeStatus.c b/source/server/vnode/src/vnodeStatus.c
deleted file mode 100644
index b0b3bbfa49..0000000000
--- a/source/server/vnode/src/vnodeStatus.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-#include "taosmsg.h"
-// #include "query.h"
-#include "vnodeRead.h"
-#include "vnodeStatus.h"
-#include "vnodeWrite.h"
-
-char* vnodeStatus[] = {
- "init",
- "ready",
- "closing",
- "updating",
- "reset"
-};
-
-bool vnodeSetInitStatus(SVnode* pVnode) {
- pthread_mutex_lock(&pVnode->statusMutex);
- pVnode->status = TAOS_VN_STATUS_INIT;
- pthread_mutex_unlock(&pVnode->statusMutex);
- return true;
-}
-
-bool vnodeSetReadyStatus(SVnode* pVnode) {
- bool set = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_READY ||
- pVnode->status == TAOS_VN_STATUS_UPDATING) {
- pVnode->status = TAOS_VN_STATUS_READY;
- set = true;
- }
-
-#if 0
- qQueryMgmtReOpen(pVnode->qMgmt);
-#endif
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return set;
-}
-
-static bool vnodeSetClosingStatusImp(SVnode* pVnode) {
- bool set = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_READY || pVnode->status == TAOS_VN_STATUS_INIT) {
- pVnode->status = TAOS_VN_STATUS_CLOSING;
- set = true;
- }
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return set;
-}
-
-bool vnodeSetClosingStatus(SVnode* pVnode) {
- if (pVnode->status == TAOS_VN_STATUS_CLOSING)
- return true;
-
- while (!vnodeSetClosingStatusImp(pVnode)) {
- taosMsleep(1);
- }
-
-#if 0
- // release local resources only after cutting off outside connections
- qQueryMgmtNotifyClosed(pVnode->qMgmt);
-#endif
- vnodeWaitReadCompleted(pVnode);
- vnodeWaitWriteCompleted(pVnode);
-
- return true;
-}
-
-bool vnodeSetUpdatingStatus(SVnode* pVnode) {
- bool set = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_READY) {
- pVnode->status = TAOS_VN_STATUS_UPDATING;
- set = true;
- }
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return set;
-}
-
-bool vnodeInInitStatus(SVnode* pVnode) {
- bool in = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_INIT) {
- in = true;
- }
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return in;
-}
-
-bool vnodeInReadyStatus(SVnode* pVnode) {
- bool in = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_READY) {
- in = true;
- }
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return in;
-}
-
-bool vnodeInClosingStatus(SVnode* pVnode) {
- bool in = false;
- pthread_mutex_lock(&pVnode->statusMutex);
-
- if (pVnode->status == TAOS_VN_STATUS_CLOSING) {
- in = true;
- }
-
- pthread_mutex_unlock(&pVnode->statusMutex);
- return in;
-}
-
diff --git a/source/server/vnode/src/vnodeVersion.c b/source/server/vnode/src/vnodeVersion.c
deleted file mode 100644
index 2b3d1b3a00..0000000000
--- a/source/server/vnode/src/vnodeVersion.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-#include "cJSON.h"
-#include "tglobal.h"
-#include "vnodeVersion.h"
-
-int32_t vnodeReadVersion(SVnode *pVnode) {
- int32_t len = 0;
- int32_t maxLen = 100;
- char * content = calloc(1, maxLen + 1);
- cJSON * root = NULL;
- FILE * fp = NULL;
-
- terrno = TSDB_CODE_VND_INVALID_VRESION_FILE;
- char file[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
-
- fp = fopen(file, "r");
- if (!fp) {
- if (errno != ENOENT) {
- vError("vgId:%d, failed to read %s, error:%s", pVnode->vgId, file, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- } else {
- terrno = TSDB_CODE_SUCCESS;
- }
- goto PARSE_VER_ERROR;
- }
-
- len = (int32_t)fread(content, 1, maxLen, fp);
- if (len <= 0) {
- vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
- goto PARSE_VER_ERROR;
- }
-
- root = cJSON_Parse(content);
- if (root == NULL) {
- vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
- goto PARSE_VER_ERROR;
- }
-
- cJSON *ver = cJSON_GetObjectItem(root, "version");
- if (!ver || ver->type != cJSON_Number) {
- vError("vgId:%d, failed to read %s, version not found", pVnode->vgId, file);
- goto PARSE_VER_ERROR;
- }
-#if 0
- pVnode->version = (uint64_t)ver->valueint;
-
- terrno = TSDB_CODE_SUCCESS;
- vInfo("vgId:%d, read %s successfully, fver:%" PRIu64, pVnode->vgId, file, pVnode->version);
-#endif
-
-PARSE_VER_ERROR:
- if (content != NULL) free(content);
- if (root != NULL) cJSON_Delete(root);
- if (fp != NULL) fclose(fp);
-
- return terrno;
-}
-
-int32_t vnodeSaveVersion(SVnode *pVnode) {
- char file[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
-
- FILE *fp = fopen(file, "w");
- if (!fp) {
- vError("vgId:%d, failed to write %s, reason:%s", pVnode->vgId, file, strerror(errno));
- return -1;
- }
-
- int32_t len = 0;
- int32_t maxLen = 100;
- char * content = calloc(1, maxLen + 1);
-
-#if 0
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"version\": %" PRIu64 "\n", pVnode->fversion);
- len += snprintf(content + len, maxLen - len, "}\n");
-#endif
- fwrite(content, 1, len, fp);
- taosFsyncFile(fileno(fp));
- fclose(fp);
- free(content);
- terrno = 0;
-
- // vInfo("vgId:%d, successed to write %s, fver:%" PRIu64, pVnode->vgId, file, pVnode->fversion);
- return TSDB_CODE_SUCCESS;
-}
\ No newline at end of file
diff --git a/source/server/vnode/src/vnodeWorker.c b/source/server/vnode/src/vnodeWorker.c
deleted file mode 100644
index a8b5723ffb..0000000000
--- a/source/server/vnode/src/vnodeWorker.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-#include "os.h"
-
-#include "vnodeWorker.h"
-
-enum { CLEANUP_TASK = 0, DESTROY_TASK = 1, BACKUP_TASK = 2 };
-
-typedef struct {
- int32_t vgId;
- int32_t code;
- int32_t type;
- void * rpcHandle;
- SVnode *pVnode;
-} SVnTask;
-
-static struct {
- SWorkerPool pool;
- taos_queue pQueue;
-} tsVworker = {0};
-
-static void vnodeProcessTaskStart(void *unused, SVnTask *pTask, int32_t qtype) {
- pTask->code = 0;
-
- switch (pTask->type) {
- case CLEANUP_TASK:
- vnodeCleanUp(pTask->pVnode);
- break;
- case DESTROY_TASK:
- vnodeDestroy(pTask->pVnode);
- break;
- case BACKUP_TASK:
- vnodeBackup(pTask->vgId);
- break;
- default:
- break;
- }
-}
-
-static void vnodeProcessTaskEnd(void *unused, SVnTask *pTask, int32_t qtype, int32_t code) {
- if (pTask->rpcHandle != NULL) {
- SRpcMsg rpcRsp = {.handle = pTask->rpcHandle, .code = pTask->code};
- rpcSendResponse(&rpcRsp);
- }
-
- taosFreeQitem(pTask);
-}
-
-static int32_t vnodeWriteIntoTaskQueue(SVnode *pVnode, int32_t type, void *rpcHandle) {
- SVnTask *pTask = taosAllocateQitem(sizeof(SVnTask));
- if (pTask == NULL) return TSDB_CODE_VND_OUT_OF_MEMORY;
-
- pTask->vgId = pVnode->vgId;
- pTask->pVnode = pVnode;
- pTask->rpcHandle = rpcHandle;
- pTask->type = type;
-
-
- return taosWriteQitem(tsVworker.pQueue, TAOS_QTYPE_RPC, pTask);
-}
-
-void vnodeProcessCleanupTask(SVnode *pVnode) {
- vnodeWriteIntoTaskQueue(pVnode, CLEANUP_TASK, NULL);
-}
-
-void vnodeProcessDestroyTask(SVnode *pVnode) {
- vnodeWriteIntoTaskQueue(pVnode, DESTROY_TASK, NULL);
-}
-
-void vnodeProcessBackupTask(SVnode *pVnode) {
- vnodeWriteIntoTaskQueue(pVnode, BACKUP_TASK, NULL);
-}
-
-int32_t vnodeInitWorker() {
- SWorkerPool *pPool = &tsVworker.pool;
- pPool->name = "vworker";
- pPool->startFp = (ProcessStartFp)vnodeProcessTaskStart;
- pPool->endFp = (ProcessEndFp)vnodeProcessTaskEnd;
- pPool->min = 0;
- pPool->max = 1;
- if (tWorkerInit(pPool) != 0) {
- return TSDB_CODE_VND_OUT_OF_MEMORY;
- }
-
- tsVworker.pQueue = tWorkerAllocQueue(pPool, NULL);
-
- vInfo("vworker is initialized, max worker %d", pPool->max);
- return TSDB_CODE_SUCCESS;
-}
-
-void vnodeCleanupWorker() {
- tWorkerFreeQueue(&tsVworker.pool, tsVworker.pQueue);
- tWorkerCleanup(&tsVworker.pool);
- tsVworker.pQueue = NULL;
- vInfo("vworker is closed");
-}
diff --git a/source/server/vnode/src/vnodeWrite.c b/source/server/vnode/src/vnodeWrite.c
index 4c845d96ab..f3258af0bf 100644
--- a/source/server/vnode/src/vnodeWrite.c
+++ b/source/server/vnode/src/vnodeWrite.c
@@ -15,12 +15,7 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "tglobal.h"
-#include "tqueue.h"
-#include "tworker.h"
-#include "taosmsg.h"
-
-#include "vnodeStatus.h"
+#include "vnodeMain.h"
#include "vnodeWrite.h"
#include "vnodeWriteMsg.h"
@@ -68,11 +63,6 @@ static int32_t vnodeWriteToWQueue(SVnode *pVnode, SWalHead *pHead, int32_t qtype
return TSDB_CODE_WAL_SIZE_LIMIT;
}
- if (!vnodeInReadyStatus(pVnode)) {
- vError("vgId:%d, failed to write into vwqueue, vstatus is %s", pVnode->vgId, vnodeStatus[pVnode->status]);
- return TSDB_CODE_APP_NOT_READY;
- }
-
if (tsVwrite.queuedBytes > tsMaxVnodeQueuedBytes) {
vDebug("vgId:%d, too many bytes:%" PRId64 " in vwqueue, flow control", pVnode->vgId, tsVwrite.queuedBytes);
return TSDB_CODE_VND_IS_FLOWCTRL;
@@ -122,7 +112,7 @@ void vnodeProcessWriteMsg(SRpcMsg *pRpcMsg) {
pMsg->vgId = htonl(pMsg->vgId);
pMsg->contLen = htonl(pMsg->contLen);
- SVnode *pVnode = vnodeAcquireNotClose(pMsg->vgId);
+ SVnode *pVnode = vnodeAcquire(pMsg->vgId);
if (pVnode == NULL) {
code = TSDB_CODE_VND_INVALID_VGROUP_ID;
} else {
diff --git a/source/util/src/terror.c b/source/util/src/terror.c
index 68cd067fb9..8e5d7a47fd 100644
--- a/source/util/src/terror.c
+++ b/source/util/src/terror.c
@@ -245,11 +245,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_DISK_PERMISSIONS, "No write permission f
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, "Missing data file")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, "Out of memory")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, "Unexpected generic error in vnode")
-TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_VRESION_FILE, "Invalid version file")
-TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FULL, "Database memory is full for commit failed")
-TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full for waiting commit")
+TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_CFG_FILE, "Invalid config file")
+TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_TERM_FILE, "Invalid term file")
+TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping")
-TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing")
+TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_UPDATING, "Database is updating")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_CLOSING, "Database is closing")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied")