diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b258a2a252ddafbd3f32f3bde3c59f3af1e79e58..cb05c84d722c69b3e42290aff1d2699081fb33d4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -26,7 +26,8 @@ "eamodio.gitlens", "matepek.vscode-catch2-test-adapter", "spmeesseman.vscode-taskexplorer", - "cschlosser.doxdocgen" + "cschlosser.doxdocgen", + "urosvujosevic.explorer-manager" ], // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], diff --git a/cmake/bdb_CMakeLists.txt.in b/cmake/bdb_CMakeLists.txt.in index 57acc95a1175e1eee677169d5c9f10d6f5cd1843..651a657c0db2422e690deb1436160320b3ea7d47 100644 --- a/cmake/bdb_CMakeLists.txt.in +++ b/cmake/bdb_CMakeLists.txt.in @@ -6,7 +6,7 @@ ExternalProject_Add(bdb SOURCE_DIR "${CMAKE_CONTRIB_DIR}/bdb" BINARY_DIR "${CMAKE_CONTRIB_DIR}/bdb" #BUILD_IN_SOURCE TRUE - CONFIGURE_COMMAND "./dist/configure" + CONFIGURE_COMMAND COMMAND ./dist/configure --enable-debug BUILD_COMMAND "$(MAKE)" INSTALL_COMMAND "" TEST_COMMAND "" diff --git a/include/client/taos.h b/include/client/taos.h index 4669ca51f7d80dd40a9d37047cf758faa680c9c8..84f625571095e519b3268d42324719461d5ac650 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -193,8 +193,7 @@ DLL_EXPORT void taos_close_stream(TAOS_STREAM *tstr); DLL_EXPORT int taos_load_table_info(TAOS *taos, const char* tableNameList); DLL_EXPORT TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int protocol, int precision); - -DLL_EXPORT TAOS_RES *tmq_create_topic(TAOS* taos, const char* name, const char* sql, int sqlLen); +DLL_EXPORT TAOS_RES *taos_create_topic(TAOS* taos, const char* name, const char* sql, int sqlLen); #ifdef __cplusplus } diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 339db4337467812f9ceba02cbef41935ee62859e..73bc748705c49700d973b641dd0fd5a4534980fc 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -68,6 +68,14 @@ typedef uint16_t tmsg_t; #define TSDB_IE_TYPE_DNODE_EXT 6 #define TSDB_IE_TYPE_DNODE_STATE 7 +typedef enum { + HEARTBEAT_TYPE_MQ = 0, + HEARTBEAT_TYPE_QUERY = 1, + // types can be added here + // + HEARTBEAT_TYPE_MAX +} EHbType; + typedef enum _mgmt_table { TSDB_MGMT_TABLE_START, TSDB_MGMT_TABLE_ACCT, @@ -147,7 +155,7 @@ typedef struct { typedef struct { SClientHbKey connKey; - SHashObj* info; // hash + SHashObj* info; // hash } SClientHbReq; typedef struct { @@ -173,7 +181,10 @@ static FORCE_INLINE uint32_t hbKeyHashFunc(const char* key, uint32_t keyLen) { } int tSerializeSClientHbReq(void** buf, const SClientHbReq* pReq); -void* tDeserializeClientHbReq(void* buf, SClientHbReq* pReq); +void* tDeserializeSClientHbReq(void* buf, SClientHbReq* pReq); + +int tSerializeSClientHbRsp(void** buf, const SClientHbRsp* pRsp); +void* tDeserializeSClientHbRsp(void* buf, SClientHbRsp* pRsp); static FORCE_INLINE void tFreeClientHbReq(void *pReq) { SClientHbReq* req = (SClientHbReq*)pReq; @@ -182,14 +193,17 @@ static FORCE_INLINE void tFreeClientHbReq(void *pReq) { } int tSerializeSClientHbBatchReq(void** buf, const SClientHbBatchReq* pReq); -void* tDeserializeClientHbBatchReq(void* buf, SClientHbBatchReq* pReq); +void* tDeserializeSClientHbBatchReq(void* buf, SClientHbBatchReq* pReq); static FORCE_INLINE void tFreeClientHbBatchReq(void* pReq) { SClientHbBatchReq *req = (SClientHbBatchReq*)pReq; - taosArrayDestroyEx(req->reqs, tFreeClientHbReq); + //taosArrayDestroyEx(req->reqs, tFreeClientHbReq); free(pReq); } +int tSerializeSClientHbBatchRsp(void** buf, const SClientHbBatchRsp* pBatchRsp); +void* tDeserializeSClientHbBatchRsp(void* buf, SClientHbBatchRsp* pBatchRsp); + static FORCE_INLINE int taosEncodeSKv(void** buf, const SKv* pKv) { int tlen = 0; tlen += taosEncodeFixedI32(buf, pKv->keyLen); @@ -220,6 +234,7 @@ static FORCE_INLINE void* taosDecodeSClientHbKey(void* buf, SClientHbKey* pKey) return buf; } + typedef struct { int32_t vgId; char* dbName; @@ -359,6 +374,31 @@ static FORCE_INLINE void* taosDecodeSEpSet(void* buf, SEpSet* pEp) { return buf; } +typedef struct SMqHbRsp { + int8_t status; //idle or not + int8_t vnodeChanged; + int8_t epChanged; // should use new epset + int8_t reserved; + SEpSet epSet; +} SMqHbRsp; + +static FORCE_INLINE int taosEncodeSMqHbRsp(void** buf, const SMqHbRsp* pRsp) { + int tlen = 0; + tlen += taosEncodeFixedI8(buf, pRsp->status); + tlen += taosEncodeFixedI8(buf, pRsp->vnodeChanged); + tlen += taosEncodeFixedI8(buf, pRsp->epChanged); + tlen += taosEncodeSEpSet(buf, &pRsp->epSet); + return tlen; +} + +static FORCE_INLINE void* taosDecodeSMqHbRsp(void* buf, SMqHbRsp* pRsp) { + buf = taosDecodeFixedI8(buf, &pRsp->status); + buf = taosDecodeFixedI8(buf, &pRsp->vnodeChanged); + buf = taosDecodeFixedI8(buf, &pRsp->epChanged); + buf = taosDecodeSEpSet(buf, &pRsp->epSet); + return buf; +} + typedef struct { int32_t acctId; int64_t clusterId; @@ -1060,6 +1100,7 @@ typedef struct { typedef struct { int8_t igExists; char* name; + char* sql; char* physicalPlan; char* logicalPlan; } SCMCreateTopicReq; @@ -1068,6 +1109,7 @@ static FORCE_INLINE int tSerializeSCMCreateTopicReq(void** buf, const SCMCreateT int tlen = 0; tlen += taosEncodeFixedI8(buf, pReq->igExists); tlen += taosEncodeString(buf, pReq->name); + tlen += taosEncodeString(buf, pReq->sql); tlen += taosEncodeString(buf, pReq->physicalPlan); tlen += taosEncodeString(buf, pReq->logicalPlan); return tlen; @@ -1076,6 +1118,7 @@ static FORCE_INLINE int tSerializeSCMCreateTopicReq(void** buf, const SCMCreateT static FORCE_INLINE void* tDeserializeSCMCreateTopicReq(void* buf, SCMCreateTopicReq* pReq) { buf = taosDecodeFixedI8(buf, &(pReq->igExists)); buf = taosDecodeString(buf, &(pReq->name)); + buf = taosDecodeString(buf, &(pReq->sql)); buf = taosDecodeString(buf, &(pReq->physicalPlan)); buf = taosDecodeString(buf, &(pReq->logicalPlan)); return buf; @@ -1198,7 +1241,7 @@ typedef struct { } SMVSubscribeRsp; typedef struct { - char name[TSDB_TOPIC_FNAME_LEN]; + char name[TSDB_TOPIC_NAME_LEN]; int8_t igExists; int32_t execLen; void* executor; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 2f4bae2fa05b9aa60f42732b02a0fe2fbfd6689e..bfeba885d0ddb6bd3ffee645353d9ac90b1f48a1 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -129,7 +129,7 @@ enum { TD_DEF_MSG_TYPE(TDMT_MND_VGROUP_LIST, "mnode-vgroup-list", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_KILL_QUERY, "mnode-kill-query", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_KILL_CONN, "mnode-kill-conn", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_MND_HEARTBEAT, "mnode-heartbeat", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_HEARTBEAT, "mnode-heartbeat", SClientHbBatchReq, SClientHbBatchRsp) TD_DEF_MSG_TYPE(TDMT_MND_SHOW, "mnode-show", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_SHOW_RETRIEVE, "mnode-retrieve", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_STATUS, "mnode-status", NULL, NULL) diff --git a/include/common/tname.h b/include/common/tname.h index 11d97dac06d7240664f48626cd9d58ad6c555afa..12a0d34cb4fef92d0f65de535808f1150aa2c33d 100644 --- a/include/common/tname.h +++ b/include/common/tname.h @@ -25,14 +25,12 @@ #define T_NAME_ACCT 0x1u #define T_NAME_DB 0x2u #define T_NAME_TABLE 0x4u -#define T_NAME_TOPIC 0x8u typedef struct SName { uint8_t type; //db_name_t, table_name_t int32_t acctId; char dbname[TSDB_DB_NAME_LEN]; char tname[TSDB_TABLE_NAME_LEN]; - char topicName[TSDB_TOPIC_NAME_LEN]; } SName; int32_t tNameExtractFullName(const SName* name, char* dst); diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 0cdbfdb07f6560b367385772685b925e5a4708e6..418c43fab9728fb28286b8003450f19938eb5468 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -44,7 +44,7 @@ typedef struct SParseContext { * @param msg extended error message if exists. * @return error code */ -int32_t qParseQuerySql(SParseContext* pContext, SQueryNode** pQuery); +int32_t qParseQuerySql(SParseContext* pContext, SQueryNode** pQueryNode); /** * Return true if it is a ddl/dcl sql statement diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index 4f1db37f794ac5ba192aae3c0e399558b73c74ce..f069b6828692d0199c9a5c1cd77547d8bfccfdbe 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -95,6 +95,7 @@ typedef struct SScanPhyNode { int8_t tableType; int32_t order; // scan order: TSDB_ORDER_ASC|TSDB_ORDER_DESC int32_t count; // repeat count + int32_t reverse; // reverse scan count } SScanPhyNode; typedef SScanPhyNode SSystemTableScanPhyNode; diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 1cd513b8c0cb666fc13e78eed04038126c5b790b..bec4c8f261efa943448e4dd4046f56e77b053815 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -307,6 +307,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied") #define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing") #define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state") +#define TSDB_CODE_VND_TB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0515) // "Table not exists") // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID") diff --git a/include/util/tcoding.h b/include/util/tcoding.h index 226856901f2d20ae6ce50f81989aba032ca38d6c..819878704833db6db9994e36f04fc3741b2461bb 100644 --- a/include/util/tcoding.h +++ b/include/util/tcoding.h @@ -351,6 +351,7 @@ static FORCE_INLINE void *taosDecodeString(void *buf, char **value) { buf = taosDecodeVariantU64(buf, &size); *value = (char *)malloc((size_t)size + 1); + if (*value == NULL) return NULL; memcpy(*value, buf, (size_t)size); diff --git a/include/util/tdef.h b/include/util/tdef.h index 9f16b58e0db30e8357da720f5254605f0d5bec08..428de5d17138a9f869b4ab0b3fc987759c256bba 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -181,7 +181,7 @@ do { \ #define TSDB_COL_NAME_LEN 65 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE -#define TSDB_MAX_SQL_SHOW_LEN 512 +#define TSDB_MAX_SQL_SHOW_LEN 1024 #define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024u) // sql length should be less than 1mb #define TSDB_APP_NAME_LEN TSDB_UNI_LEN diff --git a/source/client/inc/clientHb.h b/source/client/inc/clientHb.h deleted file mode 100644 index 7bc4311b29dc5c89203b3b32054ec7186dfee073..0000000000000000000000000000000000000000 --- a/source/client/inc/clientHb.h +++ /dev/null @@ -1,78 +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 . - */ - -#include "os.h" -#include "tarray.h" -#include "thash.h" -#include "tmsg.h" - -#define HEARTBEAT_INTERVAL 1500 // ms - -typedef enum { - HEARTBEAT_TYPE_MQ = 0, - // types can be added here - // - HEARTBEAT_TYPE_MAX -} EHbType; - -typedef int32_t (*FHbRspHandle)(SClientHbRsp* pReq); - -typedef struct SAppHbMgr { - // statistics - int32_t reportCnt; - int32_t connKeyCnt; - int64_t reportBytes; // not implemented - int64_t startTime; - // ctl - SRWLatch lock; // lock is used in serialization - // connection - void* transporter; - SEpSet epSet; - // info - SHashObj* activeInfo; // hash - SHashObj* getInfoFuncs; // hash -} SAppHbMgr; - -typedef struct SClientHbMgr { - int8_t inited; - // ctl - int8_t threadStop; - pthread_t thread; - pthread_mutex_t lock; // used when app init and cleanup - SArray* appHbMgrs; // SArray one for each cluster - FHbRspHandle handle[HEARTBEAT_TYPE_MAX]; -} SClientHbMgr; - -// TODO: embed param into function -// return type: SArray -typedef SArray* (*FGetConnInfo)(SClientHbKey connKey, void* param); - -// global, called by mgmt -int hbMgrInit(); -void hbMgrCleanUp(); -int hbHandleRsp(SClientHbBatchRsp* hbRsp); - -// cluster level -SAppHbMgr* appHbMgrInit(void* transporter, SEpSet epSet); -void appHbMgrCleanup(SAppHbMgr* pAppHbMgr); - -// conn level -int hbRegisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, FGetConnInfo func); -void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey); - -int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* value, int32_t keyLen, int32_t valueLen); - -// mq -void hbMgrInitMqHbRspHandle(); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 39f84ffd8639c5bdbe6447273a2d923941339eb0..b6f38b12cac7feeaf0da1b2baba90e20f1414c4b 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -31,6 +31,41 @@ extern "C" { #include "trpc.h" #include "query.h" +#define HEARTBEAT_INTERVAL 1500 // ms + +typedef struct SAppInstInfo SAppInstInfo; + +typedef int32_t (*FHbRspHandle)(SClientHbRsp* pReq); + +typedef struct SAppHbMgr { + // statistics + int32_t reportCnt; + int32_t connKeyCnt; + int64_t reportBytes; // not implemented + int64_t startTime; + // ctl + SRWLatch lock; // lock is used in serialization + // connection + SAppInstInfo* pAppInstInfo; + // info + SHashObj* activeInfo; // hash + SHashObj* getInfoFuncs; // hash +} SAppHbMgr; + +typedef struct SClientHbMgr { + int8_t inited; + // ctl + int8_t threadStop; + pthread_t thread; + pthread_mutex_t lock; // used when app init and cleanup + SArray* appHbMgrs; // SArray one for each cluster + FHbRspHandle handle[HEARTBEAT_TYPE_MAX]; +} SClientHbMgr; + +// TODO: embed param into function +// return type: SArray +typedef SArray* (*FGetConnInfo)(SClientHbKey connKey, void* param); + typedef struct SQueryExecMetric { int64_t start; // start timestamp int64_t parsed; // start to parse @@ -55,15 +90,15 @@ typedef struct SHeartBeatInfo { void *pTimer; // timer, used to send request msg to mnode } SHeartBeatInfo; -typedef struct SAppInstInfo { - int64_t numOfConns; - SCorEpSet mgmtEp; - SInstanceSummary summary; +struct SAppInstInfo { + int64_t numOfConns; + SCorEpSet mgmtEp; + SInstanceSummary summary; SList *pConnList; // STscObj linked list - int64_t clusterId; + int64_t clusterId; void *pTransporter; - SHeartBeatInfo hb; -} SAppInstInfo; + struct SAppHbMgr *pAppHbMgr; +}; typedef struct SAppInfo { int64_t startTime; @@ -81,13 +116,17 @@ typedef struct STscObj { char db[TSDB_DB_FNAME_LEN]; int32_t acctId; uint32_t connId; + int32_t connType; uint64_t id; // ref ID returned by taosAddRef - void *pTransporter; pthread_mutex_t mutex; // used to protect the operation on db - int32_t numOfReqs; // number of sqlObj from this tscObj + int32_t numOfReqs; // number of sqlObj bound to this connection SAppInstInfo *pAppInfo; } STscObj; +typedef struct SMqConsumer { + STscObj* pTscObj; +} SMqConsumer; + typedef struct SReqResultInfo { const char *pRspMsg; const char *pData; @@ -109,12 +148,13 @@ typedef struct SShowReqInfo { } SShowReqInfo; typedef struct SRequestSendRecvBody { - tsem_t rspSem; // not used now - void* fp; - SShowReqInfo showInfo; // todo this attribute will be removed after the query framework being completed. - struct SSchJob *pQueryJob; // query job, created according to sql query DAG. - SDataBuf requestMsg; - SReqResultInfo resInfo; + tsem_t rspSem; // not used now + void* fp; + SShowReqInfo showInfo; // todo this attribute will be removed after the query framework being completed. + SDataBuf requestMsg; + struct SSchJob *pQueryJob; // query job, created according to sql query DAG. + struct SQueryDag *pDag; // the query dag, generated according to the sql statement. + SReqResultInfo resInfo; } SRequestSendRecvBody; #define ERROR_MSG_BUF_DEFAULT_SIZE 512 @@ -169,6 +209,26 @@ void *doFetchRow(SRequestObj* pRequest); void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t numOfCols, int32_t numOfRows); +// --- heartbeat +// global, called by mgmt +int hbMgrInit(); +void hbMgrCleanUp(); +int hbHandleRsp(SClientHbBatchRsp* hbRsp); + +// cluster level +SAppHbMgr* appHbMgrInit(SAppInstInfo* pAppInstInfo); +void appHbMgrCleanup(SAppHbMgr* pAppHbMgr); + +// conn level +int hbRegisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, FGetConnInfo func); +void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey); + +int hbAddConnInfo(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* key, void* value, int32_t keyLen, int32_t valueLen); + +// --- mq +void hbMgrInitMqHbRspHandle(); + + #ifdef __cplusplus } #endif diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 0e3afb60c0c883dcf171e7dd92f2b07dcf1ef5f8..f747ccf3b636e27bc320b5d9e818b2082cca88fd 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -89,13 +89,12 @@ static void tscInitLogFile() { // todo close the transporter properly void closeTransporter(STscObj* pTscObj) { - if (pTscObj == NULL || pTscObj->pTransporter == NULL) { + if (pTscObj == NULL || pTscObj->pAppInfo->pTransporter == NULL) { return; } - tscDebug("free transporter:%p in connObj: 0x%"PRIx64, pTscObj->pTransporter, pTscObj->id); - rpcClose(pTscObj->pTransporter); - pTscObj->pTransporter = NULL; + tscDebug("free transporter:%p in connObj: 0x%"PRIx64, pTscObj->pAppInfo->pTransporter, pTscObj->id); + rpcClose(pTscObj->pAppInfo->pTransporter); } // TODO refactor @@ -140,10 +139,6 @@ void* createTscObj(const char* user, const char* auth, const char *db, SAppInstI } pObj->pAppInfo = pAppInfo; - if (pAppInfo != NULL) { - pObj->pTransporter = pAppInfo->pTransporter; - } - tstrncpy(pObj->user, user, sizeof(pObj->user)); memcpy(pObj->pass, auth, TSDB_PASSWORD_LEN); @@ -199,6 +194,7 @@ static void doDestroyRequest(void* p) { tfree(pRequest->pInfo); doFreeReqResultInfo(&pRequest->body.resInfo); + qDestroyQueryDag(pRequest->body.pDag); deregisterRequest(pRequest); tfree(pRequest); diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 9bbd62c1d9bfcdf095c0fd15140e2f644cb756b8..6d7fc9f81a1de3effef84893bc1469afdca40732 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "clientHb.h" +#include "clientInt.h" #include "trpc.h" static SClientHbMgr clientHbMgr = {0}; @@ -21,10 +21,18 @@ static SClientHbMgr clientHbMgr = {0}; static int32_t hbCreateThread(); static void hbStopThread(); -static int32_t hbMqHbRspHandle(SClientHbRsp* pReq) { +static int32_t hbMqHbRspHandle(SClientHbRsp* pRsp) { return 0; } +static int32_t hbMqAsyncCallBack(void* param, const SDataBuf* pMsg, int32_t code) { + if (code != 0) { + return -1; + } + SClientHbRsp* pRsp = (SClientHbRsp*) pMsg->pData; + return hbMqHbRspHandle(pRsp); +} + void hbMgrInitMqHbRspHandle() { clientHbMgr.handle[HEARTBEAT_TYPE_MQ] = hbMqHbRspHandle; } @@ -35,18 +43,18 @@ static FORCE_INLINE void hbMgrInitHandle() { } SClientHbBatchReq* hbGatherAllInfo(SAppHbMgr *pAppHbMgr) { - SClientHbBatchReq* pReq = malloc(sizeof(SClientHbBatchReq)); - if (pReq == NULL) { + SClientHbBatchReq* pBatchReq = malloc(sizeof(SClientHbBatchReq)); + if (pBatchReq == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } int32_t connKeyCnt = atomic_load_32(&pAppHbMgr->connKeyCnt); - pReq->reqs = taosArrayInit(connKeyCnt, sizeof(SClientHbReq)); + pBatchReq->reqs = taosArrayInit(connKeyCnt, sizeof(SClientHbReq)); void *pIter = taosHashIterate(pAppHbMgr->activeInfo, NULL); while (pIter != NULL) { - taosArrayPush(pReq->reqs, pIter); SClientHbReq* pOneReq = pIter; + taosArrayPush(pBatchReq->reqs, pOneReq); taosHashClear(pOneReq->info); pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); @@ -59,10 +67,10 @@ SClientHbBatchReq* hbGatherAllInfo(SAppHbMgr *pAppHbMgr) { taosHashCopyKey(pIter, &connKey); getConnInfoFp(connKey, NULL); - pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); + pIter = taosHashIterate(pAppHbMgr->getInfoFuncs, pIter); } - return pReq; + return pBatchReq; } static void* hbThreadFunc(void* param) { @@ -75,20 +83,48 @@ static void* hbThreadFunc(void* param) { int sz = taosArrayGetSize(clientHbMgr.appHbMgrs); for(int i = 0; i < sz; i++) { - SAppHbMgr* pAppHbMgr = taosArrayGet(clientHbMgr.appHbMgrs, i); - SClientHbBatchReq* pReq = hbGatherAllInfo(pAppHbMgr); - void* reqStr = NULL; - int tlen = tSerializeSClientHbBatchReq(&reqStr, pReq); - SMsgSendInfo info; - /*info.fp = hbHandleRsp;*/ + SAppHbMgr* pAppHbMgr = taosArrayGetP(clientHbMgr.appHbMgrs, i); + int32_t connCnt = atomic_load_32(&pAppHbMgr->connKeyCnt); + if (connCnt == 0) { + continue; + } + SClientHbBatchReq* pReq = hbGatherAllInfo(pAppHbMgr); + if (pReq == NULL) { + continue; + } + int tlen = tSerializeSClientHbBatchReq(NULL, pReq); + void *buf = malloc(tlen); + if (buf == NULL) { + //TODO: error handling + break; + } + void *bufCopy = buf; + tSerializeSClientHbBatchReq(&bufCopy, pReq); + SMsgSendInfo *pInfo = malloc(sizeof(SMsgSendInfo)); + if (pInfo == NULL) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; + tFreeClientHbBatchReq(pReq); + free(buf); + break; + } + pInfo->fp = hbMqAsyncCallBack; + pInfo->msgInfo.pData = buf; + pInfo->msgInfo.len = tlen; + pInfo->msgType = TDMT_MND_HEARTBEAT; + pInfo->param = NULL; + pInfo->requestId = generateRequestId(); + pInfo->requestObjRefId = 0; + + SAppInstInfo *pAppInstInfo = pAppHbMgr->pAppInstInfo; int64_t transporterId = 0; - asyncSendMsgToServer(pAppHbMgr->transporter, &pAppHbMgr->epSet, &transporterId, &info); + SEpSet epSet = getEpSet_s(&pAppInstInfo->mgmtEp); + asyncSendMsgToServer(pAppInstInfo->pTransporter, &epSet, &transporterId, pInfo); tFreeClientHbBatchReq(pReq); atomic_add_fetch_32(&pAppHbMgr->reportCnt, 1); - taosMsleep(HEARTBEAT_INTERVAL); } + taosMsleep(HEARTBEAT_INTERVAL); } return NULL; } @@ -110,7 +146,8 @@ static void hbStopThread() { atomic_store_8(&clientHbMgr.threadStop, 1); } -SAppHbMgr* appHbMgrInit(void* transporter, SEpSet epSet) { +SAppHbMgr* appHbMgrInit(SAppInstInfo* pAppInstInfo) { + hbMgrInit(); SAppHbMgr* pAppHbMgr = malloc(sizeof(SAppHbMgr)); if (pAppHbMgr == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -119,16 +156,27 @@ SAppHbMgr* appHbMgrInit(void* transporter, SEpSet epSet) { // init stat pAppHbMgr->startTime = taosGetTimestampMs(); - // init connection info - pAppHbMgr->transporter = transporter; - pAppHbMgr->epSet = epSet; + // init app info + pAppHbMgr->pAppInstInfo = pAppInstInfo; // init hash info pAppHbMgr->activeInfo = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + + if (pAppHbMgr->activeInfo == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + free(pAppHbMgr); + return NULL; + } pAppHbMgr->activeInfo->freeFp = tFreeClientHbReq; // init getInfoFunc pAppHbMgr->getInfoFuncs = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + if (pAppHbMgr->getInfoFuncs == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + free(pAppHbMgr); + return NULL; + } + taosArrayPush(clientHbMgr.appHbMgrs, &pAppHbMgr); return pAppHbMgr; } @@ -138,7 +186,7 @@ void appHbMgrCleanup(SAppHbMgr* pAppHbMgr) { int sz = taosArrayGetSize(clientHbMgr.appHbMgrs); for (int i = 0; i < sz; i++) { - SAppHbMgr* pTarget = taosArrayGet(clientHbMgr.appHbMgrs, i); + SAppHbMgr* pTarget = taosArrayGetP(clientHbMgr.appHbMgrs, i); if (pAppHbMgr == pTarget) { taosHashCleanup(pTarget->activeInfo); taosHashCleanup(pTarget->getInfoFuncs); @@ -171,7 +219,6 @@ void hbMgrCleanUp() { if (old == 0) return; taosArrayDestroy(clientHbMgr.appHbMgrs); - } int hbHandleRsp(SClientHbBatchRsp* hbRsp) { diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index ba08e67127c37e2ad393515539ec4c50cbcefd38..e2143d20df976c35675c031a8ad4ff8d51f14bd5 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -13,12 +13,12 @@ #include "tpagedfile.h" #include "tref.h" -#define CHECK_CODE_GOTO(expr, lable) \ +#define CHECK_CODE_GOTO(expr, label) \ do { \ int32_t code = expr; \ if (TSDB_CODE_SUCCESS != code) { \ terrno = code; \ - goto lable; \ + goto label; \ } \ } while (0) @@ -58,7 +58,7 @@ static char* getClusterKey(const char* user, const char* auth, const char* ip, i return strdup(key); } -static STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo); +static STscObj* taosConnectImpl(const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo); static void setResSchemaInfo(SReqResultInfo* pResInfo, const SDataBlockSchema* pDataBlockSchema); TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port) { @@ -71,18 +71,18 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, return NULL; } - char tmp[TSDB_DB_NAME_LEN] = {0}; + char localDb[TSDB_DB_NAME_LEN] = {0}; if (db != NULL) { if(!validateDbName(db)) { terrno = TSDB_CODE_TSC_INVALID_DB_LENGTH; return NULL; } - tstrncpy(tmp, db, sizeof(tmp)); - strdequote(tmp); + tstrncpy(localDb, db, sizeof(localDb)); + strdequote(localDb); } - char secretEncrypt[32] = {0}; + char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0}; if (auth == NULL) { if (!validatePassword(pass)) { terrno = TSDB_CODE_TSC_INVALID_PASS_LENGTH; @@ -111,18 +111,20 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, char* key = getClusterKey(user, secretEncrypt, ip, port); + // TODO: race condition here. SAppInstInfo** pInst = taosHashGet(appInfo.pInstMap, key, strlen(key)); if (pInst == NULL) { SAppInstInfo* p = calloc(1, sizeof(struct SAppInstInfo)); p->mgmtEp = epSet; p->pTransporter = openTransporter(user, secretEncrypt, tsNumOfCores); + p->pAppHbMgr = appHbMgrInit(p); taosHashPut(appInfo.pInstMap, key, strlen(key), &p, POINTER_BYTES); pInst = &p; } tfree(key); - return taosConnectImpl(ip, user, &secretEncrypt[0], db, port, NULL, NULL, *pInst); + return taosConnectImpl(user, &secretEncrypt[0], localDb, port, NULL, NULL, *pInst); } int32_t buildRequest(STscObj *pTscObj, const char *sql, int sqlLen, SRequestObj** pRequest) { @@ -152,13 +154,13 @@ int32_t parseSql(SRequestObj* pRequest, SQueryNode** pQuery) { SParseContext cxt = { .requestId = pRequest->requestId, - .acctId = pTscObj->acctId, - .db = getConnectionDB(pTscObj), - .pTransporter = pTscObj->pTransporter, - .pSql = pRequest->sqlstr, - .sqlLen = pRequest->sqlLen, - .pMsg = pRequest->msgBuf, - .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE + .acctId = pTscObj->acctId, + .db = getConnectionDB(pTscObj), + .pSql = pRequest->sqlstr, + .sqlLen = pRequest->sqlLen, + .pMsg = pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, + .pTransporter = pTscObj->pAppInfo->pTransporter, }; cxt.mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); @@ -191,10 +193,10 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQueryNode* pQuery) { pShowReqInfo->pArray = pDcl->pExtension; } } - asyncSendMsgToServer(pTscObj->pTransporter, &pDcl->epSet, &transporterId, pSendMsg); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pDcl->epSet, &transporterId, pSendMsg); } else { SEpSet* pEpSet = &pTscObj->pAppInfo->mgmtEp.epSet; - asyncSendMsgToServer(pTscObj->pTransporter, pEpSet, &transporterId, pSendMsg); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, pEpSet, &transporterId, pSendMsg); } tsem_wait(&pRequest->body.rspSem); @@ -241,7 +243,7 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag) { if (TSDB_SQL_INSERT == pRequest->type || TSDB_SQL_CREATE_TABLE == pRequest->type) { SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf}; - int32_t code = scheduleExecJob(pRequest->pTscObj->pTransporter, NULL, pDag, &pRequest->body.pQueryJob, &res); + int32_t code = scheduleExecJob(pRequest->pTscObj->pAppInfo->pTransporter, NULL, pDag, &pRequest->body.pQueryJob, &res); if (code != TSDB_CODE_SUCCESS) { // handle error and retry } else { @@ -255,39 +257,160 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag) { return pRequest->code; } - return scheduleAsyncExecJob(pRequest->pTscObj->pTransporter, NULL, pDag, &pRequest->body.pQueryJob); + return scheduleAsyncExecJob(pRequest->pTscObj->pAppInfo->pTransporter, NULL, pDag, &pRequest->body.pQueryJob); } -TAOS_RES *tmq_create_topic(TAOS* taos, const char* name, const char* sql, int sqlLen) { - STscObj* pTscObj = (STscObj*)taos; - SRequestObj* pRequest = NULL; - SQueryNode* pQuery = NULL; - SQueryDag* pDag = NULL; - char *dagStr = NULL; +typedef struct tmq_t tmq_t; + +typedef struct SMqClientTopic { + // subscribe info + int32_t sqlLen; + char* sql; + char* topicName; + int64_t topicId; + // statistics + int64_t consumeCnt; + // offset + int64_t committedOffset; + int64_t currentOffset; + //connection info + int32_t vgId; + SEpSet epSet; +} SMqClientTopic; + +typedef struct tmq_resp_err_t { + int32_t code; +} tmq_resp_err_t; + +typedef struct tmq_topic_vgroup_list_t { + char* topicName; + int32_t vgId; + int64_t committedOffset; +} tmq_topic_vgroup_list_t; + +typedef void (tmq_commit_cb(tmq_t*, tmq_resp_err_t, tmq_topic_vgroup_list_t*, void* param)); + +typedef struct tmq_conf_t{ + char* clientId; + char* groupId; + char* ip; + uint16_t port; + tmq_commit_cb* commit_cb; +} tmq_conf_t; + +struct tmq_t { + char groupId[256]; + char clientId[256]; + STscObj* pTscObj; + tmq_commit_cb* commit_cb; + SArray* clientTopics; // SArray +}; + +void tmq_conf_set_offset_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb) { + conf->commit_cb = cb; +} + +SArray* tmqGetConnInfo(SClientHbKey connKey, void* param) { + tmq_t* pTmq = (void*)param; + SArray* pArray = taosArrayInit(0, sizeof(SKv)); + if (pArray == NULL) { + return NULL; + } + SKv kv = {0}; + kv.key = malloc(256); + if (kv.key == NULL) { + taosArrayDestroy(pArray); + return NULL; + } + strcpy(kv.key, "groupId"); + kv.keyLen = strlen("groupId") + 1; + kv.value = malloc(256); + if (kv.value == NULL) { + free(kv.key); + taosArrayDestroy(pArray); + return NULL; + } + strcpy(kv.value, pTmq->groupId); + kv.valueLen = strlen(pTmq->groupId) + 1; + + taosArrayPush(pArray, &kv); + strcpy(kv.key, "clientUid"); + kv.keyLen = strlen("clientUid") + 1; + *(uint32_t*)kv.value = pTmq->pTscObj->connId; + kv.valueLen = sizeof(uint32_t); + + return NULL; +} + +tmq_t* tmqCreateConsumerImpl(TAOS* conn, tmq_conf_t* conf) { + tmq_t* pTmq = malloc(sizeof(tmq_t)); + if (pTmq == NULL) { + return NULL; + } + strcpy(pTmq->groupId, conf->groupId); + strcpy(pTmq->clientId, conf->clientId); + pTmq->pTscObj = (STscObj*)conn; + pTmq->pTscObj->connType = HEARTBEAT_TYPE_MQ; + + return pTmq; +} + +TAOS_RES *taos_create_topic(TAOS* taos, const char* topicName, const char* sql, int sqlLen) { + STscObj *pTscObj = (STscObj*)taos; + SRequestObj *pRequest = NULL; + SQueryNode *pQueryNode = NULL; + char *pStr = NULL; terrno = TSDB_CODE_SUCCESS; + if (taos == NULL || topicName == NULL || sql == NULL) { + tscError("invalid parameters for creating topic, connObj:%p, topic name:%s, sql:%s", taos, topicName, sql); + terrno = TSDB_CODE_TSC_INVALID_INPUT; + goto _return; + } + + if (strlen(topicName) >= TSDB_TOPIC_NAME_LEN) { + tscError("topic name too long, max length:%d", TSDB_TOPIC_NAME_LEN - 1); + terrno = TSDB_CODE_TSC_INVALID_INPUT; + goto _return; + } + + if (sqlLen > tsMaxSQLStringLen) { + tscError("sql string exceeds max length:%d", tsMaxSQLStringLen); + terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT; + goto _return; + } + + tscDebug("start to create topic, %s", topicName); CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); + CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return); -//temporary disabled until planner ready -#if 0 - CHECK_CODE_GOTO(parseSql(pRequest, &pQuery), _return); - //TODO: check sql valid + // todo check for invalid sql statement and return with error code - CHECK_CODE_GOTO(qCreateQueryDag(pQuery, &pDag), _return); + CHECK_CODE_GOTO(qCreateQueryDag(pQueryNode, &pRequest->body.pDag, pRequest->requestId), _return); - dagStr = qDagToString(pDag); - if(dagStr == NULL) { - //TODO + pStr = qDagToString(pRequest->body.pDag); + if(pStr == NULL) { + goto _return; } -#endif + + // The topic should be related to a database that the queried table is belonged to. + SName name = {0}; + char dbName[TSDB_DB_FNAME_LEN] = {0}; + tNameGetFullDbName(&((SQueryStmtInfo*) pQueryNode)->pTableMetaInfo[0]->name, dbName); + + tNameFromString(&name, dbName, T_NAME_ACCT|T_NAME_DB); + tNameFromString(&name, topicName, T_NAME_TABLE); + + char topicFname[TSDB_TOPIC_FNAME_LEN] = {0}; + tNameExtractFullName(&name, topicFname); SCMCreateTopicReq req = { - .name = (char*)name, - .igExists = 0, - /*.physicalPlan = dagStr,*/ - .physicalPlan = (char*)sql, - .logicalPlan = "", + .name = (char*) topicFname, + .igExists = 0, + .physicalPlan = (char*) pStr, + .sql = (char*) sql, + .logicalPlan = "no logic plan", }; int tlen = tSerializeSCMCreateTopicReq(NULL, &req); @@ -295,30 +418,54 @@ TAOS_RES *tmq_create_topic(TAOS* taos, const char* name, const char* sql, int sq if(buf == NULL) { goto _return; } + void* abuf = buf; tSerializeSCMCreateTopicReq(&abuf, &req); /*printf("formatted: %s\n", dagStr);*/ pRequest->body.requestMsg = (SDataBuf){ .pData = buf, .len = tlen }; + pRequest->type = TDMT_MND_CREATE_TOPIC; SMsgSendInfo* body = buildMsgInfoImpl(pRequest); - SEpSet* pEpSet = &pTscObj->pAppInfo->mgmtEp.epSet; + SEpSet epSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp); int64_t transporterId = 0; - asyncSendMsgToServer(pTscObj->pTransporter, pEpSet, &transporterId, body); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); _return: - qDestroyQuery(pQuery); - qDestroyQueryDag(pDag); - destroySendMsgInfo(body); + qDestroyQuery(pQueryNode); + if (body != NULL) { + destroySendMsgInfo(body); + } + if (pRequest != NULL && terrno != TSDB_CODE_SUCCESS) { pRequest->code = terrno; } + return pRequest; } +typedef struct tmq_message_t { + int32_t numOfRows; + char* topicName; + TAOS_ROW row[]; +} tmq_message_t; + +tmq_message_t* tmq_consume_poll(tmq_t* mq, int64_t blocking_time) { + return NULL; +} + +tmq_resp_err_t* tmq_commit(tmq_t* mq, void* callback, int32_t async) { + return NULL; +} + +void tmq_message_destroy(tmq_message_t* mq_message) { + +} + + TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { STscObj *pTscObj = (STscObj *)taos; if (sqlLen > (size_t) tsMaxSQLStringLen) { @@ -330,24 +477,22 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { nPrintTsc("%s", sql) SRequestObj *pRequest = NULL; - SQueryNode *pQuery = NULL; - SQueryDag *pDag = NULL; + SQueryNode *pQueryNode = NULL; terrno = TSDB_CODE_SUCCESS; CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return); - CHECK_CODE_GOTO(parseSql(pRequest, &pQuery), _return); + CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return); - if (qIsDdlQuery(pQuery)) { - CHECK_CODE_GOTO(execDdlQuery(pRequest, pQuery), _return); + if (qIsDdlQuery(pQueryNode)) { + CHECK_CODE_GOTO(execDdlQuery(pRequest, pQueryNode), _return); } else { - CHECK_CODE_GOTO(getPlan(pRequest, pQuery, &pDag), _return); - CHECK_CODE_GOTO(scheduleQuery(pRequest, pDag), _return); + CHECK_CODE_GOTO(getPlan(pRequest, pQueryNode, &pRequest->body.pDag), _return); + CHECK_CODE_GOTO(scheduleQuery(pRequest, pRequest->body.pDag), _return); pRequest->code = terrno; } _return: - qDestroyQuery(pQuery); - qDestroyQueryDag(pDag); + qDestroyQuery(pQueryNode); if (NULL != pRequest && TSDB_CODE_SUCCESS != terrno) { pRequest->code = terrno; } @@ -391,7 +536,7 @@ int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSe return 0; } -STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo) { +STscObj* taosConnectImpl(const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo) { STscObj *pTscObj = createTscObj(user, auth, db, pAppInfo); if (NULL == pTscObj) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -408,7 +553,7 @@ STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, con SMsgSendInfo* body = buildConnectMsg(pRequest); int64_t transporterId = 0; - asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); if (pRequest->code != TSDB_CODE_SUCCESS) { @@ -419,7 +564,7 @@ STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, con taos_close(pTscObj); pTscObj = NULL; } else { - tscDebug("0x%"PRIx64" connection is opening, connId:%d, dnodeConn:%p, reqId:0x%"PRIx64, pTscObj->id, pTscObj->connId, pTscObj->pTransporter, pRequest->requestId); + tscDebug("0x%"PRIx64" connection is opening, connId:%d, dnodeConn:%p, reqId:0x%"PRIx64, pTscObj->id, pTscObj->connId, pTscObj->pAppInfo->pTransporter, pRequest->requestId); destroyRequest(pRequest); } @@ -450,7 +595,9 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj *pRequest) { STscObj *pObj = pRequest->pTscObj; char* db = getConnectionDB(pObj); - tstrncpy(pConnect->db, db, sizeof(pConnect->db)); + if (db != NULL) { + tstrncpy(pConnect->db, db, sizeof(pConnect->db)); + } tfree(db); pConnect->pid = htonl(appInfo.pid); @@ -587,7 +734,7 @@ void* doFetchRow(SRequestObj* pRequest) { int64_t transporterId = 0; STscObj *pTscObj = pRequest->pTscObj; - asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); pRequest->type = TDMT_VND_SHOW_TABLES_FETCH; @@ -597,7 +744,7 @@ void* doFetchRow(SRequestObj* pRequest) { int64_t transporterId = 0; STscObj *pTscObj = pRequest->pTscObj; - asyncSendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); + asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &transporterId, body); tsem_wait(&pRequest->body.rspSem); @@ -650,9 +797,12 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t char* getConnectionDB(STscObj* pObj) { char *p = NULL; pthread_mutex_lock(&pObj->mutex); - p = strndup(pObj->db, tListLen(pObj->db)); - pthread_mutex_unlock(&pObj->mutex); + size_t len = strlen(pObj->db); + if (len > 0) { + p = strndup(pObj->db, tListLen(pObj->db)); + } + pthread_mutex_unlock(&pObj->mutex); return p; } @@ -673,4 +823,4 @@ void setQueryResultByRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* p pResultInfo->completed = (pRsp->completed == 1); setResultDataPtr(pResultInfo, pResultInfo->fields, pResultInfo->numOfCols, pResultInfo->numOfRows); -} \ No newline at end of file +} diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 4f1a96ad29d90f9ab3b3c8e1d0e5b6493adaf338..497ef1ac95d01f426a34bfd3974c3737c9bdd8c7 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -71,6 +71,9 @@ int processConnectRsp(void* param, const SDataBuf* pMsg, int32_t code) { pTscObj->pAppInfo->clusterId = pConnect->clusterId; atomic_add_fetch_64(&pTscObj->pAppInfo->numOfConns, 1); + SClientHbKey connKey = {.connId = pConnect->connId, .hbType = HEARTBEAT_TYPE_QUERY}; + hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey, NULL); + // pRequest->body.resInfo.pRspMsg = pMsg->pData; tscDebug("0x%" PRIx64 " clusterId:%" PRId64 ", totalConn:%" PRId64, pRequest->requestId, pConnect->clusterId, pTscObj->pAppInfo->numOfConns); @@ -379,4 +382,4 @@ void initMsgHandleFp() { handleRequestRspFp[TMSG_INDEX(TDMT_VND_SHOW_TABLES)] = processShowRsp; handleRequestRspFp[TMSG_INDEX(TDMT_VND_SHOW_TABLES_FETCH)] = processRetrieveVndRsp; -} \ No newline at end of file +} diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index d1093bb1a6e5753204786f256eb872e242146b27..9810b308574eacf78e29e3104bbab49b856532c4 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -53,6 +53,7 @@ TEST(testCase, connect_Test) { if (pConn == NULL) { printf("failed to connect to server, reason:%s\n", taos_errstr(NULL)); } + sleep(3); taos_close(pConn); } @@ -148,27 +149,27 @@ TEST(testCase, connect_Test) { //} // //TEST(testCase, create_db_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); -// -// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); -// if (taos_errno(pRes) != 0) { -// printf("error in create db, reason:%s\n", taos_errstr(pRes)); -// } -// -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// ASSERT_TRUE(pFields == NULL); -// -// int32_t numOfFields = taos_num_fields(pRes); -// ASSERT_EQ(numOfFields, 0); -// -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "create database abc1 vgroups 4"); -// if (taos_errno(pRes) != 0) { -// printf("error in create db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_close(pConn); + //TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + //assert(pConn != NULL); + + //TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); + //if (taos_errno(pRes) != 0) { + //printf("error in create db, reason:%s\n", taos_errstr(pRes)); + //} + + //TAOS_FIELD* pFields = taos_fetch_fields(pRes); + //ASSERT_TRUE(pFields == NULL); + + //int32_t numOfFields = taos_num_fields(pRes); + //ASSERT_EQ(numOfFields, 0); + + //taos_free_result(pRes); + + //pRes = taos_query(pConn, "create database abc1 vgroups 4"); + //if (taos_errno(pRes) != 0) { + //printf("error in create db, reason:%s\n", taos_errstr(pRes)); + //} + //taos_close(pConn); //} // //TEST(testCase, create_dnode_Test) { @@ -194,7 +195,7 @@ TEST(testCase, connect_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // assert(pConn != NULL); // -// TAOS_RES* pRes = taos_query(pConn, "drop dnode 2"); +// TAOS_RES* pRes = taos_query(pConn, "drop dnode 3"); // if (taos_errno(pRes) != 0) { // printf("error in drop dnode, reason:%s\n", taos_errstr(pRes)); // } @@ -205,6 +206,11 @@ TEST(testCase, connect_Test) { // int32_t numOfFields = taos_num_fields(pRes); // ASSERT_EQ(numOfFields, 0); // +// pRes = taos_query(pConn, "drop dnode 4"); +// if (taos_errno(pRes) != 0) { +// printf("error in drop dnode, reason:%s\n", taos_errstr(pRes)); +// } +// // taos_free_result(pRes); // taos_close(pConn); //} @@ -227,45 +233,39 @@ TEST(testCase, connect_Test) { // taos_close(pConn); //} // -//// TEST(testCase, drop_db_test) { -//// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -//// assert(pConn != NULL); -//// -//// showDB(pConn); -//// -//// TAOS_RES* pRes = taos_query(pConn, "drop database abc1"); -//// if (taos_errno(pRes) != 0) { -//// printf("failed to drop db, reason:%s\n", taos_errstr(pRes)); -//// } -//// taos_free_result(pRes); -//// -//// showDB(pConn); -//// -//// pRes = taos_query(pConn, "create database abc1"); -//// if (taos_errno(pRes) != 0) { -//// printf("create to drop db, reason:%s\n", taos_errstr(pRes)); -//// } -//// taos_free_result(pRes); -//// taos_close(pConn); -////} -// -//TEST(testCase, create_stable_Test) { +// TEST(testCase, drop_db_test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // assert(pConn != NULL); // -// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); +// showDB(pConn); +// +// TAOS_RES* pRes = taos_query(pConn, "drop database abc1"); // if (taos_errno(pRes) != 0) { -// printf("error in create db, reason:%s\n", taos_errstr(pRes)); +// printf("failed to drop db, reason:%s\n", taos_errstr(pRes)); // } // taos_free_result(pRes); // -// pRes = taos_query(pConn, "use abc1"); +// showDB(pConn); +// +// pRes = taos_query(pConn, "create database abc1"); // if (taos_errno(pRes) != 0) { -// printf("error in use db, reason:%s\n", taos_errstr(pRes)); +// printf("create to drop db, reason:%s\n", taos_errstr(pRes)); // } // taos_free_result(pRes); +// taos_close(pConn); +//} + +//TEST(testCase, create_stable_Test) { +// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); +// assert(pConn != NULL); // -// pRes = taos_query(pConn, "create stable st1(ts timestamp, k int) tags(a int)"); +// TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 2"); +// if (taos_errno(pRes) != 0) { +// printf("error in create db, reason:%s\n", taos_errstr(pRes)); +// } +// taos_free_result(pRes); +// +// pRes = taos_query(pConn, "create table if not exists abc1.st1(ts timestamp, k int) tags(a int)"); // if (taos_errno(pRes) != 0) { // printf("error in create stable, reason:%s\n", taos_errstr(pRes)); // } @@ -277,42 +277,41 @@ TEST(testCase, connect_Test) { // ASSERT_EQ(numOfFields, 0); // // taos_free_result(pRes); -// taos_close(pConn); -//} - -//TEST(testCase, create_table_Test) { -// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// assert(pConn != NULL); // -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// taos_free_result(pRes); +// pRes = taos_query(pConn, "create stable if not exists abc1.`123_$^)` (ts timestamp, `abc` int) tags(a int)"); +// if (taos_errno(pRes) != 0) { +// printf("failed to create super table 123_$^), reason:%s\n", taos_errstr(pRes)); +// } // -// pRes = taos_query(pConn, "create table tm0(ts timestamp, k int)"); // taos_free_result(pRes); +// pRes = taos_query(pConn, "drop stable `123_$^)`"); +// if (taos_errno(pRes) != 0) { +// printf("failed to drop super table 123_$^), reason:%s\n", taos_errstr(pRes)); +// } // // taos_close(pConn); //} -TEST(testCase, create_ctable_Test) { +TEST(testCase, create_table_Test) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); assert(pConn != NULL); TAOS_RES* pRes = taos_query(pConn, "use abc1"); - if (taos_errno(pRes) != 0) { - printf("failed to use db, reason:%s\n", taos_errstr(pRes)); - } taos_free_result(pRes); - pRes = taos_query(pConn, "create table tm0 using st1 tags(1)"); - if (taos_errno(pRes) != 0) { - printf("failed to create child table tm0, reason:%s\n", taos_errstr(pRes)); - } + pRes = taos_query(pConn, "create table if not exists tm0(ts timestamp, k int)"); + ASSERT_EQ(taos_errno(pRes), 0); + + taos_free_result(pRes); + + pRes = taos_query(pConn, "create table if not exists tm0(ts timestamp, k blob)"); + ASSERT_NE(taos_errno(pRes), 0); taos_free_result(pRes); taos_close(pConn); } -//TEST(testCase, show_stable_Test) { +//TEST(testCase, create_ctable_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // assert(pConn != NULL); // @@ -322,26 +321,45 @@ TEST(testCase, create_ctable_Test) { // } // taos_free_result(pRes); // -// pRes = taos_query(pConn, "show stables"); +// pRes = taos_query(pConn, "create table tm0 using st1 tags(1)"); // if (taos_errno(pRes) != 0) { -// printf("failed to show stables, reason:%s\n", taos_errstr(pRes)); -// taos_free_result(pRes); -// ASSERT_TRUE(false); -// } -// -// TAOS_ROW pRow = NULL; -// TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// int32_t numOfFields = taos_num_fields(pRes); -// -// char str[512] = {0}; -// while ((pRow = taos_fetch_row(pRes)) != NULL) { -// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); -// printf("%s\n", str); +// printf("failed to create child table tm0, reason:%s\n", taos_errstr(pRes)); // } // // taos_free_result(pRes); // taos_close(pConn); //} + +TEST(testCase, show_stable_Test) { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + assert(pConn != nullptr); + +// TAOS_RES* pRes = taos_query(pConn, "use abc1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to use db, reason:%s\n", taos_errstr(pRes)); +// } +// taos_free_result(pRes); + + TAOS_RES* pRes = taos_query(pConn, "show abc1.stables"); + if (taos_errno(pRes) != 0) { + printf("failed to show stables, reason:%s\n", taos_errstr(pRes)); + taos_free_result(pRes); + ASSERT_TRUE(false); + } + + TAOS_ROW pRow = NULL; + TAOS_FIELD* pFields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_num_fields(pRes); + + char str[512] = {0}; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + int32_t code = taos_print_row(str, pRow, pFields, numOfFields); + printf("%s\n", str); + } + + taos_free_result(pRes); + taos_close(pConn); +} // //TEST(testCase, show_vgroup_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); @@ -499,44 +517,34 @@ TEST(testCase, create_ctable_Test) { // // taosHashCleanup(phash); //} - -// TEST(testCase, create_topic_Test) { +// +//TEST(testCase, create_topic_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // assert(pConn != NULL); // -// TAOS_RES* pRes = taos_query(pConn, "create database abc1"); -// if (taos_errno(pRes) != 0) { -// printf("error in create db, reason:%s\n", taos_errstr(pRes)); -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "use abc1"); +// TAOS_RES* pRes = taos_query(pConn, "use abc1"); // if (taos_errno(pRes) != 0) { // printf("error in use db, reason:%s\n", taos_errstr(pRes)); // } // taos_free_result(pRes); // -// pRes = taos_query(pConn, "create stable st1(ts timestamp, k int) tags(a int)"); -// if (taos_errno(pRes) != 0) { -// printf("error in create stable, reason:%s\n", taos_errstr(pRes)); -// } -// // TAOS_FIELD* pFields = taos_fetch_fields(pRes); -// ASSERT_TRUE(pFields == NULL); +// ASSERT_TRUE(pFields == nullptr); // // int32_t numOfFields = taos_num_fields(pRes); // ASSERT_EQ(numOfFields, 0); // // taos_free_result(pRes); // -// char* sql = "select * from st1"; -// tmq_create_topic(pConn, "test_topic_1", sql, strlen(sql)); +// char* sql = "select * from tu"; +// pRes = taos_create_topic(pConn, "test_topic_1", sql, strlen(sql)); +// taos_free_result(pRes); // taos_close(pConn); //} - +// //TEST(testCase, insert_test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); -// ASSERT_EQ(pConn, nullptr); +// ASSERT_NE(pConn, nullptr); // // TAOS_RES* pRes = taos_query(pConn, "use abc1"); // taos_free_result(pRes); @@ -556,25 +564,31 @@ TEST(testCase, create_ctable_Test) { // TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); // ASSERT_NE(pConn, nullptr); // -//// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2"); +// TAOS_RES* pRes = taos_query(pConn, "use abc1"); +// taos_free_result(pRes); +// +//// pRes = taos_query(pConn, "create stable st1 (ts timestamp, k int) tags(a int)"); //// if (taos_errno(pRes) != 0) { -//// printf("failed to use db, reason:%s\n", taos_errstr(pRes)); -//// taos_free_result(pRes); -//// return; +//// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes)); //// } -// //// taos_free_result(pRes); -// -// TAOS_RES* pRes = taos_query(pConn, "use abc1"); -// -//// pRes = taos_query(pConn, "create table m1 (ts timestamp, k int) tags(a int)"); -// taos_free_result(pRes); //// -//// pRes = taos_query(pConn, "create table tu using m1 tags(1)"); +//// pRes = taos_query(pConn, "create table tu using st1 tags(1)"); +//// if (taos_errno(pRes) != 0) { +//// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes)); +//// } //// taos_free_result(pRes); //// -//// pRes = taos_query(pConn, "insert into tu values(now, 1)"); -//// taos_free_result(pRes); +//// for(int32_t i = 0; i < 100; ++i) { +//// char sql[512] = {0}; +//// sprintf(sql, "insert into tu values(now+%da, %d)", i, i); +//// TAOS_RES* p = taos_query(pConn, sql); +//// if (taos_errno(p) != 0) { +//// printf("failed to insert data, reason:%s\n", taos_errstr(p)); +//// } +//// +//// taos_free_result(p); +//// } // // pRes = taos_query(pConn, "select * from tu"); // if (taos_errno(pRes) != 0) { @@ -596,3 +610,31 @@ TEST(testCase, create_ctable_Test) { // taos_free_result(pRes); // taos_close(pConn); //} + +//TEST(testCase, projection_query_stables) { +// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); +// ASSERT_NE(pConn, nullptr); +// +// TAOS_RES* pRes = taos_query(pConn, "use abc1"); +// taos_free_result(pRes); +// +// pRes = taos_query(pConn, "select ts,k from m1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to select from table, reason:%s\n", taos_errstr(pRes)); +// taos_free_result(pRes); +// ASSERT_TRUE(false); +// } +// +// TAOS_ROW pRow = NULL; +// TAOS_FIELD* pFields = taos_fetch_fields(pRes); +// int32_t numOfFields = taos_num_fields(pRes); +// +// char str[512] = {0}; +// while ((pRow = taos_fetch_row(pRes)) != NULL) { +// int32_t code = taos_print_row(str, pRow, pFields, numOfFields); +// printf("%s\n", str); +// } +// +// taos_free_result(pRes); +// taos_close(pConn); +//} diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 53f59c7d57f4db395bdef1d2ac1ca5e0ef698b25..4d1a07be217fb942317f095cebec5091835feb11 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -89,7 +89,7 @@ int tSerializeSClientHbReq(void **buf, const SClientHbReq *pReq) { int tlen = 0; tlen += taosEncodeSClientHbKey(buf, &pReq->connKey); - int kvNum = taosHashGetSize(pReq->info); + int32_t kvNum = taosHashGetSize(pReq->info); tlen += taosEncodeFixedI32(buf, kvNum); SKv kv; void* pIter = taosHashIterate(pReq->info, pIter); @@ -104,14 +104,15 @@ int tSerializeSClientHbReq(void **buf, const SClientHbReq *pReq) { return tlen; } -void *tDeserializeClientHbReq(void *buf, SClientHbReq *pReq) { - ASSERT(pReq->info != NULL); +void *tDeserializeSClientHbReq(void *buf, SClientHbReq *pReq) { buf = taosDecodeSClientHbKey(buf, &pReq->connKey); // TODO: error handling - int kvNum; - taosDecodeFixedI32(buf, &kvNum); - pReq->info = taosHashInit(kvNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + int32_t kvNum; + buf = taosDecodeFixedI32(buf, &kvNum); + if (pReq->info == NULL) { + pReq->info = taosHashInit(kvNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + } for(int i = 0; i < kvNum; i++) { SKv kv; buf = taosDecodeSKv(buf, &kv); @@ -121,12 +122,69 @@ void *tDeserializeClientHbReq(void *buf, SClientHbReq *pReq) { return buf; } -int tSerializeSClientHbBatchReq(void** buf, const SClientHbBatchReq* pReq) { +int tSerializeSClientHbRsp(void** buf, const SClientHbRsp* pRsp) { + int tlen = 0; + tlen += taosEncodeSClientHbKey(buf, &pRsp->connKey); + tlen += taosEncodeFixedI32(buf, pRsp->status); + tlen += taosEncodeFixedI32(buf, pRsp->bodyLen); + tlen += taosEncodeBinary(buf, pRsp->body, pRsp->bodyLen); + return tlen; +} +void* tDeserializeSClientHbRsp(void* buf, SClientHbRsp* pRsp) { + buf = taosDecodeSClientHbKey(buf, &pRsp->connKey); + buf = taosDecodeFixedI32(buf, &pRsp->status); + buf = taosDecodeFixedI32(buf, &pRsp->bodyLen); + buf = taosDecodeBinary(buf, &pRsp->body, pRsp->bodyLen); + return buf; +} + +int tSerializeSClientHbBatchReq(void** buf, const SClientHbBatchReq* pBatchReq) { int tlen = 0; + tlen += taosEncodeFixedI64(buf, pBatchReq->reqId); + int32_t reqNum = taosArrayGetSize(pBatchReq->reqs); + tlen += taosEncodeFixedI32(buf, reqNum); + for (int i = 0; i < reqNum; i++) { + SClientHbReq* pReq = taosArrayGet(pBatchReq->reqs, i); + tlen += tSerializeSClientHbReq(buf, pReq); + } return tlen; } -void* tDeserializeClientHbBatchReq(void* buf, SClientHbBatchReq* pReq) { +void* tDeserializeSClientHbBatchReq(void* buf, SClientHbBatchReq* pBatchReq) { + buf = taosDecodeFixedI64(buf, &pBatchReq->reqId); + if (pBatchReq->reqs == NULL) { + pBatchReq->reqs = taosArrayInit(0, sizeof(SClientHbReq)); + } + int32_t reqNum; + buf = taosDecodeFixedI32(buf, &reqNum); + for (int i = 0; i < reqNum; i++) { + SClientHbReq req = {0}; + buf = tDeserializeSClientHbReq(buf, &req); + taosArrayPush(pBatchReq->reqs, &req); + } + return buf; +} + +int tSerializeSClientHbBatchRsp(void** buf, const SClientHbBatchRsp* pBatchRsp) { + int tlen = 0; + int32_t sz = taosArrayGetSize(pBatchRsp->rsps); + tlen += taosEncodeFixedI32(buf, sz); + for (int i = 0; i < sz; i++) { + SClientHbRsp* pRsp = taosArrayGet(pBatchRsp->rsps, i); + tlen += tSerializeSClientHbRsp(buf, pRsp); + } + return tlen; +} + +void* tDeserializeSClientHbBatchRsp(void* buf, SClientHbBatchRsp* pBatchRsp) { + int32_t sz; + buf = taosDecodeFixedI32(buf, &sz); + pBatchRsp->rsps = taosArrayInit(sz, sizeof(SClientHbRsp)); + for (int i = 0; i < sz; i++) { + SClientHbRsp rsp = {0}; + buf = tDeserializeSClientHbRsp(buf, &rsp); + taosArrayPush(pBatchRsp->rsps, &rsp); + } return buf; } diff --git a/source/dnode/mgmt/impl/test/CMakeLists.txt b/source/dnode/mgmt/impl/test/CMakeLists.txt index ce93a14d3fc30e6d22877e28a4d04f4e3618a349..4d6ae91def5149030bc26357d3415ee5b50a3c8e 100644 --- a/source/dnode/mgmt/impl/test/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/CMakeLists.txt @@ -5,4 +5,5 @@ add_subdirectory(bnode) add_subdirectory(snode) add_subdirectory(mnode) add_subdirectory(vnode) +add_subdirectory(stb) add_subdirectory(sut) diff --git a/source/dnode/mgmt/impl/test/stb/CMakeLists.txt b/source/dnode/mgmt/impl/test/stb/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..912f892c2985c9c303c446766feaee6557198e1c --- /dev/null +++ b/source/dnode/mgmt/impl/test/stb/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. DSTB_SRC) +add_executable(dnode_test_stb ${DSTB_SRC}) +target_link_libraries( + dnode_test_stb + PUBLIC sut +) + +add_test( + NAME dnode_test_stb + COMMAND dnode_test_stb +) diff --git a/source/dnode/mgmt/impl/test/stb/dstb.cpp b/source/dnode/mgmt/impl/test/stb/dstb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82f5761ffe6857d38c363e91022b6076025ff9af --- /dev/null +++ b/source/dnode/mgmt/impl/test/stb/dstb.cpp @@ -0,0 +1,139 @@ +/** + * @file db.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module vnode tests + * @version 0.1 + * @date 2021-12-20 + * + * @copyright Copyright (c) 2021 + * + */ + +#include "sut.h" + +class DndTestVnode : public ::testing::Test { + protected: + static void SetUpTestSuite() { test.Init("/tmp/dnode_test_stb", 9116); } + static void TearDownTestSuite() { test.Cleanup(); } + + static Testbase test; + + public: + void SetUp() override {} + void TearDown() override {} +}; + +Testbase DndTestVnode::test; + +TEST_F(DndTestVnode, 01_Create_Restart_Drop_Vnode) { + { + for (int i = 0; i < 3; ++i) { + int32_t contLen = sizeof(SCreateVnodeReq); + + SCreateVnodeReq* pReq = (SCreateVnodeReq*)rpcMallocCont(contLen); + pReq->vgId = htonl(2); + pReq->dnodeId = htonl(1); + strcpy(pReq->db, "1.d1"); + pReq->dbUid = htobe64(9527); + pReq->vgVersion = htonl(1); + pReq->cacheBlockSize = htonl(16); + pReq->totalBlocks = htonl(10); + pReq->daysPerFile = htonl(10); + pReq->daysToKeep0 = htonl(3650); + pReq->daysToKeep1 = htonl(3650); + pReq->daysToKeep2 = htonl(3650); + pReq->minRows = htonl(100); + pReq->minRows = htonl(4096); + pReq->commitTime = htonl(3600); + pReq->fsyncPeriod = htonl(3000); + pReq->walLevel = 1; + pReq->precision = 0; + pReq->compression = 2; + pReq->replica = 1; + pReq->quorum = 1; + pReq->update = 0; + pReq->cacheLastRow = 0; + pReq->selfIndex = 0; + for (int r = 0; r < pReq->replica; ++r) { + SReplica* pReplica = &pReq->replicas[r]; + pReplica->id = htonl(1); + pReplica->port = htons(9527); + } + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_CREATE_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (i == 0) { + ASSERT_EQ(pRsp->code, 0); + test.Restart(); + } else { + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED); + } + } + } + + { + for (int i = 0; i < 3; ++i) { + int32_t contLen = sizeof(SAlterVnodeReq); + + SAlterVnodeReq* pReq = (SAlterVnodeReq*)rpcMallocCont(contLen); + pReq->vgId = htonl(2); + pReq->dnodeId = htonl(1); + strcpy(pReq->db, "1.d1"); + pReq->dbUid = htobe64(9527); + pReq->vgVersion = htonl(2); + pReq->cacheBlockSize = htonl(16); + pReq->totalBlocks = htonl(10); + pReq->daysPerFile = htonl(10); + pReq->daysToKeep0 = htonl(3650); + pReq->daysToKeep1 = htonl(3650); + pReq->daysToKeep2 = htonl(3650); + pReq->minRows = htonl(100); + pReq->minRows = htonl(4096); + pReq->commitTime = htonl(3600); + pReq->fsyncPeriod = htonl(3000); + pReq->walLevel = 1; + pReq->precision = 0; + pReq->compression = 2; + pReq->replica = 1; + pReq->quorum = 1; + pReq->update = 0; + pReq->cacheLastRow = 0; + pReq->selfIndex = 0; + for (int r = 0; r < pReq->replica; ++r) { + SReplica* pReplica = &pReq->replicas[r]; + pReplica->id = htonl(1); + pReplica->port = htons(9527); + } + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_ALTER_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + ASSERT_EQ(pRsp->code, 0); + } + } + + { + for (int i = 0; i < 3; ++i) { + int32_t contLen = sizeof(SDropVnodeReq); + + SDropVnodeReq* pReq = (SDropVnodeReq*)rpcMallocCont(contLen); + pReq->vgId = htonl(2); + pReq->dnodeId = htonl(1); + strcpy(pReq->db, "1.d1"); + pReq->dbUid = htobe64(9527); + + SRpcMsg rpcMsg = {0}; + rpcMsg.pCont = pReq; + rpcMsg.contLen = sizeof(SDropVnodeReq); + rpcMsg.msgType = TDMT_DND_DROP_VNODE; + + SRpcMsg* pRsp = test.SendReq(TDMT_DND_DROP_VNODE, pReq, contLen); + ASSERT_NE(pRsp, nullptr); + if (i == 0) { + ASSERT_EQ(pRsp->code, 0); + test.Restart(); + } else { + ASSERT_EQ(pRsp->code, TSDB_CODE_DND_VNODE_NOT_DEPLOYED); + } + } + } +} diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index a55e0dd2b252c328221d7b1e6d644eadf8e5db68..0c2524f48c375b3432d1f7931fefe0e87b302ef0 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -350,7 +350,7 @@ typedef struct SMqTopicObj { // TODO: add cache and change name to id typedef struct SMqConsumerTopic { - char name[TSDB_TOPIC_FNAME_LEN]; + char name[TSDB_TOPIC_NAME_LEN]; SList *vgroups; // SList } SMqConsumerTopic; @@ -409,7 +409,7 @@ typedef struct SMqVGroupHbObj { #if 0 typedef struct SCGroupObj { - char name[TSDB_TOPIC_FNAME_LEN]; + char name[TSDB_TOPIC_NAME_LEN]; int64_t createTime; int64_t updateTime; uint64_t uid; diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index bc4d8902579f27320a33885ea19ab411cd7e60b7..39be41a4e50436e6734aefb32fb3da5861025963 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -613,32 +613,14 @@ static int32_t mndSetUpdateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj static int32_t mndUpdateDb(SMnode *pMnode, SMnodeMsg *pReq, SDbObj *pOld, SDbObj *pNew) { int32_t code = -1; STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, &pReq->rpcMsg); - if (pTrans == NULL) { - mError("db:%s, failed to update since %s", pOld->name, terrstr()); - return terrno; - } + if (pTrans == NULL) goto UPDATE_DB_OVER; mDebug("trans:%d, used to update db:%s", pTrans->id, pOld->name); - if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) { - mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); - goto UPDATE_DB_OVER; - } - - if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) { - mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); - goto UPDATE_DB_OVER; - } - - if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) { - mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); - goto UPDATE_DB_OVER; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - goto UPDATE_DB_OVER; - } + if (mndSetUpdateDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER; + if (mndSetUpdateDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER; + if (mndSetUpdateDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) goto UPDATE_DB_OVER; + if (mndTransPrepare(pMnode, pTrans) != 0) goto UPDATE_DB_OVER; code = 0; diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index fced3facbec8443552b3ec5f90803f23a0da7f7b..79e5d9eae595eb95be701c3f0da8518cbd55f660 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -258,6 +258,39 @@ static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatReq *pReq) { } static int32_t mndProcessHeartBeatReq(SMnodeMsg *pReq) { + SMnode *pMnode = pReq->pMnode; + char *batchReqStr = pReq->rpcMsg.pCont; + SClientHbBatchReq batchReq = {0}; + tDeserializeSClientHbBatchReq(batchReqStr, &batchReq); + SArray *pArray = batchReq.reqs; + int sz = taosArrayGetSize(pArray); + + SClientHbBatchRsp batchRsp = {0}; + batchRsp.rsps = taosArrayInit(0, sizeof(SClientHbRsp)); + + for (int i = 0; i < sz; i++) { + SClientHbReq* pHbReq = taosArrayGet(pArray, i); + if (pHbReq->connKey.hbType == HEARTBEAT_TYPE_QUERY) { + + } else if (pHbReq->connKey.hbType == HEARTBEAT_TYPE_MQ) { + SClientHbRsp rsp = { + .status = 0, + .connKey = pHbReq->connKey, + .bodyLen = 0, + .body = NULL + }; + taosArrayPush(batchRsp.rsps, &rsp); + } + } + int32_t tlen = tSerializeSClientHbBatchRsp(NULL, &batchRsp); + void* buf = rpcMallocCont(tlen); + void* bufCopy = buf; + tSerializeSClientHbBatchRsp(&bufCopy, &batchRsp); + pReq->contLen = tlen; + pReq->pCont = buf; + return 0; + +#if 0 SMnode *pMnode = pReq->pMnode; SProfileMgmt *pMgmt = &pMnode->profileMgmt; @@ -327,6 +360,7 @@ static int32_t mndProcessHeartBeatReq(SMnodeMsg *pReq) { pReq->contLen = sizeof(SConnectRsp); pReq->pCont = pRsp; return 0; +#endif } static int32_t mndProcessKillQueryReq(SMnodeMsg *pReq) { diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c index acdc718f20c3176313bbed172daffc55f7892bba..67aeae0d4c3f35b1637b1d1ec51f2809e28bc4dc 100644 --- a/source/dnode/mnode/impl/src/mndTopic.c +++ b/source/dnode/mnode/impl/src/mndTopic.c @@ -118,11 +118,13 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) { SDB_GET_INT64(pRaw, dataPos, &pTopic->dbUid, TOPIC_DECODE_OVER); SDB_GET_INT32(pRaw, dataPos, &pTopic->version, TOPIC_DECODE_OVER); SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER); + + pTopic->sql = calloc(pTopic->sqlLen + 1, sizeof(char)); SDB_GET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_DECODE_OVER); - SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); - SDB_GET_BINARY(pRaw, dataPos, pTopic->logicalPlan, len, TOPIC_DECODE_OVER); - SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); - SDB_GET_BINARY(pRaw, dataPos, pTopic->physicalPlan, len, TOPIC_DECODE_OVER); +// SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); +// SDB_GET_BINARY(pRaw, dataPos, pTopic->logicalPlan, len, TOPIC_DECODE_OVER); +// SDB_GET_INT32(pRaw, dataPos, &len, TOPIC_DECODE_OVER); +// SDB_GET_BINARY(pRaw, dataPos, pTopic->physicalPlan, len, TOPIC_DECODE_OVER); SDB_GET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_DECODE_OVER) @@ -178,7 +180,7 @@ void mndReleaseTopic(SMnode *pMnode, SMqTopicObj *pTopic) { static SDbObj *mndAcquireDbByTopic(SMnode *pMnode, char *topicName) { SName name = {0}; - tNameFromString(&name, topicName, T_NAME_ACCT | T_NAME_DB | T_NAME_TOPIC); + tNameFromString(&name, topicName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); char db[TSDB_TABLE_FNAME_LEN] = {0}; tNameGetFullDbName(&name, db); @@ -203,20 +205,24 @@ static SDDropTopicReq *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, SMq return pDrop; } -static int32_t mndCheckCreateTopicMsg(SCMCreateTopicReq *pCreate) { +static int32_t mndCheckCreateTopicMsg(SCMCreateTopicReq *creattopReq) { // deserialize and other stuff return 0; } static int32_t mndCreateTopic(SMnode *pMnode, SMnodeMsg *pMsg, SCMCreateTopicReq *pCreate, SDbObj *pDb) { SMqTopicObj topicObj = {0}; - tstrncpy(topicObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN); + tstrncpy(topicObj.name, pCreate->name, TSDB_TOPIC_FNAME_LEN); tstrncpy(topicObj.db, pDb->name, TSDB_DB_FNAME_LEN); topicObj.createTime = taosGetTimestampMs(); topicObj.updateTime = topicObj.createTime; topicObj.uid = mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN); topicObj.dbUid = pDb->uid; topicObj.version = 1; + topicObj.sql = strdup(pCreate->sql); + topicObj.physicalPlan = strdup(pCreate->physicalPlan); + topicObj.logicalPlan = strdup(pCreate->logicalPlan); + topicObj.sqlLen = strlen(pCreate->sql); SSdbRaw *pTopicRaw = mndTopicActionEncode(&topicObj); if (pTopicRaw == NULL) return -1; @@ -228,46 +234,47 @@ static int32_t mndCreateTopic(SMnode *pMnode, SMnodeMsg *pMsg, SCMCreateTopicReq static int32_t mndProcessCreateTopicMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; char *msgStr = pMsg->rpcMsg.pCont; - SCMCreateTopicReq *pCreate; - tDeserializeSCMCreateTopicReq(msgStr, pCreate); - mDebug("topic:%s, start to create", pCreate->name); + SCMCreateTopicReq createTopicReq = {0}; + tDeserializeSCMCreateTopicReq(msgStr, &createTopicReq); + + mDebug("topic:%s, start to create, sql:%s", createTopicReq.name, createTopicReq.sql); - if (mndCheckCreateTopicMsg(pCreate) != 0) { - mError("topic:%s, failed to create since %s", pCreate->name, terrstr()); + if (mndCheckCreateTopicMsg(&createTopicReq) != 0) { + mError("topic:%s, failed to create since %s", createTopicReq.name, terrstr()); return -1; } - SMqTopicObj *pTopic = mndAcquireTopic(pMnode, pCreate->name); + SMqTopicObj *pTopic = mndAcquireTopic(pMnode, createTopicReq.name); if (pTopic != NULL) { sdbRelease(pMnode->pSdb, pTopic); - if (pCreate->igExists) { - mDebug("topic:%s, already exist, ignore exist is set", pCreate->name); + if (createTopicReq.igExists) { + mDebug("topic:%s, already exist, ignore exist is set", createTopicReq.name); return 0; } else { terrno = TSDB_CODE_MND_TOPIC_ALREADY_EXIST; - mError("db:%s, failed to create since %s", pCreate->name, terrstr()); + mError("db:%s, failed to create since %s", createTopicReq.name, terrstr()); return -1; } } - SDbObj *pDb = mndAcquireDbByTopic(pMnode, pCreate->name); + SDbObj *pDb = mndAcquireDbByTopic(pMnode, createTopicReq.name); if (pDb == NULL) { terrno = TSDB_CODE_MND_DB_NOT_SELECTED; - mError("topic:%s, failed to create since %s", pCreate->name, terrstr()); + mError("topic:%s, failed to create since %s", createTopicReq.name, terrstr()); return -1; } - int32_t code = mndCreateTopic(pMnode, pMsg, pCreate, pDb); + int32_t code = mndCreateTopic(pMnode, pMsg, &createTopicReq, pDb); mndReleaseDb(pMnode, pDb); if (code != 0) { terrno = code; - mError("topic:%s, failed to create since %s", pCreate->name, terrstr()); + mError("topic:%s, failed to create since %s", createTopicReq.name, terrstr()); return -1; } - return TSDB_CODE_MND_ACTION_IN_PROGRESS; + return TSDB_CODE_SUCCESS; } static int32_t mndDropTopic(SMnode *pMnode, SMnodeMsg *pMsg, SMqTopicObj *pTopic) { return 0; } diff --git a/source/dnode/mnode/impl/test/profile/profile.cpp b/source/dnode/mnode/impl/test/profile/profile.cpp index bf047517d3bbb47b11ca5582de1660c46bdf597b..4b329886eba63cfd4a1864a4796c73db604fbef0 100644 --- a/source/dnode/mnode/impl/test/profile/profile.cpp +++ b/source/dnode/mnode/impl/test/profile/profile.cpp @@ -96,6 +96,38 @@ TEST_F(MndTestProfile, 03_ConnectMsg_Show) { } TEST_F(MndTestProfile, 04_HeartBeatMsg) { + SClientHbBatchReq batchReq; + batchReq.reqs = taosArrayInit(0, sizeof(SClientHbReq)); + SClientHbReq req = {0}; + req.connKey = {.connId = 123, .hbType = HEARTBEAT_TYPE_MQ}; + req.info = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + SKv kv; + kv.key = (void*)"abc"; + kv.keyLen = 4; + kv.value = (void*)"bcd"; + kv.valueLen = 4; + taosHashPut(req.info, kv.key, kv.keyLen, kv.value, kv.valueLen); + taosArrayPush(batchReq.reqs, &req); + + int32_t tlen = tSerializeSClientHbBatchReq(NULL, &batchReq); + + void* buf = (SClientHbBatchReq*)rpcMallocCont(tlen); + void* bufCopy = buf; + tSerializeSClientHbBatchReq(&bufCopy, &batchReq); + SRpcMsg* pMsg = test.SendReq(TDMT_MND_HEARTBEAT, buf, tlen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + char* pRspChar = (char*)pMsg->pCont; + SClientHbBatchRsp rsp = {0}; + tDeserializeSClientHbBatchRsp(pRspChar, &rsp); + int sz = taosArrayGetSize(rsp.rsps); + ASSERT_EQ(sz, 1); + SClientHbRsp* pRsp = (SClientHbRsp*) taosArrayGet(rsp.rsps, 0); + EXPECT_EQ(pRsp->connKey.connId, 123); + EXPECT_EQ(pRsp->connKey.hbType, HEARTBEAT_TYPE_MQ); + EXPECT_EQ(pRsp->status, 0); + +#if 0 int32_t contLen = sizeof(SHeartBeatReq); SHeartBeatReq* pReq = (SHeartBeatReq*)rpcMallocCont(contLen); @@ -129,9 +161,12 @@ TEST_F(MndTestProfile, 04_HeartBeatMsg) { EXPECT_EQ(pRsp->epSet.numOfEps, 1); EXPECT_EQ(pRsp->epSet.port[0], 9031); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); +#endif } TEST_F(MndTestProfile, 05_KillConnMsg) { + // temporary remove since kill will use new heartbeat msg +#if 0 { int32_t contLen = sizeof(SKillConnReq); @@ -190,6 +225,7 @@ TEST_F(MndTestProfile, 05_KillConnMsg) { connId = pRsp->connId; } +#endif } TEST_F(MndTestProfile, 06_KillConnMsg_InvalidConn) { @@ -204,6 +240,8 @@ TEST_F(MndTestProfile, 06_KillConnMsg_InvalidConn) { } TEST_F(MndTestProfile, 07_KillQueryMsg) { + // temporary remove since kill will use new heartbeat msg +#if 0 { int32_t contLen = sizeof(SKillQueryReq); @@ -252,6 +290,7 @@ TEST_F(MndTestProfile, 07_KillQueryMsg) { EXPECT_EQ(pRsp->epSet.port[0], 9031); EXPECT_STREQ(pRsp->epSet.fqdn[0], "localhost"); } +#endif } TEST_F(MndTestProfile, 08_KillQueryMsg_InvalidConn) { diff --git a/source/dnode/mnode/impl/test/stb/CMakeLists.txt b/source/dnode/mnode/impl/test/stb/CMakeLists.txt index 68e4dfb07f114e7644638938130445549aa023ec..72197daf0997f00f5eeee006d16d8240c2741f48 100644 --- a/source/dnode/mnode/impl/test/stb/CMakeLists.txt +++ b/source/dnode/mnode/impl/test/stb/CMakeLists.txt @@ -1,11 +1,11 @@ aux_source_directory(. STB_SRC) -add_executable(dnode_test_stb ${STB_SRC}) +add_executable(mnode_test_stb ${STB_SRC}) target_link_libraries( - dnode_test_stb + mnode_test_stb PUBLIC sut ) add_test( - NAME dnode_test_stb - COMMAND dnode_test_stb + NAME mnode_test_stb + COMMAND mnode_test_stb ) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 7ff02309ec4664508b2d17377aba8a64553cd2c4..d8de94b204a9f773bff8b134a36de385dd78ff71 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -35,28 +35,26 @@ typedef struct SDnode SDnode; typedef int32_t (*PutReqToVQueryQFp)(SDnode *pDnode, struct SRpcMsg *pReq); typedef struct SVnodeCfg { - int32_t vgId; - SDnode *pDnode; - struct { - uint64_t wsize; - uint64_t ssize; - uint64_t lsize; - bool isHeapAllocator; - }; + int32_t vgId; + SDnode * pDnode; + uint64_t wsize; + uint64_t ssize; + uint64_t lsize; + bool isHeapAllocator; uint32_t ttl; uint32_t keep; - bool isWeak; + bool isWeak; STsdbCfg tsdbCfg; SMetaCfg metaCfg; - STqCfg tqCfg; - SWalCfg walCfg; + STqCfg tqCfg; + SWalCfg walCfg; } SVnodeCfg; typedef struct { int32_t sver; - char *timezone; - char *locale; - char *charset; + char * timezone; + char * locale; + char * charset; uint16_t nthreads; // number of commit threads. 0 for no threads and a schedule queue should be given (TODO) PutReqToVQueryQFp putReqToVQueryQFp; } SVnodeOpt; diff --git a/source/dnode/vnode/src/inc/metaCache.h b/source/dnode/vnode/src/inc/metaCache.h deleted file mode 100644 index 46798f0de40b779c4d2f5afdeba2fa65f3d58705..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaCache.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_META_CACHE_H_ -#define _TD_META_CACHE_H_ - -#include "meta.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SMetaCache SMetaCache; - -int metaOpenCache(SMeta *pMeta); -void metaCloseCache(SMeta *pMeta); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_CACHE_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaCfg.h b/source/dnode/vnode/src/inc/metaCfg.h deleted file mode 100644 index 5c72ffa680c10c14cf75b47f6576ecdc9c7e3c2e..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaCfg.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_META_CFG_H_ -#define _TD_META_CFG_H_ - -#include "meta.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const SMetaCfg defaultMetaOptions; - -int metaValidateOptions(const SMetaCfg *); -void metaOptionsCopy(SMetaCfg *pDest, const SMetaCfg *pSrc); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_CFG_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaDB.h b/source/dnode/vnode/src/inc/metaDB.h deleted file mode 100644 index b4b7e5d19e6df51b993487526b6733990a134b93..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaDB.h +++ /dev/null @@ -1,36 +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_META_DB_H_ -#define _TD_META_DB_H_ - -#include "meta.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SMetaDB SMetaDB; - -int metaOpenDB(SMeta *pMeta); -void metaCloseDB(SMeta *pMeta); -int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg); -int metaRemoveTableFromDb(SMeta *pMeta, tb_uid_t uid); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_DB_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaDef.h b/source/dnode/vnode/src/inc/metaDef.h index e1c15af5aaa167be39da8c009e29e539a9d49d10..b76c08b7b4a9a59081e3de6eac70b8e1aedafe15 100644 --- a/source/dnode/vnode/src/inc/metaDef.h +++ b/source/dnode/vnode/src/inc/metaDef.h @@ -19,18 +19,49 @@ #include "mallocator.h" #include "meta.h" -#include "metaCache.h" -#include "metaCfg.h" -#include "metaDB.h" -#include "metaIdx.h" -#include "metaTbCfg.h" -#include "metaTbTag.h" -#include "metaTbUid.h" #ifdef __cplusplus extern "C" { #endif +typedef struct SMetaCache SMetaCache; +typedef struct SMetaIdx SMetaIdx; +typedef struct SMetaDB SMetaDB; + +// SMetaDB +int metaOpenDB(SMeta* pMeta); +void metaCloseDB(SMeta* pMeta); +int metaSaveTableToDB(SMeta* pMeta, STbCfg* pTbCfg); +int metaRemoveTableFromDb(SMeta* pMeta, tb_uid_t uid); + +// SMetaCache +int metaOpenCache(SMeta* pMeta); +void metaCloseCache(SMeta* pMeta); + +// SMetaCfg +extern const SMetaCfg defaultMetaOptions; +// int metaValidateOptions(const SMetaCfg*); +void metaOptionsCopy(SMetaCfg* pDest, const SMetaCfg* pSrc); + +// SMetaIdx +int metaOpenIdx(SMeta* pMeta); +void metaCloseIdx(SMeta* pMeta); +int metaSaveTableToIdx(SMeta* pMeta, const STbCfg* pTbOptions); +int metaRemoveTableFromIdx(SMeta* pMeta, tb_uid_t uid); + +// STbUidGnrt +typedef struct STbUidGenerator { + tb_uid_t nextUid; +} STbUidGenerator; + +// STableUidGenerator +int metaOpenUidGnrt(SMeta* pMeta); +void metaCloseUidGnrt(SMeta* pMeta); + +// tb_uid_t +#define IVLD_TB_UID 0 +tb_uid_t metaGenerateUid(SMeta* pMeta); + struct SMeta { char* path; SMetaCfg options; diff --git a/source/dnode/vnode/src/inc/metaQuery.h b/source/dnode/vnode/src/inc/metaQuery.h deleted file mode 100644 index ca3b68b41536a38760ef933ee86dc91ce2c3a509..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaQuery.h +++ /dev/null @@ -1,27 +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 _VNODE_QUERY_H_ -#define _VNODE_QUERY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*_VNODE_QUERY_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaTbCfg.h b/source/dnode/vnode/src/inc/metaTbCfg.h deleted file mode 100644 index b7b3924d1487520ded604f2e709c530f448edcce..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaTbCfg.h +++ /dev/null @@ -1,32 +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_META_TABLE_CFG_H_ -#define _TD_META_TABLE_CFG_H_ - -#include "meta.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int metaValidateTbCfg(SMeta *pMeta, const STbCfg *); -size_t metaEncodeTbObjFromTbOptions(const STbCfg *, void *pBuf, size_t bsize); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_TABLE_CFG_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaTbTag.h b/source/dnode/vnode/src/inc/metaTbTag.h deleted file mode 100644 index 15b660be92a46ad8f1eb466adf1da055833b19f7..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaTbTag.h +++ /dev/null @@ -1,27 +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_META_TB_TAG_H_ -#define _TD_META_TB_TAG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_TB_TAG_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/metaTbUid.h b/source/dnode/vnode/src/inc/metaTbUid.h deleted file mode 100644 index 07d1f6635b16f591fe9f440be3fa51d0f34c7844..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/metaTbUid.h +++ /dev/null @@ -1,42 +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_META_UID_H_ -#define _TD_META_UID_H_ - -#include "meta.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------ APIS EXPOSED ------------------------ */ -typedef struct STbUidGenerator { - tb_uid_t nextUid; -} STbUidGenerator; - -// STableUidGenerator -int metaOpenUidGnrt(SMeta *pMeta); -void metaCloseUidGnrt(SMeta *pMeta); - -// tb_uid_t -#define IVLD_TB_UID 0 -tb_uid_t metaGenerateUid(SMeta *pMeta); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_META_UID_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/tsdbHealth.h b/source/dnode/vnode/src/inc/tsdbHealth.h deleted file mode 100644 index d7b70ac053749863241fdd946842c7face2ed961..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/tsdbHealth.h +++ /dev/null @@ -1,29 +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_TSDB_HEALTH_H_ -#define _TD_TSDB_HEALTH_H_ - -#if 0 - -bool tsdbUrgeQueryFree(STsdbRepo* pRepo); -int32_t tsdbInsertNewBlock(STsdbRepo* pRepo); - -bool tsdbIdleMemEnough(); -bool tsdbAllowNewBlock(STsdbRepo* pRepo); - -#endif - -#endif /* _TD_TSDB_BUFFER_H_ */ diff --git a/source/dnode/vnode/src/inc/tsdbRowMergeBuf.h b/source/dnode/vnode/src/inc/tsdbRowMergeBuf.h deleted file mode 100644 index 1531d532b9a2ba410747e833a8881289b5dd1370..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/tsdbRowMergeBuf.h +++ /dev/null @@ -1,49 +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 TSDB_ROW_MERGE_BUF_H -#define TSDB_ROW_MERGE_BUF_H - -#if 0 - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tsdb.h" -#include "tchecksum.h" -#include "tsdbReadImpl.h" - -typedef void* SMergeBuf; - -SDataRow tsdbMergeTwoRows(SMergeBuf *pBuf, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2); - -static FORCE_INLINE int tsdbMergeBufMakeSureRoom(SMergeBuf *pBuf, STSchema* pSchema1, STSchema* pSchema2) { - size_t len1 = dataRowMaxBytesFromSchema(pSchema1); - size_t len2 = dataRowMaxBytesFromSchema(pSchema2); - return tsdbMakeRoom(pBuf, MAX(len1, len2)); -} - -static FORCE_INLINE void tsdbFreeMergeBuf(SMergeBuf buf) { - taosTZfree(buf); -} - -#ifdef __cplusplus -} -#endif - -#endif - -#endif /* ifndef TSDB_ROW_MERGE_BUF_H */ diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h new file mode 100644 index 0000000000000000000000000000000000000000..7f43a93ab715e3303b4647d87886ad1ab0e23b38 --- /dev/null +++ b/source/dnode/vnode/src/inc/vnd.h @@ -0,0 +1,179 @@ +/* + * 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_DEF_H_ +#define _TD_VNODE_DEF_H_ + +#include "mallocator.h" +// #include "sync.h" +#include "tcoding.h" +#include "tfs.h" +#include "tlist.h" +#include "tlockfree.h" +#include "tmacro.h" +#include "wal.h" + +#include "vnode.h" + +#include "vnodeQuery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SVState SVState; +typedef struct SVBufPool SVBufPool; + +typedef struct SVnodeTask { + TD_DLIST_NODE(SVnodeTask); + void* arg; + int (*execute)(void*); +} SVnodeTask; + +typedef struct SVnodeMgr { + td_mode_flag_t vnodeInitFlag; + // For commit + bool stop; + uint16_t nthreads; + pthread_t* threads; + pthread_mutex_t mutex; + pthread_cond_t hasTask; + TD_DLIST(SVnodeTask) queue; + // For vnode Mgmt + SDnode* pDnode; + PutReqToVQueryQFp putReqToVQueryQFp; +} SVnodeMgr; + +extern SVnodeMgr vnodeMgr; + +// SVState +struct SVState { + int64_t processed; + int64_t committed; + int64_t applied; +}; + +struct SVnode { + int32_t vgId; + char* path; + SVnodeCfg config; + SVState state; + SVBufPool* pBufPool; + SMeta* pMeta; + STsdb* pTsdb; + STQ* pTq; + SWal* pWal; + tsem_t canCommit; + SQHandle* pQuery; + SDnode* pDnode; +}; + +int vnodeScheduleTask(SVnodeTask* task); + +int32_t vnodePutReqToVQueryQ(SVnode* pVnode, struct SRpcMsg* pReq); + +// For Log +extern int32_t vDebugFlag; + +#define vFatal(...) \ + do { \ + if (vDebugFlag & DEBUG_FATAL) { \ + taosPrintLog("VND FATAL ", 255, __VA_ARGS__); \ + } \ + } while (0) +#define vError(...) \ + do { \ + if (vDebugFlag & DEBUG_ERROR) { \ + taosPrintLog("VND ERROR ", 255, __VA_ARGS__); \ + } \ + } while (0) +#define vWarn(...) \ + do { \ + if (vDebugFlag & DEBUG_WARN) { \ + taosPrintLog("VND WARN ", 255, __VA_ARGS__); \ + } \ + } while (0) +#define vInfo(...) \ + do { \ + if (vDebugFlag & DEBUG_INFO) { \ + taosPrintLog("VND ", 255, __VA_ARGS__); \ + } \ + } while (0) +#define vDebug(...) \ + do { \ + if (vDebugFlag & DEBUG_DEBUG) { \ + taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); \ + } \ + } while (0) +#define vTrace(...) \ + do { \ + if (vDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("VND ", tsdbDebugFlag, __VA_ARGS__); \ + } \ + } while (0) + +// vnodeCfg.h +extern const SVnodeCfg defaultVnodeOptions; + +int vnodeValidateOptions(const SVnodeCfg*); +void vnodeOptionsCopy(SVnodeCfg* pDest, const SVnodeCfg* pSrc); + +// For commit +#define vnodeShouldCommit vnodeBufPoolIsFull +int vnodeSyncCommit(SVnode* pVnode); +int vnodeAsyncCommit(SVnode* pVnode); + +// SVBufPool + +int vnodeOpenBufPool(SVnode* pVnode); +void vnodeCloseBufPool(SVnode* pVnode); +int vnodeBufPoolSwitch(SVnode* pVnode); +int vnodeBufPoolRecycle(SVnode* pVnode); +void* vnodeMalloc(SVnode* pVnode, uint64_t size); +bool vnodeBufPoolIsFull(SVnode* pVnode); + +SMemAllocatorFactory* vBufPoolGetMAF(SVnode* pVnode); + +// SVMemAllocator +typedef struct SVArenaNode { + TD_SLIST_NODE(SVArenaNode); + uint64_t size; // current node size + void* ptr; + char data[]; +} SVArenaNode; + +typedef struct SVMemAllocator { + T_REF_DECLARE() + TD_DLIST_NODE(SVMemAllocator); + uint64_t capacity; + uint64_t ssize; + uint64_t lsize; + SVArenaNode* pNode; + TD_SLIST(SVArenaNode) nlist; +} SVMemAllocator; + +SVMemAllocator* vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize); +void vmaDestroy(SVMemAllocator* pVMA); +void vmaReset(SVMemAllocator* pVMA); +void* vmaMalloc(SVMemAllocator* pVMA, uint64_t size); +void vmaFree(SVMemAllocator* pVMA, void* ptr); +bool vmaIsFull(SVMemAllocator* pVMA); + + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_VNODE_DEF_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeBufferPool.h b/source/dnode/vnode/src/inc/vnodeBufferPool.h deleted file mode 100644 index b4535597ee29e47ec6ca0683bd2caf4e304f9c86..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeBufferPool.h +++ /dev/null @@ -1,41 +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_BUFFER_POOL_H_ -#define _TD_VNODE_BUFFER_POOL_H_ - -#include "tlist.h" -#include "vnode.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SVBufPool SVBufPool; - -int vnodeOpenBufPool(SVnode *pVnode); -void vnodeCloseBufPool(SVnode *pVnode); -int vnodeBufPoolSwitch(SVnode *pVnode); -int vnodeBufPoolRecycle(SVnode *pVnode); -void *vnodeMalloc(SVnode *pVnode, uint64_t size); -bool vnodeBufPoolIsFull(SVnode *pVnode); - -SMemAllocatorFactory *vBufPoolGetMAF(SVnode *pVnode); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_BUFFER_POOL_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeCfg.h b/source/dnode/vnode/src/inc/vnodeCfg.h deleted file mode 100644 index c4245b40239311bef771493435e553a072f31f4c..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeCfg.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_CFG_H_ -#define _TD_VNODE_CFG_H_ - -#include "vnode.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const SVnodeCfg defaultVnodeOptions; - -int vnodeValidateOptions(const SVnodeCfg *); -void vnodeOptionsCopy(SVnodeCfg *pDest, const SVnodeCfg *pSrc); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_CFG_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeCommit.h b/source/dnode/vnode/src/inc/vnodeCommit.h deleted file mode 100644 index e6568fbd52bf439cc5ed0c1eaf44a51b1b74166f..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeCommit.h +++ /dev/null @@ -1,33 +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_COMMIT_H_ -#define _TD_VNODE_COMMIT_H_ - -#include "vnode.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define vnodeShouldCommit vnodeBufPoolIsFull -int vnodeSyncCommit(SVnode *pVnode); -int vnodeAsyncCommit(SVnode *pVnode); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_COMMIT_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeDef.h b/source/dnode/vnode/src/inc/vnodeDef.h deleted file mode 100644 index 85563890fa9fc701f0ad5a5c09e73dd1a3312192..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeDef.h +++ /dev/null @@ -1,96 +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_DEF_H_ -#define _TD_VNODE_DEF_H_ - -#include "mallocator.h" -// #include "sync.h" -#include "tcoding.h" -#include "tlist.h" -#include "tlockfree.h" -#include "tmacro.h" -#include "wal.h" -#include "tfs.h" - -#include "vnode.h" - -#include "vnodeBufferPool.h" -#include "vnodeCfg.h" -#include "vnodeCommit.h" -#include "vnodeMemAllocator.h" -#include "vnodeQuery.h" -#include "vnodeStateMgr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SVnodeTask { - TD_DLIST_NODE(SVnodeTask); - void* arg; - int (*execute)(void*); -} SVnodeTask; - -typedef struct SVnodeMgr { - td_mode_flag_t vnodeInitFlag; - // For commit - bool stop; - uint16_t nthreads; - pthread_t* threads; - pthread_mutex_t mutex; - pthread_cond_t hasTask; - TD_DLIST(SVnodeTask) queue; - // For vnode Mgmt - SDnode* pDnode; - PutReqToVQueryQFp putReqToVQueryQFp; -} SVnodeMgr; - -extern SVnodeMgr vnodeMgr; - -struct SVnode { - int32_t vgId; - char* path; - SVnodeCfg config; - SVState state; - SVBufPool* pBufPool; - SMeta* pMeta; - STsdb* pTsdb; - STQ* pTq; - SWal* pWal; - tsem_t canCommit; - SQHandle* pQuery; - SDnode* pDnode; -}; - -int vnodeScheduleTask(SVnodeTask* task); - -int32_t vnodePutReqToVQueryQ(SVnode *pVnode, struct SRpcMsg *pReq); - -// For Log -extern int32_t vDebugFlag; - -#define vFatal(...) do { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("TDB FATAL ", 255, __VA_ARGS__); }} while(0) -#define vError(...) do { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("TDB ERROR ", 255, __VA_ARGS__); }} while(0) -#define vWarn(...) do { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("TDB WARN ", 255, __VA_ARGS__); }} while(0) -#define vInfo(...) do { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("TDB ", 255, __VA_ARGS__); }} while(0) -#define vDebug(...) do { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0) -#define vTrace(...) do { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("TDB ", tsdbDebugFlag, __VA_ARGS__); }} while(0) - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_DEF_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h deleted file mode 100644 index 028798bc3e15d343a777aaf6b6214de7dabeaa63..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ /dev/null @@ -1,45 +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_INT_H_ -#define _TD_VNODE_INT_H_ - -#include "vnode.h" - -#include "meta.h" -// #include "sync.h" -#include "tlog.h" -#include "tq.h" -#include "tsdb.h" -#include "wal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int32_t vDebugFlag; - -#define vFatal(...) { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("VND FATAL ", 255, __VA_ARGS__); }} -#define vError(...) { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("VND ERROR ", 255, __VA_ARGS__); }} -#define vWarn(...) { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("VND WARN ", 255, __VA_ARGS__); }} -#define vInfo(...) { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("VND ", 255, __VA_ARGS__); }} -#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }} -#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }} - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_INT_H_*/ diff --git a/source/dnode/vnode/src/inc/vnodeMemAllocator.h b/source/dnode/vnode/src/inc/vnodeMemAllocator.h deleted file mode 100644 index eb821a4b6cef8df3de8092bd0c94bf8d91c889e6..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeMemAllocator.h +++ /dev/null @@ -1,53 +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_MEM_ALLOCATOR_H_ -#define _TD_VNODE_MEM_ALLOCATOR_H_ - -#include "os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SVArenaNode { - TD_SLIST_NODE(SVArenaNode); - uint64_t size; // current node size - void * ptr; - char data[]; -} SVArenaNode; - -typedef struct SVMemAllocator { - T_REF_DECLARE() - TD_DLIST_NODE(SVMemAllocator); - uint64_t capacity; - uint64_t ssize; - uint64_t lsize; - SVArenaNode *pNode; - TD_SLIST(SVArenaNode) nlist; -} SVMemAllocator; - -SVMemAllocator *vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize); -void vmaDestroy(SVMemAllocator *pVMA); -void vmaReset(SVMemAllocator *pVMA); -void * vmaMalloc(SVMemAllocator *pVMA, uint64_t size); -void vmaFree(SVMemAllocator *pVMA, void *ptr); -bool vmaIsFull(SVMemAllocator *pVMA); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_MEM_ALLOCATOR_H_*/ diff --git a/source/dnode/vnode/src/inc/vnodeWrite.h b/source/dnode/vnode/src/inc/vnodeWrite.h deleted file mode 100644 index 57f19b11c4adcf471337fe739162d493389d95b3..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/inc/vnodeWrite.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_WRITE_H_ -#define _TD_VNODE_WRITE_H_ - -#include "vnode.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vnodeProcessWriteMsg(SVnode* pVnode, SVnodeMsg* pMsg); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_VNODE_WRITE_H_*/ diff --git a/source/dnode/vnode/src/meta/metaMain.c b/source/dnode/vnode/src/meta/metaMain.c index b6aa029b1919a6c5635b678657042d009e31472e..ad87b2de9ec0861293290a410b004395a882a6e3 100644 --- a/source/dnode/vnode/src/meta/metaMain.c +++ b/source/dnode/vnode/src/meta/metaMain.c @@ -30,11 +30,11 @@ SMeta *metaOpen(const char *path, const SMetaCfg *pMetaCfg, SMemAllocatorFactory pMetaCfg = &defaultMetaOptions; } - // Validate the options - if (metaValidateOptions(pMetaCfg) < 0) { - // TODO: deal with error - return NULL; - } + // // Validate the options + // if (metaValidateOptions(pMetaCfg) < 0) { + // // TODO: deal with error + // return NULL; + // } // Allocate handle pMeta = metaNew(path, pMetaCfg, pMAF); diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 1398639f39dccb660de7d39480fa1524f694a248..4725f77fa25b33368f2d993165e08489cf8070e5 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -17,10 +17,10 @@ int metaCreateTable(SMeta *pMeta, STbCfg *pTbCfg) { // Validate the tbOptions - if (metaValidateTbCfg(pMeta, pTbCfg) < 0) { - // TODO: handle error - return -1; - } + // if (metaValidateTbCfg(pMeta, pTbCfg) < 0) { + // // TODO: handle error + // return -1; + // } // TODO: add atomicity diff --git a/source/dnode/vnode/src/tsdb/tsdbHealth.c b/source/dnode/vnode/src/tsdb/tsdbHealth.c deleted file mode 100644 index 99c1b925b004cf2608abd52b5e6ecc2961f2bbe6..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/tsdb/tsdbHealth.c +++ /dev/null @@ -1,98 +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 . - */ - -// #include "os.h" -// #include "tmsg.h" -// #include "tarray.h" -// #include "query.h" -// #include "tglobal.h" -// #include "tlist.h" -// #include "tsdbint.h" -// #include "tsdbBuffer.h" -// #include "tsdbLog.h" -// #include "tsdbHealth.h" -// #include "ttimer.h" -// #include "tthread.h" - - -// // return malloc new block count -// int32_t tsdbInsertNewBlock(STsdbRepo * pRepo) { -// STsdbBufPool *pPool = pRepo->pPool; -// int32_t cnt = 0; - -// if(tsdbAllowNewBlock(pRepo)) { -// STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); -// if (pBufBlock) { -// if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) { -// // append error -// tsdbFreeBufBlock(pBufBlock); -// } else { -// pPool->nElasticBlocks ++; -// cnt ++ ; -// } -// } -// } -// return cnt; -// } - -// // switch anther thread to run -// void* cbKillQueryFree(void* param) { -// STsdbRepo* pRepo = (STsdbRepo*)param; -// // vnode -// if(pRepo->appH.notifyStatus) { -// pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_NOBLOCK, TSDB_CODE_SUCCESS); -// } - -// // free -// if(pRepo->pthread){ -// void* p = pRepo->pthread; -// pRepo->pthread = NULL; -// free(p); -// } - -// return NULL; -// } - -// // return true do free , false do nothing -// bool tsdbUrgeQueryFree(STsdbRepo * pRepo) { -// // check previous running -// if(pRepo->pthread && taosThreadRunning(pRepo->pthread)) { -// tsdbWarn("vgId:%d pre urge thread is runing. nBlocks=%d nElasticBlocks=%d", REPO_ID(pRepo), pRepo->pPool->nBufBlocks, pRepo->pPool->nElasticBlocks); -// return false; -// } -// // create new -// pRepo->pthread = taosCreateThread(cbKillQueryFree, pRepo); -// if(pRepo->pthread == NULL) { -// tsdbError("vgId:%d create urge thread error.", REPO_ID(pRepo)); -// return false; -// } -// return true; -// } - -// bool tsdbAllowNewBlock(STsdbRepo* pRepo) { -// int32_t nMaxElastic = pRepo->config.totalBlocks/3; -// STsdbBufPool* pPool = pRepo->pPool; -// if(pPool->nElasticBlocks >= nMaxElastic) { -// tsdbWarn("vgId:%d tsdbAllowNewBlock return fasle. nElasticBlock(%d) >= MaxElasticBlocks(%d)", REPO_ID(pRepo), pPool->nElasticBlocks, nMaxElastic); -// return false; -// } -// return true; -// } - -// bool tsdbNoProblem(STsdbRepo* pRepo) { -// if(listNEles(pRepo->pPool->bufBlockList) == 0) -// return false; -// return true; -// } \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index a8296e8f8e5867f8c507e9ab1dbd8bcc3f3c1a88..86ba2d99a30799ae7d8907c928f12d2cd5e77423 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -713,13 +713,6 @@ static bool initTableMemIterator(STsdbReadHandle* pHandle, STableCheckInfo* pChe pCheckInfo->initBuf = true; int32_t order = pHandle->order; - // no data in buffer, abort -// if (pHandle->pMemTable->snapshot.mem == NULL && pHandle->pMemTable->snapshot.imem == NULL) { -// return false; -// } -// -// assert(pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL); -// STbData** pMem = NULL; STbData** pIMem = NULL; @@ -787,8 +780,7 @@ static bool initTableMemIterator(STsdbReadHandle* pHandle, STableCheckInfo* pChe assert(pCheckInfo->lastKey >= key); } } else { - tsdbDebug("%p uid:%"PRId64", no data in imem, 0x%"PRIx64, pHandle, pCheckInfo->tableId, - pHandle->qId); + tsdbDebug("%p uid:%"PRId64", no data in imem, 0x%"PRIx64, pHandle, pCheckInfo->tableId, pHandle->qId); } return true; @@ -2554,9 +2546,6 @@ static bool doHasDataInBuffer(STsdbReadHandle* pTsdbReadHandle) { pTsdbReadHandle->activeIndex += 1; } - // no data in memtable or imemtable, decrease the memory reference. - // TODO !! -// tsdbMayUnTakeMemSnapshot(pTsdbReadHandle); return false; } diff --git a/source/dnode/vnode/src/tsdb/tsdbRowMergeBuf.c b/source/dnode/vnode/src/tsdb/tsdbRowMergeBuf.c deleted file mode 100644 index 1eebea22d430ef913e33c4e2366072dd8e4261d4..0000000000000000000000000000000000000000 --- a/source/dnode/vnode/src/tsdb/tsdbRowMergeBuf.c +++ /dev/null @@ -1,30 +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 . - */ - -// #include "tsdbRowMergeBuf.h" -// #include "tdataformat.h" - -// // row1 has higher priority -// SMemRow tsdbMergeTwoRows(SMergeBuf *pBuf, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2) { -// if(row2 == NULL) return row1; -// if(row1 == NULL) return row2; -// ASSERT(pSchema1->version == memRowVersion(row1)); -// ASSERT(pSchema2->version == memRowVersion(row2)); - -// if(tsdbMergeBufMakeSureRoom(pBuf, pSchema1, pSchema2) < 0) { -// return NULL; -// } -// return mergeTwoMemRows(*pBuf, row1, row2, pSchema1, pSchema2); -// } diff --git a/source/dnode/vnode/src/tsdb/tsdbWrite.c b/source/dnode/vnode/src/tsdb/tsdbWrite.c index 570e821af0e43d7b26e33b1e91c5ddd7a405d0cc..5f937f17e969d919f75c231db4e646456be488ef 100644 --- a/source/dnode/vnode/src/tsdb/tsdbWrite.c +++ b/source/dnode/vnode/src/tsdb/tsdbWrite.c @@ -17,9 +17,11 @@ int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg, SSubmitRsp *pRsp) { // Check if mem is there. If not, create one. - pTsdb->mem = tsdbNewMemTable(pTsdb); if (pTsdb->mem == NULL) { - return -1; + pTsdb->mem = tsdbNewMemTable(pTsdb); + if (pTsdb->mem == NULL) { + return -1; + } } return tsdbMemTableInsert(pTsdb, pTsdb->mem, pMsg, NULL); } \ No newline at end of file diff --git a/source/dnode/vnode/src/vnd/vnodeArenaMAImpl.c b/source/dnode/vnode/src/vnd/vnodeArenaMAImpl.c index 5999b08a7d83f5460eabe80038ba18fca9b5b99b..f49babb1a52dd9d4b55be03e874912d59a1b177e 100644 --- a/source/dnode/vnode/src/vnd/vnodeArenaMAImpl.c +++ b/source/dnode/vnode/src/vnd/vnodeArenaMAImpl.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" static SVArenaNode *vArenaNodeNew(uint64_t capacity); static void vArenaNodeFree(SVArenaNode *pNode); diff --git a/source/dnode/vnode/src/vnd/vnodeBufferPool.c b/source/dnode/vnode/src/vnd/vnodeBufferPool.c index c2040501e8f76fe9fc558bea2dd09884d66cbaa2..8df6b4256652c0b9c471b43ef299f4cca7279a8a 100644 --- a/source/dnode/vnode/src/vnd/vnodeBufferPool.c +++ b/source/dnode/vnode/src/vnd/vnodeBufferPool.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" /* ------------------------ STRUCTURES ------------------------ */ #define VNODE_BUF_POOL_SHARDS 3 diff --git a/source/dnode/vnode/src/vnd/vnodeCfg.c b/source/dnode/vnode/src/vnd/vnodeCfg.c index 97c3cc9ceee4f2f8a82bf85a2a8293237563228a..727a4b41f7b687680d9c39e965f08553937bc0b1 100644 --- a/source/dnode/vnode/src/vnd/vnodeCfg.c +++ b/source/dnode/vnode/src/vnd/vnodeCfg.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" const SVnodeCfg defaultVnodeOptions = { .wsize = 96 * 1024 * 1024, .ssize = 1 * 1024 * 1024, .lsize = 1024, .walCfg = {.level = TAOS_WAL_WRITE}}; /* TODO */ diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c index fbea827ec767a0ab17a9905c9fa3e570a29cf555..bc7a8460b8b842a0d8d008c650d7d78db438d1c0 100644 --- a/source/dnode/vnode/src/vnd/vnodeCommit.c +++ b/source/dnode/vnode/src/vnd/vnodeCommit.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" static int vnodeStartCommit(SVnode *pVnode); static int vnodeEndCommit(SVnode *pVnode); diff --git a/source/dnode/vnode/src/vnd/vnodeInt.c b/source/dnode/vnode/src/vnd/vnodeInt.c index 0f33fa65cd888eae518bc1079b1d35c9feb0e6e8..3d23784e133f88138ec04ee5340323f8dde7d180 100644 --- a/source/dnode/vnode/src/vnd/vnodeInt.c +++ b/source/dnode/vnode/src/vnd/vnodeInt.c @@ -14,7 +14,8 @@ */ #define _DEFAULT_SOURCE -#include "vnodeInt.h" +#include "vnd.h" +// #include "vnodeInt.h" int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; } diff --git a/source/dnode/vnode/src/vnd/vnodeMain.c b/source/dnode/vnode/src/vnd/vnodeMain.c index 85ccc9879ec4471c85e9df06fd69db4055c7580c..ae17c9887d8c349dda1dced9d4584bf1388817c9 100644 --- a/source/dnode/vnode/src/vnd/vnodeMain.c +++ b/source/dnode/vnode/src/vnd/vnodeMain.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg); static void vnodeFree(SVnode *pVnode); diff --git a/source/dnode/vnode/src/vnd/vnodeMgr.c b/source/dnode/vnode/src/vnd/vnodeMgr.c index ce9e487076ecd53cff587e0aab37c09fa458f32f..730155b75a3eeb9d37341b5fca25b8b6b2008ae7 100644 --- a/source/dnode/vnode/src/vnd/vnodeMgr.c +++ b/source/dnode/vnode/src/vnd/vnodeMgr.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED}; diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 2c959e663f399858ec20509b94cfc62db7cf9f61..2e9c77c59be6cb36aa29dc998dc5fed4e0be8e40 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -14,7 +14,7 @@ */ #include "vnodeQuery.h" -#include "vnodeDef.h" +#include "vnd.h" static int32_t vnodeGetTableList(SVnode *pVnode, SRpcMsg *pMsg); static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); @@ -79,6 +79,7 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { pTbCfg = metaGetTbInfoByName(pVnode->pMeta, pReq->tableFname, &uid); if (pTbCfg == NULL) { + code = TSDB_CODE_VND_TB_NOT_EXIST; goto _exit; } diff --git a/source/dnode/vnode/src/vnd/vnodeWrite.c b/source/dnode/vnode/src/vnd/vnodeWrite.c index 01619b5c77bd89425ebb2f61f053c9d881cdddb5..bb863d6ed02ae2416c05539dc3f576d2386af702 100644 --- a/source/dnode/vnode/src/vnd/vnodeWrite.c +++ b/source/dnode/vnode/src/vnd/vnodeWrite.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "vnodeDef.h" +#include "vnd.h" int vnodeProcessNoWalWMsgs(SVnode *pVnode, SRpcMsg *pMsg) { switch (pMsg->msgType) { @@ -84,6 +84,7 @@ int vnodeApplyWMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { // TODO: handle error } vTrace("vgId:%d process create table %s", pVnode->vgId, pCreateTbReq->name); + free(pCreateTbReq->name); if (pCreateTbReq->type == TD_SUPER_TABLE) { free(pCreateTbReq->stbCfg.pSchema); free(pCreateTbReq->stbCfg.pTagSchema); @@ -116,7 +117,7 @@ int vnodeApplyWMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { // Check if it needs to commit if (vnodeShouldCommit(pVnode)) { - tsem_wait(&(pVnode->canCommit)); + // tsem_wait(&(pVnode->canCommit)); if (vnodeAsyncCommit(pVnode) < 0) { // TODO: handle error } diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index 94f34b8e1726dcd234c6e08eb426536f1f669edf..f6b752bc6cbbd89bb3a897c41ac8e9f981aa2ed5 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -285,16 +285,16 @@ int32_t ctgGetTableMetaFromVnode(struct SCatalog* pCatalog, void *pTransporter, char dbFullName[TSDB_DB_FNAME_LEN]; tNameGetFullDbName(pTableName, dbFullName); - ctgDebug("try to get table meta from vnode, db:%s, tbName:%s", dbFullName, pTableName->tname); + ctgDebug("try to get table meta from vnode, db:%s, tbName:%s", dbFullName, tNameGetTableName(pTableName)); - SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbName = dbFullName, .tableFullName = (char *)pTableName->tname}; + SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbName = dbFullName, .tableFullName = (char *)tNameGetTableName(pTableName)}; char *msg = NULL; SEpSet *pVnodeEpSet = NULL; int32_t msgLen = 0; int32_t code = queryBuildMsg[TMSG_INDEX(TDMT_VND_TABLE_META)](&bInput, &msg, 0, &msgLen); if (code) { - ctgError("Build vnode tablemeta msg failed, code:%x, tbName:%s", code, pTableName->tname); + ctgError("Build vnode tablemeta msg failed, code:%x, tbName:%s", code, tNameGetTableName(pTableName)); CTG_ERR_RET(code); } @@ -313,21 +313,21 @@ int32_t ctgGetTableMetaFromVnode(struct SCatalog* pCatalog, void *pTransporter, if (TSDB_CODE_SUCCESS != rpcRsp.code) { if (CTG_TABLE_NOT_EXIST(rpcRsp.code)) { SET_META_TYPE_NONE(output->metaType); - ctgDebug("tablemeta not exist in vnode, tbName:%s", pTableName->tname); + ctgDebug("tablemeta not exist in vnode, tbName:%s", tNameGetTableName(pTableName)); return TSDB_CODE_SUCCESS; } - ctgError("error rsp for table meta from vnode, code:%x, tbName:%s", rpcRsp.code, pTableName->tname); + ctgError("error rsp for table meta from vnode, code:%x, tbName:%s", rpcRsp.code, tNameGetTableName(pTableName)); CTG_ERR_RET(rpcRsp.code); } code = queryProcessMsgRsp[TMSG_INDEX(TDMT_VND_TABLE_META)](output, rpcRsp.pCont, rpcRsp.contLen); if (code) { - ctgError("Process vnode tablemeta rsp failed, code:%x, tbName:%s", code, pTableName->tname); + ctgError("Process vnode tablemeta rsp failed, code:%x, tbName:%s", code, tNameGetTableName(pTableName)); CTG_ERR_RET(code); } - ctgDebug("Got table meta from vnode, db:%s, tbName:%s", dbFullName, pTableName->tname); + ctgDebug("Got table meta from vnode, db:%s, tbName:%s", dbFullName, tNameGetTableName(pTableName)); return TSDB_CODE_SUCCESS; } @@ -776,7 +776,7 @@ int32_t ctgRenewTableMetaImpl(struct SCatalog* pCatalog, void *pTransporter, con STableMetaOutput *output = &voutput; if (CTG_IS_STABLE(isSTable)) { - ctgDebug("will renew table meta, supposed to be stable, tbName:%s", pTableName->tname); + ctgDebug("will renew table meta, supposed to be stable, tbName:%s", tNameGetTableName(pTableName)); // if get from mnode failed, will not try vnode CTG_ERR_JRET(ctgGetTableMetaFromMnode(pCatalog, pTransporter, pMgmtEps, pTableName, &moutput)); @@ -787,13 +787,13 @@ int32_t ctgRenewTableMetaImpl(struct SCatalog* pCatalog, void *pTransporter, con output = &moutput; } } else { - ctgDebug("will renew table meta, not supposed to be stable, tbName:%s, isStable:%d", pTableName->tname, isSTable); + ctgDebug("will renew table meta, not supposed to be stable, tbName:%s, isStable:%d", tNameGetTableName(pTableName), isSTable); // if get from vnode failed or no table meta, will not try mnode CTG_ERR_JRET(ctgGetTableMetaFromVnode(pCatalog, pTransporter, pMgmtEps, pTableName, &vgroupInfo, &voutput)); if (CTG_IS_META_TABLE(voutput.metaType) && TSDB_SUPER_TABLE == voutput.tbMeta->tableType) { - ctgDebug("will continue to renew table meta since got stable, tbName:%s, metaType:%d", pTableName->tname, voutput.metaType); + ctgDebug("will continue to renew table meta since got stable, tbName:%s, metaType:%d", tNameGetTableName(pTableName), voutput.metaType); CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCatalog, pTransporter, pMgmtEps, voutput.tbFname, &moutput)); @@ -820,7 +820,7 @@ int32_t ctgRenewTableMetaImpl(struct SCatalog* pCatalog, void *pTransporter, con } if (CTG_IS_META_NONE(output->metaType)) { - ctgError("no tablemeta got, tbNmae:%s", pTableName->tname); + ctgError("no tablemeta got, tbNmae:%s", tNameGetTableName(pTableName)); CTG_ERR_JRET(CTG_ERR_CODE_TABLE_NOT_EXIST); } @@ -860,7 +860,7 @@ int32_t ctgGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMg CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pTableName, pTableMeta, &exist)); if (0 == exist) { - ctgError("renew tablemeta succeed but get from cache failed, may be deleted, tbName:%s", pTableName->tname); + ctgError("renew tablemeta succeed but get from cache failed, may be deleted, tbName:%s", tNameGetTableName(pTableName)); CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); } @@ -1241,7 +1241,7 @@ int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pRpc, const S } else { int32_t vgId = tbMeta->vgId; if (NULL == taosHashGetClone(dbVgroup->vgInfo, &vgId, sizeof(vgId), &vgroupInfo)) { - ctgError("table's vgId not found in vgroup list, vgId:%d, tbName:%s", vgId, pTableName->tname); + ctgError("table's vgId not found in vgroup list, vgId:%d, tbName:%s", vgId, tNameGetTableName(pTableName)); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); } @@ -1252,7 +1252,7 @@ int32_t catalogGetTableDistVgroup(struct SCatalog* pCatalog, void *pRpc, const S } if (NULL == taosArrayPush(vgList, &vgroupInfo)) { - ctgError("taosArrayPush vgroupInfo to array failed, vgId:%d, tbName:%s", vgId, pTableName->tname); + ctgError("taosArrayPush vgroupInfo to array failed, vgId:%d, tbName:%s", vgId, tNameGetTableName(pTableName)); CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); } diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index d76f2703924ff51ff4cb2d16986c33dbda29a871..34d89a75b312de5b894636b44519a09fba94bd16 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -374,6 +374,12 @@ typedef struct STaskParam { struct SUdfInfo *pUdfInfo; } STaskParam; +typedef struct SExchangeInfo { + int32_t numOfSources; + SEpSet *pEpset; + int32_t bytes; // total load bytes from remote +} SExchangeInfo; + typedef struct STableScanInfo { void *pTsdbReadHandle; int32_t numOfBlocks; @@ -393,12 +399,9 @@ typedef struct STableScanInfo { SSDataBlock block; int32_t numOfOutput; int64_t elapsedTime; - int32_t tableIndex; - int32_t prevGroupId; // previous table group id int32_t scanFlag; // table scan flag to denote if it is a repeat/reverse/main scan - STimeWindow window; } STableScanInfo; typedef struct STagScanInfo { @@ -542,34 +545,36 @@ typedef struct SOrderOperatorInfo { void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream); -SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); -SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv); - -SOperatorInfo* createAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult); -SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createExchangeOperatorInfo(const SVgroupInfo* pVgroups, int32_t numOfSources, int32_t numOfOutput, SExecTaskInfo* pTaskInfo); + +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, int32_t reverseTime, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createTableSeqScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); + +SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream); +SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult); +SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv); +SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); SOperatorInfo* createMultiwaySortOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows, void* merger); -SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp); -SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult); -SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, +SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp); +SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult); +SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter); -SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput); -SOperatorInfo* createOrderOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal); +SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pdownstream, int32_t numOfDownstream, SSchema* pSchema, int32_t numOfOutput); +SOperatorInfo* createOrderOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal); //SSDataBlock* doGlobalAggregate(void* param, bool* newgroup); //SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 0dfcc9b1d81d226a2d563fbf88087580a1b0a641..93f792e6e3593853c842bb8f28f8ee786e9c9719 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -294,7 +294,6 @@ SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numO SSDataBlock *res = calloc(1, sizeof(SSDataBlock)); res->info.numOfCols = numOfOutput; - res->pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData)); for (int32_t i = 0; i < numOfOutput; ++i) { SColumnInfoData idata = {{0}}; @@ -1815,7 +1814,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { return TSDB_CODE_SUCCESS; } -static SQLFunctionCtx* createSQLFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, +static SQLFunctionCtx* createSqlFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t** rowCellInfoOffset) { STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; @@ -1919,6 +1918,104 @@ static SQLFunctionCtx* createSQLFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprI return pFuncCtx; } +static SQLFunctionCtx* createSqlFunctionCtx_rv(SExprInfo* pExpr, int32_t numOfOutput, int32_t** rowCellInfoOffset) { + SQLFunctionCtx * pFuncCtx = (SQLFunctionCtx *)calloc(numOfOutput, sizeof(SQLFunctionCtx)); + if (pFuncCtx == NULL) { + return NULL; + } + + *rowCellInfoOffset = calloc(numOfOutput, sizeof(int32_t)); + if (*rowCellInfoOffset == 0) { + tfree(pFuncCtx); + return NULL; + } + + for (int32_t i = 0; i < numOfOutput; ++i) { + SSqlExpr *pSqlExpr = &pExpr[i].base; + SQLFunctionCtx* pCtx = &pFuncCtx[i]; +#if 0 + SColIndex *pIndex = &pSqlExpr->colInfo; + + if (TSDB_COL_REQ_NULL(pIndex->flag)) { + pCtx->requireNull = true; + pIndex->flag &= ~(TSDB_COL_NULL); + } else { + pCtx->requireNull = false; + } +#endif +// pCtx->inputBytes = pSqlExpr->colBytes; +// pCtx->inputType = pSqlExpr->colType; + + pCtx->ptsOutputBuf = NULL; + + pCtx->resDataInfo.bytes = pSqlExpr->resSchema.bytes; + pCtx->resDataInfo.type = pSqlExpr->resSchema.type; + +// pCtx->order = pQueryAttr->order.order; +// pCtx->functionId = pSqlExpr->functionId; +// pCtx->stableQuery = pQueryAttr->stableQuery; + pCtx->resDataInfo.intermediateBytes = pSqlExpr->interBytes; + pCtx->start.key = INT64_MIN; + pCtx->end.key = INT64_MIN; + + pCtx->numOfParams = pSqlExpr->numOfParams; + for (int32_t j = 0; j < pCtx->numOfParams; ++j) { + int16_t type = pSqlExpr->param[j].nType; + int16_t bytes = pSqlExpr->param[j].nLen; + + if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { + taosVariantCreateFromBinary(&pCtx->param[j], pSqlExpr->param[j].pz, bytes, type); + } else { + taosVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlExpr->param[j].i, bytes, type); + } + } + + // set the order information for top/bottom query + int32_t functionId = pCtx->functionId; + + if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM || functionId == FUNCTION_DIFF) { + int32_t f = getExprFunctionId(&pExpr[0]); + assert(f == FUNCTION_TS || f == FUNCTION_TS_DUMMY); + +// pCtx->param[2].i = pQueryAttr->order.order; + pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; + pCtx->param[3].i = functionId; + pCtx->param[3].nType = TSDB_DATA_TYPE_BIGINT; + +// pCtx->param[1].i = pQueryAttr->order.col.info.colId; + } else if (functionId == FUNCTION_INTERP) { +// pCtx->param[2].i = (int8_t)pQueryAttr->fillType; +// if (pQueryAttr->fillVal != NULL) { +// if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) { +// pCtx->param[1].nType = TSDB_DATA_TYPE_NULL; +// } else { // todo refactor, taosVariantCreateFromBinary should handle the NULL value +// if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) { +// taosVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i], pCtx->inputBytes, pCtx->inputType); +// } +// } +// } + } else if (functionId == FUNCTION_TS_COMP) { +// pCtx->param[0].i = pQueryAttr->vgId; //TODO this should be the parameter from client + pCtx->param[0].nType = TSDB_DATA_TYPE_BIGINT; + } else if (functionId == FUNCTION_TWA) { +// pCtx->param[1].i = pQueryAttr->window.skey; + pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT; +// pCtx->param[2].i = pQueryAttr->window.ekey; + pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; + } else if (functionId == FUNCTION_ARITHM) { +// pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i); + } + } + +// for(int32_t i = 1; i < numOfOutput; ++i) { +// (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pExpr[i - 1].base.interBytes); +// } + + setCtxTagColumnInfo(pFuncCtx, numOfOutput); + + return pFuncCtx; +} + static void* destroySQLFunctionCtx(SQLFunctionCtx* pCtx, int32_t numOfOutput) { if (pCtx == NULL) { return NULL; @@ -3467,8 +3564,6 @@ static void setupEnvForReverseScan(STableScanInfo *pTableScanInfo, SQLFunctionCt // } // reverse order time range - SWAP(pTableScanInfo->window.skey, pTableScanInfo->window.ekey, TSKEY); - SET_REVERSE_SCAN_FLAG(pTableScanInfo); // setTaskStatus(pTableScanInfo, QUERY_NOT_COMPLETED); @@ -4452,7 +4547,7 @@ void queryCostStatis(SQInfo *pQInfo) { // return true; //} -void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream) { +void appendDownstream(SOperatorInfo* p, SOperatorInfo* pUpstream) { if (p->pDownstream == NULL) { assert(p->numOfDownstream == 0); } @@ -4545,28 +4640,6 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr pRuntimeEnv->cur.vgroupIndex = -1; setResultBufSize(pQueryAttr, &pRuntimeEnv->resultInfo); - switch(tbScanner) { -// case OP_TableBlockInfoScan: { -// pRuntimeEnv->proot = createTableBlockInfoScanOperator(pRuntimeEnv->pTsdbReadHandle, pRuntimeEnv); -// break; -// } -// case OP_TableSeqScan: { -// pRuntimeEnv->proot = createTableSeqScanOperator(pRuntimeEnv->pTsdbReadHandle, pRuntimeEnv); -// break; -// } -// case OP_DataBlocksOptScan: { -// pRuntimeEnv->proot = createDataBlocksOptScanInfo(pRuntimeEnv->pTsdbReadHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr), pQueryAttr->needReverseScan? 1:0); -// break; -// } -// case OP_TableScan: { -// pRuntimeEnv->proot = createTableScanOperator(pRuntimeEnv->pTsdbReadHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr)); -// break; -// } - default: { // do nothing - break; - } - } - if (sourceOptr != NULL) { assert(pRuntimeEnv->proot == NULL); pRuntimeEnv->proot = sourceOptr; @@ -4838,21 +4911,104 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { pOperator->status = OP_EXEC_DONE; return pBlock; #endif +} + +int32_t loadRemoteDataCallback(void* param, const SDataBuf* pMsg, int32_t code) { + +} + +static SSDataBlock* doLoadRemoteData(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + + SExchangeInfo *pExchangeInfo = pOperator->info; + SExecTaskInfo *pTaskInfo = pOperator->pTaskInfo; + + *newgroup = false; + + SResFetchReq *pMsg = calloc(1, sizeof(SResFetchReq)); + if (NULL == pMsg) { // todo handle malloc error + } + + SEpSet epSet; + + int64_t sId = -1, queryId = 0, taskId = 1, vgId = 1; + pMsg->header.vgId = htonl(vgId); + + pMsg->sId = htobe64(sId); + pMsg->taskId = htobe64(taskId); + pMsg->queryId = htobe64(queryId); + + // send the fetch remote task result reques + SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo)); + if (NULL == pMsgSendInfo) { + qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", queryId, taskId, (int32_t)sizeof(SMsgSendInfo)); + } + + pMsgSendInfo->param = NULL; + pMsgSendInfo->msgInfo.pData = pMsg; + pMsgSendInfo->msgInfo.len = sizeof(SResFetchReq); + pMsgSendInfo->msgType = TDMT_VND_FETCH; + pMsgSendInfo->fp = loadRemoteDataCallback; + + int64_t transporterId = 0; + void* pTransporter = NULL; + int32_t code = asyncSendMsgToServer(pTransporter, &epSet, &transporterId, pMsgSendInfo); + + printf("abc\n"); + getchar(); + + // add it into the sink node } -SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createExchangeOperatorInfo(const SVgroupInfo* pVgroups, int32_t numOfSources, int32_t numOfOutput, SExecTaskInfo* pTaskInfo) { + assert(numOfSources > 0); + + SExchangeInfo* pInfo = calloc(1, sizeof(SExchangeInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + + if (pInfo == NULL || pOperator == NULL) { + tfree(pInfo); + tfree(pOperator); + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return NULL; + } + + pInfo->numOfSources = numOfSources; + + pOperator->name = "ExchangeOperator"; + pOperator->operatorType = OP_Exchange; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = NULL; + pOperator->exec = doLoadRemoteData; + pOperator->pTaskInfo = pTaskInfo; + + return pOperator; +} + +SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, SExecTaskInfo* pTaskInfo) { assert(repeatTime > 0 && numOfOutput > 0); - STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pTsdbReadHandle = pTsdbQueryHandle; + STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + + if (pInfo == NULL || pOperator == NULL) { + tfree(pInfo); + tfree(pOperator); + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return NULL; + } + + pInfo->pTsdbReadHandle = pTsdbReadHandle; pInfo->times = repeatTime; pInfo->reverseTimes = 0; pInfo->order = order; pInfo->current = 0; pInfo->scanFlag = MAIN_SCAN; - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableScanOperator"; pOperator->operatorType = OP_TableScan; pOperator->blockingOptr = false; @@ -4866,10 +5022,43 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, in return pOperator; } -SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv) { +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput, int32_t repeatTime, int32_t reverseTime, SExecTaskInfo* pTaskInfo) { + assert(repeatTime > 0); + + STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + tfree(pInfo); + tfree(pOperator); + + terrno = TSDB_CODE_QRY_OUT_OF_MEMORY; + return NULL; + } + + pInfo->pTsdbReadHandle = pTsdbReadHandle; + pInfo->times = repeatTime; + pInfo->reverseTimes = reverseTime; + pInfo->order = order; + pInfo->current = 0; + pInfo->scanFlag = MAIN_SCAN; + + pOperator->name = "DataBlocksOptimizedScanOperator"; + pOperator->operatorType = OP_DataBlocksOptScan; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = NULL; + pOperator->exec = doTableScan; + pOperator->pTaskInfo = pTaskInfo; + + return pOperator; +} + +SOperatorInfo* createTableSeqScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv) { STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pTsdbReadHandle = pTsdbQueryHandle; + pInfo->pTsdbReadHandle = pTsdbReadHandle; pInfo->times = 1; pInfo->reverseTimes = 0; pInfo->order = pRuntimeEnv->pQueryAttr->order.order; @@ -4879,7 +5068,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEn SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableSeqScanOperator"; -// pOperator->operatorType = OP_TableSeqScan; + pOperator->operatorType = OP_TableSeqScan; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; @@ -4890,10 +5079,10 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEn return pOperator; } -SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv) { +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv) { STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pTsdbReadHandle = pTsdbQueryHandle; + pInfo->pTsdbReadHandle = pTsdbReadHandle; pInfo->block.pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData)); SColumnInfoData infoData = {{0}}; @@ -4973,27 +5162,6 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf } -SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, STaskRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { - assert(repeatTime > 0); - - STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pTsdbReadHandle = pTsdbQueryHandle; - pInfo->times = repeatTime; - pInfo->reverseTimes = reverseTime; - pInfo->current = 0; - pInfo->order = pRuntimeEnv->pQueryAttr->order.order; - - SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); - pOptr->name = "DataBlocksOptimizedScanOperator"; -// pOptr->operatorType = OP_DataBlocksOptScan; - pOptr->pRuntimeEnv = pRuntimeEnv; - pOptr->blockingOptr = false; - pOptr->info = pInfo; - pOptr->exec = doTableScan; - - return pOptr; -} - SArray* getOrderCheckColumns(STaskAttr* pQuery) { int32_t numOfCols = (pQuery->pGroupbyExpr == NULL)? 0: taosArrayGetSize(pQuery->pGroupbyExpr->columnInfo); @@ -5098,7 +5266,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, S pInfo->bufCapacity = 4096; pInfo->udfInfo = pUdfInfo; pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor); - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); pInfo->orderColumnList = getOrderCheckColumns(pRuntimeEnv->pQueryAttr); pInfo->groupColumnList = getResultGroupCheckColumns(pRuntimeEnv->pQueryAttr); @@ -5147,7 +5315,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, S // pOperator->exec = doGlobalAggregate; pOperator->cleanup = destroyGlobalAggOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -5296,7 +5464,7 @@ SOperatorInfo *createOrderOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->cleanup = destroyOrderOperatorInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6228,33 +6396,33 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { tfree(pOperator); } -SOperatorInfo* createAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); - STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t numOfRows = (int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); +// STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfRows = 1;//(int32_t)(getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx_rv(pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); pInfo->seed = rand(); - setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MAIN_SCAN); +// setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MAIN_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableAggregate"; -// pOperator->operatorType = OP_Aggregate; + pOperator->operatorType = OP_Aggregate; pOperator->blockingOptr = true; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; pOperator->pExpr = pExpr; pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->pRuntimeEnv = NULL; pOperator->exec = doAggregate; pOperator->cleanup = destroyAggOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6334,7 +6502,7 @@ SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOp size_t tableGroup = GET_NUM_OF_TABLEGROUP(pRuntimeEnv); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, (int32_t) tableGroup); - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)tableGroup, TSDB_DATA_TYPE_INT); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -6349,7 +6517,7 @@ SOperatorInfo* createMultiTableAggOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOp pOperator->exec = doSTableAggregate; pOperator->cleanup = destroyAggOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6362,7 +6530,7 @@ SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperator SOptrBasicInfo* pBInfo = &pInfo->binfo; pBInfo->pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity); - pBInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pBInfo->rowCellInfoOffset); + pBInfo->pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pBInfo->rowCellInfoOffset); initResultRowInfo(&pBInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MAIN_SCAN); @@ -6379,7 +6547,7 @@ SOperatorInfo* createProjectOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperator pOperator->exec = doProjectOperation; pOperator->cleanup = destroyProjectOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6437,7 +6605,7 @@ SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroyConditionOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6455,7 +6623,7 @@ SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorIn pOperator->exec = doLimit; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6463,7 +6631,7 @@ SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorIn SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); - pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); + pInfo->pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6480,7 +6648,7 @@ SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOpe pOperator->exec = doIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6488,7 +6656,7 @@ SOperatorInfo* createTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOpe SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); - pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); + pInfo->pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6505,7 +6673,7 @@ SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, S pOperator->exec = doAllIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6513,7 +6681,7 @@ SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOper SStateWindowOperatorInfo* pInfo = calloc(1, sizeof(SStateWindowOperatorInfo)); pInfo->colIndex = -1; pInfo->reptScan = false; - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6529,13 +6697,13 @@ SOperatorInfo* createStatewindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOper pOperator->exec = doStateWindowAgg; pOperator->cleanup = destroyStateWindowOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo)); - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6554,14 +6722,14 @@ SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperator pOperator->exec = doSessionWindowAgg; pOperator->cleanup = destroySWindowOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); - pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); + pInfo->pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6578,14 +6746,14 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntim pOperator->exec = doSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); - pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); + pInfo->pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset); pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); @@ -6602,7 +6770,7 @@ SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRun pOperator->exec = doAllSTableIntervalAgg; pOperator->cleanup = destroyBasicOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6613,7 +6781,7 @@ SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperator pInfo->colIndex = -1; // group by column index - pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + pInfo->binfo.pCtx = createSqlFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); STaskAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; @@ -6635,7 +6803,7 @@ SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperator pOperator->exec = hashGroupbyAggregate; pOperator->cleanup = destroyGroupbyOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6674,7 +6842,7 @@ SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInf pOperator->exec = doFill; pOperator->cleanup = destroySFillOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -6722,7 +6890,7 @@ SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->cleanup = destroySlimitOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -7020,7 +7188,7 @@ SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperato pOperator->pExpr = pExpr; pOperator->cleanup = destroyDistinctOperatorInfo; - appendUpstream(pOperator, downstream); + appendDownstream(pOperator, downstream); return pOperator; } @@ -7187,10 +7355,13 @@ static SExecTaskInfo* createExecTaskInfo(uint64_t queryId) { SOperatorInfo* doCreateOperatorTreeNode(SPhyNode* pPhyNode, SExecTaskInfo* pTaskInfo, void* param) { if (pPhyNode->pChildren == NULL || taosArrayGetSize(pPhyNode->pChildren) == 0) { if (pPhyNode->info.type == OP_TableScan) { - SScanPhyNode* pScanPhyNode = (SScanPhyNode*) pPhyNode; - size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets); - SOperatorInfo* pOperatorInfo = createTableScanOperator(param, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pTaskInfo); - pTaskInfo->pRoot = pOperatorInfo; + SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode; + size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets); + return createTableScanOperatorInfo(param, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pTaskInfo); + } else if (pPhyNode->info.type == OP_DataBlocksOptScan) { + SScanPhyNode* pScanPhyNode = (SScanPhyNode*)pPhyNode; + size_t numOfCols = taosArrayGetSize(pPhyNode->pTargets); + return createDataBlocksOptScanInfo(param, pScanPhyNode->order, numOfCols, pScanPhyNode->count, pScanPhyNode->reverse, pTaskInfo); } else { assert(0); } @@ -7199,21 +7370,20 @@ SOperatorInfo* doCreateOperatorTreeNode(SPhyNode* pPhyNode, SExecTaskInfo* pTask int32_t doCreateExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, void* readerHandle) { STsdbQueryCond cond = {.loadExternalRows = false}; - cond.twindow.skey = INT64_MIN; - cond.twindow.ekey = INT64_MAX; uint64_t uid = 0; SPhyNode* pPhyNode = pPlan->pNode; - if (pPhyNode->info.type == OP_TableScan) { + if (pPhyNode->info.type == OP_TableScan || pPhyNode->info.type == OP_DataBlocksOptScan) { - SScanPhyNode* pScanNode = (SScanPhyNode*) pPhyNode; - uid = pScanNode->uid; - cond.order = pScanNode->order; - cond.numOfCols = taosArrayGetSize(pScanNode->node.pTargets); + STableScanPhyNode* pTableScanNode = (STableScanPhyNode*) pPhyNode; + uid = pTableScanNode->scan.uid; + cond.order = pTableScanNode->scan.order; + cond.numOfCols = taosArrayGetSize(pTableScanNode->scan.node.pTargets); cond.colList = calloc(cond.numOfCols, sizeof(SColumnInfo)); + cond.twindow = pTableScanNode->window; for(int32_t i = 0; i < cond.numOfCols; ++i) { - SExprInfo* pExprInfo = taosArrayGetP(pScanNode->node.pTargets, i); + SExprInfo* pExprInfo = taosArrayGetP(pTableScanNode->scan.node.pTargets, i); assert(pExprInfo->pExpr->nodeType == TEXPR_COL_NODE); SSchema* pSchema = pExprInfo->pExpr->pSchema; @@ -7235,7 +7405,11 @@ int32_t doCreateExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, void* r *pTaskInfo = createExecTaskInfo((uint64_t)pPlan->id.queryId); tsdbReadHandleT tsdbReadHandle = tsdbQueryTables(readerHandle, &cond, &group, (*pTaskInfo)->id.queryId, NULL); - doCreateOperatorTreeNode(pPlan->pNode, *pTaskInfo, tsdbReadHandle); + (*pTaskInfo)->pRoot = doCreateOperatorTreeNode(pPlan->pNode, *pTaskInfo, tsdbReadHandle); + if ((*pTaskInfo)->pRoot == NULL) { + return terrno; + } + return TSDB_CODE_SUCCESS; } diff --git a/source/libs/function/src/tscalarfunction.c b/source/libs/function/src/tscalarfunction.c index 1e7e3ef1556eaa161ca2311253b656dddc559cce..90d25b3e4a225067a77a66d97f4b103347f38d38 100644 --- a/source/libs/function/src/tscalarfunction.c +++ b/source/libs/function/src/tscalarfunction.c @@ -2,7 +2,6 @@ #include "tbinoperator.h" #include "tunaryoperator.h" - static void assignBasicParaInfo(struct SScalarFuncParam* dst, const struct SScalarFuncParam* src) { dst->type = src->type; dst->bytes = src->bytes; diff --git a/source/libs/parser/inc/astGenerator.h b/source/libs/parser/inc/astGenerator.h index 7f357a2bbdfeff431dcfed899040e2ba264e7a2c..c601c4e3e35a82e6248cc4f24a001dfb2bfb1a56 100644 --- a/source/libs/parser/inc/astGenerator.h +++ b/source/libs/parser/inc/astGenerator.h @@ -170,8 +170,6 @@ typedef struct SCreateDbInfo { int8_t update; int8_t cachelast; SArray *keep; -// int8_t dbType; -// int16_t partitions; } SCreateDbInfo; typedef struct SCreateFuncInfo { diff --git a/source/libs/parser/inc/astToMsg.h b/source/libs/parser/inc/astToMsg.h index 8acbc6bc11ada01cc08d357b408cb74142bdfe0f..8f2c2ad4b34399da900e2f3960459eb0e1e94b58 100644 --- a/source/libs/parser/inc/astToMsg.h +++ b/source/libs/parser/inc/astToMsg.h @@ -8,7 +8,7 @@ SCreateUserReq* buildUserManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); SCreateAcctReq* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t* outputLen, int64_t id, char* msgBuf, int32_t msgLen); -SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext* pParseCtx, char* msgBuf, int32_t msgLen); +SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext* pParseCtx, SMsgBuf* pMsgBuf); SCreateDbReq* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, SParseContext *pCtx, SMsgBuf* pMsgBuf); SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len, SParseContext* pParseCtx, SMsgBuf* pMsgBuf); SMDropStbReq* buildDropStableMsg(SSqlInfo* pInfo, int32_t* len, SParseContext* pParseCtx, SMsgBuf* pMsgBuf); diff --git a/source/libs/parser/src/astGenerator.c b/source/libs/parser/src/astGenerator.c index 34ed8bd3554e86e5a168f67eec5018db3b0f976d..8e8da92bf596fac6e08a6609561fc95b58962cf1 100644 --- a/source/libs/parser/src/astGenerator.c +++ b/source/libs/parser/src/astGenerator.c @@ -972,14 +972,15 @@ void tSetDbName(SToken *pCpxName, SToken *pDb) { void tSetColumnInfo(SField *pField, SToken *pName, SField *pType) { int32_t maxLen = sizeof(pField->name) / sizeof(pField->name[0]); - // column name is too long, set the it to be invalid. + // The column name is too long, set it to be invalid. if ((int32_t) pName->n >= maxLen) { - pName->n = -1; + pField->name[0] = 0; } else { strncpy(pField->name, pName->z, pName->n); pField->name[pName->n] = 0; } + // denote an invalid data type in the column definition. pField->type = pType->type; if(!isValidDataType(pField->type)){ pField->bytes = 0; diff --git a/source/libs/parser/src/astToMsg.c b/source/libs/parser/src/astToMsg.c index 5b841594e067e1af32b1b57014f36ef2f2d98a0f..697fd0c4cbdfe2e2923d502b2260065792047190 100644 --- a/source/libs/parser/src/astToMsg.c +++ b/source/libs/parser/src/astToMsg.c @@ -85,8 +85,12 @@ SDropUserReq* buildDropUserMsg(SSqlInfo* pInfo, int32_t *msgLen, int64_t id, cha return pMsg; } -SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, char* msgBuf, int32_t msgLen) { +SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, SMsgBuf* pMsgBuf) { SShowReq* pShowMsg = calloc(1, sizeof(SShowReq)); + if (pShowMsg == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return pShowMsg; + } pShowMsg->type = pShowInfo->showType; if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) { @@ -105,7 +109,22 @@ SShowReq* buildShowMsg(SShowInfo* pShowInfo, SParseContext *pCtx, char* msgBuf, if (pShowInfo->showType == TSDB_MGMT_TABLE_STB || pShowInfo->showType == TSDB_MGMT_TABLE_VGROUP) { SName n = {0}; - tNameSetDbName(&n, pCtx->acctId, pCtx->db, strlen(pCtx->db)); + + if (pShowInfo->prefix.n > 0) { + if (pShowInfo->prefix.n >= TSDB_DB_FNAME_LEN) { + terrno = buildInvalidOperationMsg(pMsgBuf, "prefix name is too long"); + tfree(pShowMsg); + return NULL; + } + tNameSetDbName(&n, pCtx->acctId, pShowInfo->prefix.z, pShowInfo->prefix.n); + } else if (pCtx->db == NULL || strlen(pCtx->db) == 0) { + terrno = buildInvalidOperationMsg(pMsgBuf, "database is not specified"); + tfree(pShowMsg); + return NULL; + } else { + tNameSetDbName(&n, pCtx->acctId, pCtx->db, strlen(pCtx->db)); + } + tNameGetFullDbName(&n, pShowMsg->db); } @@ -240,6 +259,9 @@ SMCreateStbReq* buildCreateStbMsg(SCreateTableSql* pCreateTableSql, int32_t* len } SMCreateStbReq* pCreateStbMsg = (SMCreateStbReq*)calloc(1, sizeof(SMCreateStbReq) + (numOfCols + numOfTags) * sizeof(SSchema)); + if (pCreateStbMsg == NULL) { + return NULL; + } char* pMsg = NULL; #if 0 diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index 5d56a88c14bc9fccc11d973e89a042e030286cfa..512204b40b1e02f858ec8a494630fa721c95b791 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -917,6 +917,8 @@ int32_t validateLimitNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBu return buildInvalidOperationMsg(pMsgBuf, msg1); } } + + return TSDB_CODE_SUCCESS; } int32_t validateOrderbyNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) { diff --git a/source/libs/parser/src/dCDAstProcess.c b/source/libs/parser/src/dCDAstProcess.c index 4d4d68e9622b1301e8fb18c7dadd873f640512d3..955507ae1b6251d9be22708c782e8c24bcd42b82 100644 --- a/source/libs/parser/src/dCDAstProcess.c +++ b/source/libs/parser/src/dCDAstProcess.c @@ -109,7 +109,11 @@ static int32_t setShowInfo(SShowInfo* pShowInfo, SParseContext* pCtx, void** out } *pEpSet = pCtx->mgmtEpSet; - *output = buildShowMsg(pShowInfo, pCtx, pMsgBuf->buf, pMsgBuf->len); + *output = buildShowMsg(pShowInfo, pCtx, pMsgBuf); + if (*output == NULL) { + return terrno; + } + *outputLen = sizeof(SShowReq) /* + htons(pShowMsg->payloadLen)*/; } @@ -312,9 +316,9 @@ int32_t doCheckForCreateTable(SCreateTableSql* pCreateTable, SMsgBuf* pMsgBuf) { assert(pFieldList != NULL); // if sql specifies db, use it, otherwise use default db - SToken* pzTableName = &(pCreateTable->name); + SToken* pNameToken = &(pCreateTable->name); - if (parserValidateNameToken(pzTableName) != TSDB_CODE_SUCCESS) { + if (parserValidateIdToken(pNameToken) != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg1); } @@ -973,6 +977,7 @@ SVnodeModifOpStmtInfo* qParserValidateCreateTbSqlNode(SSqlInfo* pInfo, SParseCon int32_t msgLen = 0; int32_t code = doCheckAndBuildCreateTableReq(pCreateTable, pCtx, pMsgBuf, (char**) &pModifSqlStmt, &msgLen); if (code != TSDB_CODE_SUCCESS) { + terrno = code; tfree(pModifSqlStmt); return NULL; } diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index fea215238c67dda2a89345132e9d6fa0eca3d802..58e368aa0db24caf87f58ecc094ae1d70e977360 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -80,11 +80,11 @@ int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { return TSDB_CODE_SUCCESS; } -int32_t qParseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { +int32_t qParseQuerySql(SParseContext* pCxt, SQueryNode** pQueryNode) { if (isInsertSql(pCxt->pSql, pCxt->sqlLen)) { - return parseInsertSql(pCxt, (SVnodeModifOpStmtInfo**)pQuery); + return parseInsertSql(pCxt, (SVnodeModifOpStmtInfo**)pQueryNode); } else { - return parseQuerySql(pCxt, pQuery); + return parseQuerySql(pCxt, pQueryNode); } } diff --git a/source/libs/parser/src/parserUtil.c b/source/libs/parser/src/parserUtil.c index 7bb0f8ee835193f28d4c900cea9d4816a4cabbde..4d506b84a0b04d8cfac215c8a23eb8b277080ed9 100644 --- a/source/libs/parser/src/parserUtil.c +++ b/source/libs/parser/src/parserUtil.c @@ -124,12 +124,13 @@ int32_t parserValidatePassword(SToken* pToken, SMsgBuf* pMsgBuf) { } int32_t parserValidateNameToken(SToken* pToken) { - if (pToken == NULL || pToken->z == NULL || pToken->type != TK_ID) { + if (pToken == NULL || pToken->z == NULL || pToken->type != TK_ID || pToken->n == 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } // it is a token quoted with escape char '`' if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) { + pToken->n = strdequote(pToken->z); return TSDB_CODE_SUCCESS; } @@ -1945,17 +1946,30 @@ int32_t KvRowAppend(const void *value, int32_t len, void *param) { int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, SMsgBuf* pMsgBuf) { const char* msg1 = "name too long"; + const char* msg2 = "invalid database name"; int32_t code = TSDB_CODE_SUCCESS; - char* p = strnchr(pTableName->z, TS_PATH_DELIMITER[0], pTableName->n, false); + char* p = strnchr(pTableName->z, TS_PATH_DELIMITER[0], pTableName->n, true); if (p != NULL) { // db has been specified in sql string so we ignore current db path - tNameSetAcctId(pName, pParseCtx->acctId); + assert(*p == TS_PATH_DELIMITER[0]); - char name[TSDB_TABLE_FNAME_LEN] = {0}; - strncpy(name, pTableName->z, pTableName->n); + int32_t dbLen = p - pTableName->z; + char name[TSDB_DB_FNAME_LEN] = {0}; + strncpy(name, pTableName->z, dbLen); + dbLen = strdequote(name); - code = tNameFromString(pName, name, T_NAME_DB|T_NAME_TABLE); + code = tNameSetDbName(pName, pParseCtx->acctId, name, dbLen); + if (code != TSDB_CODE_SUCCESS) { + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + + int32_t tbLen = pTableName->n - dbLen - 1; + char tbname[TSDB_TABLE_FNAME_LEN] = {0}; + strncpy(tbname, p + 1, tbLen); + /*tbLen = */strdequote(tbname); + + code = tNameFromString(pName, tbname, T_NAME_TABLE); if (code != 0) { return buildInvalidOperationMsg(pMsgBuf, msg1); } @@ -1964,10 +1978,17 @@ int32_t createSName(SName* pName, SToken* pTableName, SParseContext* pParseCtx, return buildInvalidOperationMsg(pMsgBuf, msg1); } - tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db)); + assert(pTableName->n < TSDB_TABLE_FNAME_LEN); char name[TSDB_TABLE_FNAME_LEN] = {0}; strncpy(name, pTableName->z, pTableName->n); + strdequote(name); + + code = tNameSetDbName(pName, pParseCtx->acctId, pParseCtx->db, strlen(pParseCtx->db)); + if (code != TSDB_CODE_SUCCESS) { + code = buildInvalidOperationMsg(pMsgBuf, msg2); + return code; + } code = tNameFromString(pName, name, T_NAME_TABLE); if (code != 0) { diff --git a/source/libs/planner/src/physicalPlan.c b/source/libs/planner/src/physicalPlan.c index 65c97110cec7bfeaf91804499acd0f2a10f59840..422233eed74beaf0e322023afbb394736ea8b2c3 100644 --- a/source/libs/planner/src/physicalPlan.c +++ b/source/libs/planner/src/physicalPlan.c @@ -189,6 +189,7 @@ static SPhyNode* createUserTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableI return (SPhyNode*)node; } + static bool isSystemTable(SQueryTableInfo* pTable) { // todo return false; @@ -261,8 +262,8 @@ static void vgroupMsgToEpSet(const SVgroupMsg* vg, SQueryNodeAddr* execNode) { } static uint64_t splitSubplanByTable(SPlanContext* pCxt, SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { - SVgroupsInfo* vgroupList = pTable->pMeta->vgroupList; - for (int32_t i = 0; i < pTable->pMeta->vgroupList->numOfVgroups; ++i) { + SVgroupsInfo* pVgroupList = pTable->pMeta->vgroupList; + for (int32_t i = 0; i < pVgroupList->numOfVgroups; ++i) { STORE_CURRENT_SUBPLAN(pCxt); SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_SCAN); subplan->msgType = TDMT_VND_QUERY; diff --git a/source/libs/planner/src/physicalPlanJson.c b/source/libs/planner/src/physicalPlanJson.c index 123364134d16bf77feb3fe2bc56b5e497bf3fcfe..97eb63ac3129bc8454b6263b7f8aca31f2dde397 100644 --- a/source/libs/planner/src/physicalPlanJson.c +++ b/source/libs/planner/src/physicalPlanJson.c @@ -559,28 +559,35 @@ static const char* jkScanNodeTableId = "TableId"; static const char* jkScanNodeTableType = "TableType"; static const char* jkScanNodeTableOrder = "Order"; static const char* jkScanNodeTableCount = "Count"; +static const char* jkScanNodeTableRevCount = "Reverse"; static bool scanNodeToJson(const void* obj, cJSON* json) { - const SScanPhyNode* scan = (const SScanPhyNode*)obj; - bool res = cJSON_AddNumberToObject(json, jkScanNodeTableId, scan->uid); + const SScanPhyNode* pNode = (const SScanPhyNode*)obj; + bool res = cJSON_AddNumberToObject(json, jkScanNodeTableId, pNode->uid); + + if (res) { + res = cJSON_AddNumberToObject(json, jkScanNodeTableType, pNode->tableType); + } if (res) { - res = cJSON_AddNumberToObject(json, jkScanNodeTableType, scan->tableType); + res = cJSON_AddNumberToObject(json, jkScanNodeTableOrder, pNode->order); } if (res) { - res = cJSON_AddNumberToObject(json, jkScanNodeTableOrder, scan->order); + res = cJSON_AddNumberToObject(json, jkScanNodeTableCount, pNode->count); } + if (res) { - res = cJSON_AddNumberToObject(json, jkScanNodeTableCount, scan->count); + res = cJSON_AddNumberToObject(json, jkScanNodeTableRevCount, pNode->reverse); } return res; } static bool scanNodeFromJson(const cJSON* json, void* obj) { - SScanPhyNode* scan = (SScanPhyNode*)obj; - scan->uid = getNumber(json, jkScanNodeTableId); - scan->tableType = getNumber(json, jkScanNodeTableType); - scan->count = getNumber(json, jkScanNodeTableCount); - scan->order = getNumber(json, jkScanNodeTableOrder); + SScanPhyNode* pNode = (SScanPhyNode*)obj; + pNode->uid = getNumber(json, jkScanNodeTableId); + pNode->tableType = getNumber(json, jkScanNodeTableType); + pNode->count = getNumber(json, jkScanNodeTableCount); + pNode->order = getNumber(json, jkScanNodeTableOrder); + pNode->reverse = getNumber(json, jkScanNodeTableRevCount); return true; } @@ -996,10 +1003,13 @@ static SSubplan* subplanFromJson(const cJSON* json) { if (NULL == subplan) { return NULL; } + bool res = fromObject(json, jkSubplanId, subplanIdFromJson, &subplan->id, true); + if (res) { res = fromPnode(json, jkSubplanNode, phyNodeFromJson, (void**)&subplan->pNode); } + if (res) { res = fromObjectWithAlloc(json, jkSubplanDataSink, dataSinkFromJson, (void**)&subplan->pDataSink, sizeof(SDataSink), false); } @@ -1027,7 +1037,7 @@ int32_t subPlanToString(const SSubplan* subplan, char** str, int32_t* len) { } *str = cJSON_Print(json); -// printf("====Physical plan:====\n") +// printf("====Physical plan:====\n"); // printf("%s\n", *str); *len = strlen(*str) + 1; return TSDB_CODE_SUCCESS; @@ -1047,14 +1057,18 @@ cJSON* qDagToJson(const SQueryDag* pDag) { if(pRoot == NULL) { return NULL; } - cJSON_AddNumberToObject(pRoot, "numOfSubplans", pDag->numOfSubplans); - cJSON_AddNumberToObject(pRoot, "queryId", pDag->queryId); + + cJSON_AddNumberToObject(pRoot, "Number", pDag->numOfSubplans); + cJSON_AddNumberToObject(pRoot, "QueryId", pDag->queryId); + cJSON *pLevels = cJSON_CreateArray(); if(pLevels == NULL) { cJSON_Delete(pRoot); return NULL; } - cJSON_AddItemToObject(pRoot, "pSubplans", pLevels); + + cJSON_AddItemToObject(pRoot, "Subplans", pLevels); + size_t level = taosArrayGetSize(pDag->pSubplans); for(size_t i = 0; i < level; i++) { const SArray* pSubplans = (const SArray*)taosArrayGetP(pDag->pSubplans, i); @@ -1064,6 +1078,7 @@ cJSON* qDagToJson(const SQueryDag* pDag) { cJSON_Delete(pRoot); return NULL; } + cJSON_AddItemToArray(pLevels, plansOneLevel); for(size_t j = 0; j < num; j++) { cJSON* pSubplan = subplanToJson((const SSubplan*)taosArrayGetP(pSubplans, j)); @@ -1071,6 +1086,7 @@ cJSON* qDagToJson(const SQueryDag* pDag) { cJSON_Delete(pRoot); return NULL; } + cJSON_AddItemToArray(plansOneLevel, pSubplan); } } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 095f17992532d2ea7cbb1e7dc7d4c15792b761f6..62ea28b811d15e9901fd0bb5d333fdffb1eb072c 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -1029,6 +1029,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, msg = pTask->msg; break; } + case TDMT_VND_QUERY: { msgSize = sizeof(SSubQueryMsg) + pTask->msgLen; msg = calloc(1, msgSize); @@ -1047,7 +1048,8 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, pMsg->contentLen = htonl(pTask->msgLen); memcpy(pMsg->msg, pTask->msg, pTask->msgLen); break; - } + } + case TDMT_VND_RES_READY: { msgSize = sizeof(SResReadyReq); msg = calloc(1, msgSize); diff --git a/source/libs/tdb/CMakeLists.txt b/source/libs/tdb/CMakeLists.txt index 647771fd2da71417533b6f4d5b356e28ea5d3666..eb63f2b14479e1e4cb45a4e2b1bf015a7b4699a1 100644 --- a/source/libs/tdb/CMakeLists.txt +++ b/source/libs/tdb/CMakeLists.txt @@ -1,10 +1,11 @@ -aux_source_directory(src TDB_SRC) + +set(TDB_SUBDIRS "btree" "db" "hash" "mpool" "dmgr") +foreach(TDB_SUBDIR ${TDB_SUBDIRS}) + aux_source_directory("src/${TDB_SUBDIR}" TDB_SRC) +endforeach() + add_library(tdb STATIC ${TDB_SRC}) -# target_include_directories( -# tkv -# PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/tkv" -# PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" -# ) + target_include_directories( tdb PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" @@ -17,5 +18,5 @@ target_link_libraries( ) if(${BUILD_TEST}) - # add_subdirectory(test) + add_subdirectory(test) endif(${BUILD_TEST}) diff --git a/source/libs/tdb/inc/tdb.h b/source/libs/tdb/inc/tdb.h index 40d79de8215e530a7c453a71ee497b6e9ba42bfa..905b08ee0bffdddd948fc62d70b0d42cf7f6a17b 100644 --- a/source/libs/tdb/inc/tdb.h +++ b/source/libs/tdb/inc/tdb.h @@ -22,10 +22,14 @@ extern "C" { #endif +#define TDB_EXTERN +#define TDB_PUBLIC +#define TDB_STATIC static + typedef enum { - TDB_BTREE = 0, - TDB_HASH, - TDB_HEAP, + TDB_BTREE_T = 0, + TDB_HASH_T, + TDB_HEAP_T, } tdb_db_t; // Forward declaration @@ -39,9 +43,9 @@ typedef struct { } TDB_KEY, TDB_VALUE; // TDB Operations -int tdbCreateDB(TDB** dbpp); -int tdbOpenDB(TDB* dbp, tdb_db_t type, uint32_t flags); -int tdbCloseDB(TDB* dbp, uint32_t flags); +TDB_EXTERN int tdbCreateDB(TDB** dbpp, tdb_db_t type); +TDB_EXTERN int tdbOpenDB(TDB* dbp, uint32_t flags); +TDB_EXTERN int tdbCloseDB(TDB* dbp, uint32_t flags); #ifdef __cplusplus } diff --git a/source/libs/tdb/src/db/tdbDB.c b/source/libs/tdb/src/db/tdbDB.c new file mode 100644 index 0000000000000000000000000000000000000000..2af40d8642376ed1720082a6172f845caad7d637 --- /dev/null +++ b/source/libs/tdb/src/db/tdbDB.c @@ -0,0 +1,67 @@ +/* + * 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 . + */ + +#include "tdbDB.h" +#include "tdb.h" + +TDB_EXTERN int tdbCreateDB(TDB** dbpp, tdb_db_t type) { + TDB* dbp; + int ret; + + dbp = calloc(1, sizeof(*dbp)); + if (dbp == NULL) { + return -1; + } + + dbp->pageSize = TDB_DEFAULT_PGSIZE; + dbp->type = type; + + switch (type) { + case TDB_BTREE_T: + // ret = tdbInitBtreeDB(dbp); + // if (ret < 0) goto _err; + break; + case TDB_HASH_T: + // ret = tdbInitHashDB(dbp); + // if (ret < 0) goto _err; + break; + case TDB_HEAP_T: + // ret = tdbInitHeapDB(dbp); + // if (ret < 0) goto _err; + break; + default: + break; + } + + *dbpp = dbp; + return 0; + +_err: + if (dbp) { + free(dbp); + } + *dbpp = NULL; + return 0; +} + +TDB_EXTERN int tdbOpenDB(TDB* dbp, uint32_t flags) { + // TODO + return 0; +} + +TDB_EXTERN int tdbCloseDB(TDB* dbp, uint32_t flags) { + // TODO + return 0; +} \ No newline at end of file diff --git a/source/libs/tdb/src/tdbDiskMgr.c b/source/libs/tdb/src/dmgr/tdbDiskMgr.c similarity index 100% rename from source/libs/tdb/src/tdbDiskMgr.c rename to source/libs/tdb/src/dmgr/tdbDiskMgr.c diff --git a/source/libs/tdb/src/inc/tdbBtree.h b/source/libs/tdb/src/inc/tdbBtree.h index c68f94bb4870fd3323d9859f22f9c5de90a333c2..28258b8e60b7ea44f13fc56903d99e7427cdddfc 100644 --- a/source/libs/tdb/src/inc/tdbBtree.h +++ b/source/libs/tdb/src/inc/tdbBtree.h @@ -16,7 +16,7 @@ #ifndef _TD_TDB_BTREE_H_ #define _TD_TDB_BTREE_H_ -#include "tkvDef.h" +#include "tdbDef.h" #ifdef __cplusplus extern "C" { @@ -26,6 +26,8 @@ typedef struct { pgid_t root; // root page number } TDB_BTREE; +TDB_PUBLIC int tdbInitBtreeDB(TDB *dbp); + #ifdef __cplusplus } #endif diff --git a/source/libs/tdb/src/inc/tdbDB.h b/source/libs/tdb/src/inc/tdbDB.h index 479ef777111dc420495298f8c447b0d7cbab46e8..fca197dc39f28a1d27ed250bd940f8b1b7055e9d 100644 --- a/source/libs/tdb/src/inc/tdbDB.h +++ b/source/libs/tdb/src/inc/tdbDB.h @@ -16,21 +16,25 @@ #ifndef _TD_TDB_DB_H_ #define _TD_TDB_DB_H_ +#include "tdb.h" #include "tdbBtree.h" #include "tdbHash.h" +#include "tdbHeap.h" #ifdef __cplusplus extern "C" { #endif - struct TDB { pgsize_t pageSize; tdb_db_t type; + char * fname; + char * dbname; union { - TDB_BTREE btree; - TDB_HASH hash; - } dbam; // Different access methods + TDB_BTREE *btree; + TDB_HASH * hash; + TDB_HEAP * heap; + } dbam; // db access method }; #ifdef __cplusplus diff --git a/source/libs/tdb/src/inc/tdbDef.h b/source/libs/tdb/src/inc/tdbDef.h index a04b8cc402d9023628411ac2b619ae66ab7c31f7..4b5e54368bddd630c21db87a80dd398c8354fce1 100644 --- a/source/libs/tdb/src/inc/tdbDef.h +++ b/source/libs/tdb/src/inc/tdbDef.h @@ -24,16 +24,17 @@ extern "C" { // pgid_t typedef int32_t pgid_t; -#define TKV_IVLD_PGID ((pgid_t)-1) +#define TDB_IVLD_PGID ((pgid_t)-1) // framd_id_t typedef int32_t frame_id_t; // pgsize_t typedef int32_t pgsize_t; -#define TKV_MIN_PGSIZE 512 -#define TKV_MAX_PGSIZE 16384 -#define TKV_IS_PGSIZE_VLD(s) (((s) >= TKV_MIN_PGSIZE) && (TKV_MAX_PGSIZE <= TKV_MAX_PGSIZE)) +#define TDB_MIN_PGSIZE 512 +#define TDB_MAX_PGSIZE 16384 +#define TDB_DEFAULT_PGSIZE 4096 +#define TDB_IS_PGSIZE_VLD(s) (((s) >= TKV_MIN_PGSIZE) && (TKV_MAX_PGSIZE <= TKV_MAX_PGSIZE)) #ifdef __cplusplus } diff --git a/source/libs/tdb/src/inc/tdbHash.h b/source/libs/tdb/src/inc/tdbHash.h index fca19035f1d6fd40f8ece7cdb488a8dbb919bed2..8219bda2f82eae05f7aa1fba5433c261272612b5 100644 --- a/source/libs/tdb/src/inc/tdbHash.h +++ b/source/libs/tdb/src/inc/tdbHash.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef _TD_TKV_HAHS_H_ -#define _TD_TKV_HAHS_H_ +#ifndef _TD_TDB_HASH_H_ +#define _TD_TDB_HASH_H_ #include "tdbDef.h" @@ -26,8 +26,10 @@ typedef struct { // TODO } TDB_HASH; +TDB_PUBLIC int tdbInitHashDB(TDB *dbp); + #ifdef __cplusplus } #endif -#endif /*_TD_TKV_HAHS_H_*/ \ No newline at end of file +#endif /*_TD_TDB_HASH_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnodeStateMgr.h b/source/libs/tdb/src/inc/tdbHeap.h similarity index 81% rename from source/dnode/vnode/src/inc/vnodeStateMgr.h rename to source/libs/tdb/src/inc/tdbHeap.h index 5862b304ed171d135d7096ab4af076ce6fcbb8e3..25a812fa5f7507624b6e4e02954735cbd0e38b00 100644 --- a/source/dnode/vnode/src/inc/vnodeStateMgr.h +++ b/source/libs/tdb/src/inc/tdbHeap.h @@ -13,21 +13,23 @@ * along with this program. If not, see . */ -#ifndef _TD_VNODE_STATE_MGR_H_ -#define _TD_VNODE_STATE_MGR_H_ +#ifndef _TD_TDB_HEAP_H_ +#define _TD_TDB_HEAP_H_ + +#include "tdbDef.h" #ifdef __cplusplus extern "C" { #endif typedef struct { - int64_t processed; - int64_t committed; - int64_t applied; -} SVState; + // TODO +} TDB_HEAP; + +TDB_PUBLIC int tdbInitHeapDB(TDB *dbp); #ifdef __cplusplus } #endif -#endif /*_TD_VNODE_STATE_MGR_H_*/ +#endif /*_TD_TDB_HEAP_H_*/ \ No newline at end of file diff --git a/source/libs/tdb/src/tdbBufPool.c b/source/libs/tdb/src/mpool/tdbBufPool.c similarity index 100% rename from source/libs/tdb/src/tdbBufPool.c rename to source/libs/tdb/src/mpool/tdbBufPool.c diff --git a/source/libs/tdb/test/tdbTest.cpp b/source/libs/tdb/test/tdbTest.cpp index 3ff43fdd696ab0d6e727ddf77850ef0a167e125f..38c3b0b9173fe2bfec0f6a674b63e38dedfcd1e9 100644 --- a/source/libs/tdb/test/tdbTest.cpp +++ b/source/libs/tdb/test/tdbTest.cpp @@ -6,9 +6,9 @@ TEST(tdb_api_test, tdb_create_open_close_db_test) { int ret; TDB *dbp; - tdbCreateDB(&dbp); + tdbCreateDB(&dbp, TDB_BTREE_T); - tdbOpenDB(dbp, TDB_BTREE, 0); + tdbOpenDB(dbp, 0); tdbCloseDB(dbp, 0); } \ No newline at end of file diff --git a/source/libs/transport/CMakeLists.txt b/source/libs/transport/CMakeLists.txt index c4eeef5df20f23e8d2c557bc7e91a8ce2442032c..61d781210c7eb0239ce447a757a9a25c54a6775d 100644 --- a/source/libs/transport/CMakeLists.txt +++ b/source/libs/transport/CMakeLists.txt @@ -27,4 +27,11 @@ if (${BUILD_WITH_UV}) add_definitions(-DUSE_UV) endif(${BUILD_WITH_UV}) +if (${BUILD_TEST}) + add_subdirectory(test) +endif(${BUILD_TEST}) + + + + diff --git a/source/libs/transport/inc/rpcHead.h b/source/libs/transport/inc/rpcHead.h index 7317d84af1671c06452b6b3f4525675414e160a5..5ddf1a83c96271abba9aefc254b9cee442c375cc 100644 --- a/source/libs/transport/inc/rpcHead.h +++ b/source/libs/transport/inc/rpcHead.h @@ -21,10 +21,6 @@ extern "C" { #endif -#ifdef USE_UV - -#else - #define RPC_CONN_TCP 2 extern int tsRpcOverhead; @@ -75,7 +71,6 @@ typedef struct { } SRpcDigest; #pragma pack(pop) -#endif #ifdef __cplusplus } diff --git a/source/libs/transport/inc/rpcTcp.h b/source/libs/transport/inc/rpcTcp.h index 5e5c43a1db95a2886552db9c0e65df83115b2cd3..ad42307516462521055575d11bef38273b125fe1 100644 --- a/source/libs/transport/inc/rpcTcp.h +++ b/source/libs/transport/inc/rpcTcp.h @@ -21,8 +21,6 @@ extern "C" { #endif -#ifdef USE_UV -#else void *taosInitTcpServer(uint32_t ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle); void taosStopTcpServer(void *param); void taosCleanUpTcpServer(void *param); @@ -35,8 +33,6 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin void taosCloseTcpConnection(void *chandle); int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle); -#endif - #ifdef __cplusplus } #endif diff --git a/source/libs/transport/inc/transportInt.h b/source/libs/transport/inc/transportInt.h index 9809f7ee1af24f3cbe426c7e67f62f7f0ebebb42..f93753cfe9a20d39cff4a313dc1b81866ebecd73 100644 --- a/source/libs/transport/inc/transportInt.h +++ b/source/libs/transport/inc/transportInt.h @@ -16,15 +16,65 @@ #ifndef _TD_TRANSPORT_INT_H_ #define _TD_TRANSPORT_INT_H_ +#include "rpcHead.h" #ifdef __cplusplus extern "C" { #endif #ifdef USE_UV -#else +#include +typedef void *queue[2]; + +/* Private macros. */ +#define QUEUE_NEXT(q) (*(queue **)&((*(q))[0])) +#define QUEUE_PREV(q) (*(queue **)&((*(q))[1])) + +#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q))) +#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q))) + +/* Initialize an empty queue. */ +#define QUEUE_INIT(q) \ + { \ + QUEUE_NEXT(q) = (q); \ + QUEUE_PREV(q) = (q); \ + } + +/* Return true if the queue has no element. */ +#define QUEUE_IS_EMPTY(q) ((const queue *)(q) == (const queue *)QUEUE_NEXT(q)) + +/* Insert an element at the back of a queue. */ +#define QUEUE_PUSH(q, e) \ + { \ + QUEUE_NEXT(e) = (q); \ + QUEUE_PREV(e) = QUEUE_PREV(q); \ + QUEUE_PREV_NEXT(e) = (e); \ + QUEUE_PREV(q) = (e); \ + } + +/* Remove the given element from the queue. Any element can be removed at any * + * time. */ +#define QUEUE_REMOVE(e) \ + { \ + QUEUE_PREV_NEXT(e) = QUEUE_NEXT(e); \ + QUEUE_NEXT_PREV(e) = QUEUE_PREV(e); \ + } + +/* Return the element at the front of the queue. */ +#define QUEUE_HEAD(q) (QUEUE_NEXT(q)) + +/* Return the element at the back of the queue. */ +#define QUEUE_TAIL(q) (QUEUE_PREV(q)) + +/* Iterate over the element of a queue. * Mutating the queue while iterating + * results in undefined behavior. */ +#define QUEUE_FOREACH(q, e) for ((q) = QUEUE_NEXT(e); (q) != (e); (q) = QUEUE_NEXT(q)) + +/* Return the structure holding the given element. */ +#define QUEUE_DATA(e, type, field) ((type *)((void *)((char *)(e)-offsetof(type, field)))) + +#endif // USE_LIBUV -#endif #ifdef __cplusplus } #endif diff --git a/source/libs/transport/src/rpcCache.c b/source/libs/transport/src/rpcCache.c index 40767d2ba53c27cc183c29305837d041673320d2..1db2808126a162e4b15305ff80057955de1025a3 100644 --- a/source/libs/transport/src/rpcCache.c +++ b/source/libs/transport/src/rpcCache.c @@ -22,9 +22,6 @@ #include "ttimer.h" #include "tutil.h" -#ifdef USE_UV - -#else typedef struct SConnHash { char fqdn[TSDB_FQDN_LEN]; uint16_t port; @@ -295,4 +292,3 @@ static void rpcUnlockCache(int64_t *lockedBy) { assert(false); } } -#endif diff --git a/source/libs/transport/src/rpcMain.c b/source/libs/transport/src/rpcMain.c index 3095ddb9d254e67692a26874040c7ad3580091d7..f381768a34de1a6c46a55f5aeaa7d495f9d4d655 100644 --- a/source/libs/transport/src/rpcMain.c +++ b/source/libs/transport/src/rpcMain.c @@ -13,9 +13,6 @@ * along with this program. If not, see . */ -#ifdef USE_UV -#include -#endif #include "lz4.h" #include "os.h" #include "rpcCache.h" @@ -30,11 +27,23 @@ #include "tmd5.h" #include "tmempool.h" #include "tmsg.h" +#include "transportInt.h" #include "tref.h" #include "trpc.h" #include "ttimer.h" #include "tutil.h" +static pthread_once_t tsRpcInitOnce = PTHREAD_ONCE_INIT; + +int tsRpcMaxUdpSize = 15000; // bytes +int tsProgressTimer = 100; +// not configurable +int tsRpcMaxRetry; +int tsRpcHeadSize; +int tsRpcOverhead; + +#ifndef USE_UV + typedef struct { int sessions; // number of sessions allowed int numOfThreads; // number of threads to process incoming messages @@ -50,235 +59,21 @@ typedef struct { char secret[TSDB_PASSWORD_LEN]; // secret for the link char ckey[TSDB_PASSWORD_LEN]; // ciphering key - void (*cfp)(void* parent, SRpcMsg*, SEpSet*); - int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey); + void (*cfp)(void *parent, SRpcMsg *, SEpSet *); + int (*afp)(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey); int32_t refCount; - void* parent; - void* idPool; // handle to ID pool - void* tmrCtrl; // handle to timer - SHashObj* hash; // handle returned by hash utility - void* tcphandle; // returned handle from TCP initialization - void* udphandle; // returned handle from UDP initialization - void* pCache; // connection cache + void * parent; + void * idPool; // handle to ID pool + void * tmrCtrl; // handle to timer + SHashObj * hash; // handle returned by hash utility + void * tcphandle; // returned handle from TCP initialization + void * udphandle; // returned handle from UDP initialization + void * pCache; // connection cache pthread_mutex_t mutex; - struct SRpcConn* connList; // connection list + struct SRpcConn *connList; // connection list } SRpcInfo; -#ifdef USE_UV - -#define container_of(ptr, type, member) ((type*)((char*)(ptr)-offsetof(type, member))) - -typedef struct SThreadObj { - pthread_t thread; - uv_pipe_t* pipe; - uv_loop_t* loop; - uv_async_t* workerAsync; // - int fd; -} SThreadObj; - -typedef struct SServerObj { - uv_tcp_t server; - uv_loop_t* loop; - int workerIdx; - int numOfThread; - SThreadObj** pThreadObj; - uv_pipe_t** pipe; -} SServerObj; - -typedef struct SConnCtx { - uv_tcp_t* pClient; - uv_timer_t* pTimer; - uv_async_t* pWorkerAsync; - int ref; -} SConnCtx; - -static void allocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); -static void onTimeout(uv_timer_t* handle); -static void onRead(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf); -static void onWrite(uv_write_t* req, int status); -static void onAccept(uv_stream_t* stream, int status); -void onConnection(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf); -static void workerAsyncCB(uv_async_t* handle); -static void* workerThread(void* arg); - -int32_t rpcInit() { return -1; } -void rpcCleanup() { return; }; -void* rpcOpen(const SRpcInit* pInit) { - SRpcInfo* pRpc = calloc(1, sizeof(SRpcInfo)); - if (pRpc == NULL) { - return NULL; - } - if (pInit->label) { - tstrncpy(pRpc->label, pInit->label, sizeof(pRpc->label)); - } - pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads; - - SServerObj* srv = calloc(1, sizeof(SServerObj)); - srv->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); - srv->numOfThread = pRpc->numOfThreads; - srv->workerIdx = 0; - srv->pThreadObj = (SThreadObj**)calloc(srv->numOfThread, sizeof(SThreadObj*)); - srv->pipe = (uv_pipe_t**)calloc(srv->numOfThread, sizeof(uv_pipe_t*)); - uv_loop_init(srv->loop); - - for (int i = 0; i < srv->numOfThread; i++) { - srv->pThreadObj[i] = (SThreadObj*)calloc(1, sizeof(SThreadObj)); - srv->pipe[i] = (uv_pipe_t*)calloc(2, sizeof(uv_pipe_t)); - int fds[2]; - if (uv_socketpair(AF_UNIX, SOCK_STREAM, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE) != 0) { - return NULL; - } - uv_pipe_init(srv->loop, &(srv->pipe[i][0]), 1); - uv_pipe_open(&(srv->pipe[i][0]), fds[1]); // init write - - srv->pThreadObj[i]->fd = fds[0]; - srv->pThreadObj[i]->pipe = &(srv->pipe[i][1]); // init read - int err = pthread_create(&(srv->pThreadObj[i]->thread), NULL, workerThread, (void*)(srv->pThreadObj[i])); - if (err == 0) { - tError("sucess to create worker thread %d", i); - // printf("thread %d create\n", i); - } else { - tError("failed to create worker thread %d", i); - return NULL; - } - } - uv_tcp_init(srv->loop, &srv->server); - struct sockaddr_in bind_addr; - uv_ip4_addr("0.0.0.0", pInit->localPort, &bind_addr); - uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 0); - int err = 0; - if ((err = uv_listen((uv_stream_t*)&srv->server, 128, onAccept)) != 0) { - tError("Listen error %s\n", uv_err_name(err)); - return NULL; - } - uv_run(srv->loop, UV_RUN_DEFAULT); - - return pRpc; -} -void rpcClose(void* arg) { return; } -void* rpcMallocCont(int contLen) { return NULL; } -void rpcFreeCont(void* cont) { return; } -void* rpcReallocCont(void* ptr, int contLen) { return NULL; } - -void rpcSendRequest(void* thandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* rid) { return; } - -void rpcSendResponse(const SRpcMsg* pMsg) {} - -void rpcSendRedirectRsp(void* pConn, const SEpSet* pEpSet) {} -int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return -1; } -void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { return; } -int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; } -void rpcCancelRequest(int64_t rid) { return; } - -void allocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - -void onTimeout(uv_timer_t* handle) { - // opt - tDebug("time out"); -} -void onRead(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { - // opt - tDebug("data already was read on a stream"); -} - -void onWrite(uv_write_t* req, int status) { - // opt - if (req) tDebug("data already was written on stream"); -} - -void workerAsyncCB(uv_async_t* handle) { - // opt - SThreadObj* pObj = container_of(handle, SThreadObj, workerAsync); -} -void onAccept(uv_stream_t* stream, int status) { - if (status == -1) { - return; - } - SServerObj* pObj = container_of(stream, SServerObj, server); - tDebug("new conntion accepted by main server, dispatch to one worker thread"); - - uv_tcp_t* cli = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); - uv_tcp_init(pObj->loop, cli); - if (uv_accept(stream, (uv_stream_t*)cli) == 0) { - uv_write_t* wr = (uv_write_t*)malloc(sizeof(uv_write_t)); - - uv_buf_t buf = uv_buf_init("a", 1); - // despatch to worker thread - pObj->workerIdx = (pObj->workerIdx + 1) % pObj->numOfThread; - uv_write2(wr, (uv_stream_t*)&(pObj->pipe[pObj->workerIdx][0]), &buf, 1, (uv_stream_t*)cli, onWrite); - } else { - uv_close((uv_handle_t*)cli, NULL); - } -} -void onConnection(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { - if (nread < 0) { - if (nread != UV_EOF) { - tError("read error %s", uv_err_name(nread)); - } - // TODO(log other failure reason) - uv_close((uv_handle_t*)q, NULL); - return; - } - SThreadObj* pObj = (SThreadObj*)container_of(q, struct SThreadObj, pipe); - - uv_pipe_t* pipe = (uv_pipe_t*)q; - if (!uv_pipe_pending_count(pipe)) { - tError("No pending count"); - return; - } - uv_handle_type pending = uv_pipe_pending_type(pipe); - assert(pending == UV_TCP); - - SConnCtx* pConn = malloc(sizeof(SConnCtx)); - /* init conn timer*/ - pConn->pTimer = malloc(sizeof(uv_timer_t)); - uv_timer_init(pObj->loop, pConn->pTimer); - - pConn->pClient = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); - pConn->pWorkerAsync = pObj->workerAsync; // thread safty - uv_tcp_init(pObj->loop, pConn->pClient); - - if (uv_accept(q, (uv_stream_t*)(pConn->pClient)) == 0) { - uv_os_fd_t fd; - uv_fileno((const uv_handle_t*)pConn->pClient, &fd); - tDebug("new connection created: %d", fd); - uv_timer_start(pConn->pTimer, onTimeout, 10, 0); - uv_read_start((uv_stream_t*)(pConn->pClient), allocBuffer, onRead); - } else { - uv_timer_stop(pConn->pTimer); - free(pConn->pTimer); - uv_close((uv_handle_t*)pConn->pClient, NULL); - free(pConn->pClient); - free(pConn); - } -} - -void* workerThread(void* arg) { - SThreadObj* pObj = (SThreadObj*)arg; - int fd = pObj->fd; - pObj->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); - uv_loop_init(pObj->loop); - - uv_pipe_init(pObj->loop, pObj->pipe, 1); - uv_pipe_open(pObj->pipe, fd); - - pObj->workerAsync = malloc(sizeof(uv_async_t)); - uv_async_init(pObj->loop, pObj->workerAsync, workerAsyncCB); - uv_read_start((uv_stream_t*)pObj->pipe, allocBuffer, onConnection); -} -#else - -#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest)) -#define rpcHeadFromCont(cont) ((SRpcHead*)((char*)cont - sizeof(SRpcHead))) -#define rpcContFromHead(msg) (msg + sizeof(SRpcHead)) -#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead)) -#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead)) -#define rpcIsReq(type) (type & 1U) - typedef struct { SRpcInfo * pRpc; // associated SRpcInfo SEpSet epSet; // ip list provided by app @@ -299,6 +94,13 @@ typedef struct { char msg[0]; // RpcHead starts from here } SRpcReqContext; +#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest)) +#define rpcHeadFromCont(cont) ((SRpcHead *)((char *)cont - sizeof(SRpcHead))) +#define rpcContFromHead(msg) (msg + sizeof(SRpcHead)) +#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead)) +#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead)) +#define rpcIsReq(type) (type & 1U) + typedef struct SRpcConn { char info[48]; // debug info: label + pConn + ahandle int sid; // session ID @@ -336,15 +138,6 @@ typedef struct SRpcConn { SRpcReqContext *pContext; // request context } SRpcConn; -static pthread_once_t tsRpcInitOnce = PTHREAD_ONCE_INIT; - -int tsRpcMaxUdpSize = 15000; // bytes -int tsProgressTimer = 100; -// not configurable -int tsRpcMaxRetry; -int tsRpcHeadSize; -int tsRpcOverhead; - static int tsRpcRefId = -1; static int32_t tsRpcNum = 0; // static pthread_once_t tsRpcInit = PTHREAD_ONCE_INIT; @@ -442,7 +235,8 @@ void *rpcOpen(const SRpcInit *pInit) { pRpc = (SRpcInfo *)calloc(1, sizeof(SRpcInfo)); if (pRpc == NULL) return NULL; - if (pInit->label) tstrncpy(pRpc->label, pInit->label, sizeof(pRpc->label)); + if (pInit->label) tstrncpy(pRpc->label, pInit->label, strlen(pInit->label)); + pRpc->connType = pInit->connType; if (pRpc->connType == TAOS_CONN_CLIENT) { pRpc->numOfThreads = pInit->numOfThreads; diff --git a/source/libs/transport/src/rpcTcp.c b/source/libs/transport/src/rpcTcp.c index 9fa51a6fdce38072a008b1203ccfa0da88802d78..56dd8cce2512eca08e62a3f6d393253e86612c29 100644 --- a/source/libs/transport/src/rpcTcp.c +++ b/source/libs/transport/src/rpcTcp.c @@ -14,9 +14,6 @@ */ #include "rpcTcp.h" -#ifdef USE_UV -#include -#endif #include "os.h" #include "rpcHead.h" #include "rpcLog.h" @@ -24,9 +21,6 @@ #include "taoserror.h" #include "tutil.h" -#ifdef USE_UV - -#else typedef struct SFdObj { void * signature; SOCKET fd; // TCP socket FD @@ -413,8 +407,11 @@ void *taosOpenTcpClientConnection(void *shandle, void *thandle, uint32_t ip, uin pFdObj->thandle = thandle; pFdObj->port = port; pFdObj->ip = ip; - tDebug("%s %p TCP connection to 0x%x:%hu is created, localPort:%hu FD:%p numOfFds:%d", pThreadObj->label, thandle, - ip, port, localPort, pFdObj, pThreadObj->numOfFds); + + char ipport[40] = {0}; + taosIpPort2String(ip, port, ipport); + tDebug("%s %p TCP connection to %s is created, localPort:%hu FD:%p numOfFds:%d", pThreadObj->label, thandle, + ipport, localPort, pFdObj, pThreadObj->numOfFds); } else { tError("%s failed to malloc client FdObj(%s)", pThreadObj->label, strerror(errno)); taosCloseSocket(fd); @@ -662,5 +659,3 @@ static void taosFreeFdObj(SFdObj *pFdObj) { tfree(pFdObj); } - -#endif diff --git a/source/libs/transport/src/rpcUdp.c b/source/libs/transport/src/rpcUdp.c index 79956cc98db038c6e6e06a06fdbd7cb947c4ecef..b57cf57c55b5a0ae4ddb60f2883e8524bebb960d 100644 --- a/source/libs/transport/src/rpcUdp.c +++ b/source/libs/transport/src/rpcUdp.c @@ -22,9 +22,6 @@ #include "ttimer.h" #include "tutil.h" -#ifdef USE_UV -// no support upd currently -#else #define RPC_MAX_UDP_CONNS 256 #define RPC_MAX_UDP_PKTS 1000 #define RPC_UDP_BUF_TIME 5 // mseconds @@ -260,4 +257,3 @@ int taosSendUdpData(uint32_t ip, uint16_t port, void *data, int dataLen, void *c return ret; } -#endif diff --git a/source/libs/transport/src/transport.c b/source/libs/transport/src/transport.c index f2f48bbc8a69a022d0fc6b8a88c5a9a55d0b4ad6..93bbaf282002842a7344dbf650ec856ace42eff0 100644 --- a/source/libs/transport/src/transport.c +++ b/source/libs/transport/src/transport.c @@ -12,3 +12,735 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ + +#ifdef USE_UV + +#include +#include "lz4.h" +#include "os.h" +#include "rpcCache.h" +#include "rpcHead.h" +#include "rpcLog.h" +#include "rpcTcp.h" +#include "rpcUdp.h" +#include "taoserror.h" +#include "tglobal.h" +#include "thash.h" +#include "tidpool.h" +#include "tmd5.h" +#include "tmempool.h" +#include "tmsg.h" +#include "transportInt.h" +#include "tref.h" +#include "trpc.h" +#include "ttimer.h" +#include "tutil.h" + +#define container_of(ptr, type, member) ((type*)((char*)(ptr)-offsetof(type, member))) +#define RPC_RESERVE_SIZE (sizeof(SRpcReqContext)) +static const char* notify = "a"; + +typedef struct { + int sessions; // number of sessions allowed + int numOfThreads; // number of threads to process incoming messages + int idleTime; // milliseconds; + uint16_t localPort; + int8_t connType; + int index; // for UDP server only, round robin for multiple threads + char label[TSDB_LABEL_LEN]; + + char user[TSDB_UNI_LEN]; // meter ID + char spi; // security parameter index + char encrypt; // encrypt algorithm + char secret[TSDB_PASSWORD_LEN]; // secret for the link + char ckey[TSDB_PASSWORD_LEN]; // ciphering key + + void (*cfp)(void* parent, SRpcMsg*, SEpSet*); + int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey); + + int32_t refCount; + void* parent; + void* idPool; // handle to ID pool + void* tmrCtrl; // handle to timer + SHashObj* hash; // handle returned by hash utility + void* tcphandle; // returned handle from TCP initialization + void* udphandle; // returned handle from UDP initialization + void* pCache; // connection cache + pthread_mutex_t mutex; + struct SRpcConn* connList; // connection list +} SRpcInfo; + +typedef struct { + SRpcInfo* pRpc; // associated SRpcInfo + SEpSet epSet; // ip list provided by app + void* ahandle; // handle provided by app + struct SRpcConn* pConn; // pConn allocated + tmsg_t msgType; // message type + uint8_t* pCont; // content provided by app + int32_t contLen; // content length + int32_t code; // error code + int16_t numOfTry; // number of try for different servers + int8_t oldInUse; // server EP inUse passed by app + int8_t redirect; // flag to indicate redirect + int8_t connType; // connection type + int64_t rid; // refId returned by taosAddRef + SRpcMsg* pRsp; // for synchronous API + tsem_t* pSem; // for synchronous API + SEpSet* pSet; // for synchronous API + char msg[0]; // RpcHead starts from here +} SRpcReqContext; + +typedef struct SThreadObj { + pthread_t thread; + uv_pipe_t* pipe; + int fd; + uv_loop_t* loop; + uv_async_t* workerAsync; // + queue conn; + pthread_mutex_t connMtx; + void* shandle; +} SThreadObj; + +#define RPC_MSG_OVERHEAD (sizeof(SRpcReqContext) + sizeof(SRpcHead) + sizeof(SRpcDigest)) +#define rpcHeadFromCont(cont) ((SRpcHead*)((char*)cont - sizeof(SRpcHead))) +#define rpcContFromHead(msg) (msg + sizeof(SRpcHead)) +#define rpcMsgLenFromCont(contLen) (contLen + sizeof(SRpcHead)) +#define rpcContLenFromMsg(msgLen) (msgLen - sizeof(SRpcHead)) +#define rpcIsReq(type) (type & 1U) + +typedef struct SServerObj { + pthread_t thread; + uv_tcp_t server; + uv_loop_t* loop; + int workerIdx; + int numOfThread; + SThreadObj** pThreadObj; + uv_pipe_t** pipe; + uint32_t ip; + uint32_t port; +} SServerObj; + +typedef struct SConnBuffer { + char* buf; + int len; + int cap; + int left; +} SConnBuffer; + +typedef struct SRpcConn { + uv_tcp_t* pTcp; + uv_write_t* pWriter; + uv_timer_t* pTimer; + + uv_async_t* pWorkerAsync; + queue queue; + int ref; + int persist; // persist connection or not + SConnBuffer connBuf; // read buf, + SConnBuffer writeBuf; // write buf + int count; + void* shandle; // rpc init + void* ahandle; // + void* hostThread; + // del later + char secured; + int spi; + char info[64]; + char user[TSDB_UNI_LEN]; // user ID for the link + char secret[TSDB_PASSWORD_LEN]; + char ckey[TSDB_PASSWORD_LEN]; // ciphering key +} SRpcConn; + +// auth function +static int uvAuthMsg(SRpcConn* pConn, char* msg, int msgLen); +static int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey); +static void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey); +static int rpcAddAuthPart(SRpcConn* pConn, char* msg, int msgLen); +// compress data +static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen); +static SRpcHead* rpcDecompressRpcMsg(SRpcHead* pHead); + +static void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf); +static void uvOnTimeoutCb(uv_timer_t* handle); +static void uvOnWriteCb(uv_write_t* req, int status); +static void uvOnAcceptCb(uv_stream_t* stream, int status); +static void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf); +static void uvWorkerAsyncCb(uv_async_t* handle); + +static SRpcConn* connCreate(); +static void connDestroy(SRpcConn* conn); +static void uvConnDestroy(uv_handle_t* handle); + +static void* workerThread(void* arg); +static void* acceptThread(void* arg); + +void* taosInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle); +void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle); + +void* taosInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, void* fp, void* shandle) { + SServerObj* srv = calloc(1, sizeof(SServerObj)); + srv->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); + srv->numOfThread = numOfThreads; + srv->workerIdx = 0; + srv->pThreadObj = (SThreadObj**)calloc(srv->numOfThread, sizeof(SThreadObj*)); + srv->pipe = (uv_pipe_t**)calloc(srv->numOfThread, sizeof(uv_pipe_t*)); + srv->ip = ip; + srv->port = port; + uv_loop_init(srv->loop); + + for (int i = 0; i < srv->numOfThread; i++) { + SThreadObj* thrd = (SThreadObj*)calloc(1, sizeof(SThreadObj)); + srv->pipe[i] = (uv_pipe_t*)calloc(2, sizeof(uv_pipe_t)); + int fds[2]; + if (uv_socketpair(AF_UNIX, SOCK_STREAM, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE) != 0) { + return NULL; + } + uv_pipe_init(srv->loop, &(srv->pipe[i][0]), 1); + uv_pipe_open(&(srv->pipe[i][0]), fds[1]); // init write + + thrd->shandle = shandle; + thrd->fd = fds[0]; + thrd->pipe = &(srv->pipe[i][1]); // init read + int err = pthread_create(&(thrd->thread), NULL, workerThread, (void*)(thrd)); + if (err == 0) { + tDebug("sucess to create worker-thread %d", i); + // printf("thread %d create\n", i); + } else { + // TODO: clear all other resource later + tError("failed to create worker-thread %d", i); + } + srv->pThreadObj[i] = thrd; + } + + int err = pthread_create(&srv->thread, NULL, acceptThread, (void*)srv); + if (err == 0) { + tDebug("success to create accept-thread"); + } else { + // clear all resource later + } + + return srv; +} +void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { + /* + * formate of data buffer: + * |<-------SRpcReqContext------->|<------------data read from socket----------->| + */ + static const int CAPACITY = 1024; + + SRpcConn* ctx = handle->data; + SConnBuffer* pBuf = &ctx->connBuf; + if (pBuf->cap == 0) { + pBuf->buf = (char*)calloc(CAPACITY + RPC_RESERVE_SIZE, sizeof(char)); + pBuf->len = 0; + pBuf->cap = CAPACITY; + pBuf->left = -1; + + buf->base = pBuf->buf + RPC_RESERVE_SIZE; + buf->len = CAPACITY; + } else { + if (pBuf->len >= pBuf->cap) { + if (pBuf->left == -1) { + pBuf->cap *= 2; + pBuf->buf = realloc(pBuf->buf, pBuf->cap + RPC_RESERVE_SIZE); + } else if (pBuf->len + pBuf->left > pBuf->cap) { + pBuf->cap = pBuf->len + pBuf->left; + pBuf->buf = realloc(pBuf->buf, pBuf->len + pBuf->left + RPC_RESERVE_SIZE); + } + } + buf->base = pBuf->buf + pBuf->len + RPC_RESERVE_SIZE; + buf->len = pBuf->cap - pBuf->len; + } +} +// check data read from socket completely or not +// +static bool isReadAll(SConnBuffer* data) { + // TODO(yihao): handle pipeline later + SRpcHead rpcHead; + int32_t headLen = sizeof(rpcHead); + if (data->len >= headLen) { + memcpy((char*)&rpcHead, data->buf + RPC_RESERVE_SIZE, headLen); + int32_t msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen); + if (msgLen > data->len) { + data->left = msgLen - data->len; + return false; + } else { + return true; + } + } else { + return false; + } +} +static void uvDoProcess(SRecvInfo* pRecv) { + SRpcHead* pHead = (SRpcHead*)pRecv->msg; + SRpcInfo* pRpc = (SRpcInfo*)pRecv->shandle; + SRpcConn* pConn = pRecv->thandle; + + tDump(pRecv->msg, pRecv->msgLen); + + terrno = 0; + SRpcReqContext* pContest; + + // do auth and check +} +static int uvAuthMsg(SRpcConn* pConn, char* msg, int len) { + SRpcHead* pHead = (SRpcHead*)msg; + int code = 0; + + if ((pConn->secured && pHead->spi == 0) || (pHead->spi == 0 && pConn->spi == 0)) { + // secured link, or no authentication + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); + // tTrace("%s, secured link, no auth is required", pConn->info); + return 0; + } + + if (!rpcIsReq(pHead->msgType)) { + // for response, if code is auth failure, it shall bypass the auth process + code = htonl(pHead->code); + if (code == TSDB_CODE_RPC_INVALID_TIME_STAMP || code == TSDB_CODE_RPC_AUTH_FAILURE || + code == TSDB_CODE_RPC_INVALID_VERSION || code == TSDB_CODE_RPC_AUTH_REQUIRED || + code == TSDB_CODE_MND_USER_NOT_EXIST || code == TSDB_CODE_RPC_NOT_READY) { + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen); + // tTrace("%s, dont check authentication since code is:0x%x", pConn->info, code); + return 0; + } + } + + code = 0; + if (pHead->spi == pConn->spi) { + // authentication + SRpcDigest* pDigest = (SRpcDigest*)((char*)pHead + len - sizeof(SRpcDigest)); + + int32_t delta; + delta = (int32_t)htonl(pDigest->timeStamp); + delta -= (int32_t)taosGetTimestampSec(); + if (abs(delta) > 900) { + tWarn("%s, time diff:%d is too big, msg discarded", pConn->info, delta); + code = TSDB_CODE_RPC_INVALID_TIME_STAMP; + } else { + if (rpcAuthenticateMsg(pHead, len - TSDB_AUTH_LEN, pDigest->auth, pConn->secret) < 0) { + // tDebug("%s, authentication failed, msg discarded", pConn->info); + code = TSDB_CODE_RPC_AUTH_FAILURE; + } else { + pHead->msgLen = (int32_t)htonl((uint32_t)pHead->msgLen) - sizeof(SRpcDigest); + if (!rpcIsReq(pHead->msgType)) pConn->secured = 1; // link is secured for client + // tTrace("%s, message is authenticated", pConn->info); + } + } + } else { + tDebug("%s, auth spi:%d not matched with received:%d", pConn->info, pConn->spi, pHead->spi); + code = pHead->spi ? TSDB_CODE_RPC_AUTH_FAILURE : TSDB_CODE_RPC_AUTH_REQUIRED; + } + + return code; +} +// refers specifically to query or insert timeout +static void uvHandleActivityTimeout(uv_timer_t* handle) { + // impl later + SRpcConn* conn = handle->data; +} +static void uvProcessData(SRpcConn* pConn) { + SRecvInfo info; + SRecvInfo* p = &info; + SConnBuffer* pBuf = &pConn->connBuf; + p->msg = pBuf->buf + RPC_RESERVE_SIZE; + p->msgLen = pBuf->len; + p->ip = 0; + p->port = 0; + p->shandle = pConn->shandle; // + p->thandle = pConn; + p->chandle = NULL; + + // + SRpcHead* pHead = (SRpcHead*)p->msg; + assert(rpcIsReq(pHead->msgType)); + + SRpcInfo* pRpc = (SRpcInfo*)p->shandle; + pConn->ahandle = (void*)pHead->ahandle; + // auth here + + int8_t code = uvAuthMsg(pConn, (char*)pHead, p->msgLen); + if (code != 0) { + terrno = code; + return; + } + pHead->code = htonl(pHead->code); + + SRpcMsg rpcMsg; + + pHead = rpcDecompressRpcMsg(pHead); + rpcMsg.contLen = rpcContLenFromMsg(pHead->msgLen); + rpcMsg.pCont = pHead->content; + rpcMsg.msgType = pHead->msgType; + rpcMsg.code = pHead->code; + rpcMsg.ahandle = pConn->ahandle; + rpcMsg.handle = pConn; + + (*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL); + uv_timer_start(pConn->pTimer, uvHandleActivityTimeout, pRpc->idleTime, 0); + // auth + // validate msg type +} +void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { + // opt + SRpcConn* ctx = cli->data; + SConnBuffer* pBuf = &ctx->connBuf; + if (nread > 0) { + pBuf->len += nread; + if (isReadAll(pBuf)) { + tDebug("alread read complete packet"); + uvProcessData(ctx); + } else { + tDebug("read half packet, continue to read"); + } + return; + } + if (terrno != 0) { + // handle err code + } + + if (nread != UV_EOF) { + tDebug("Read error %s\n", uv_err_name(nread)); + } + uv_close((uv_handle_t*)cli, uvConnDestroy); +} +void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { + buf->base = malloc(sizeof(char)); + buf->len = 2; +} + +void uvOnTimeoutCb(uv_timer_t* handle) { + // opt + tDebug("time out"); +} + +void uvOnWriteCb(uv_write_t* req, int status) { + SRpcConn* conn = req->data; + if (status == 0) { + tDebug("data already was written on stream"); + } else { + connDestroy(conn); + } + // opt +} + +void uvWorkerAsyncCb(uv_async_t* handle) { + SThreadObj* pThrd = container_of(handle, SThreadObj, workerAsync); + SRpcConn* conn = NULL; + + // opt later + pthread_mutex_lock(&pThrd->connMtx); + if (!QUEUE_IS_EMPTY(&pThrd->conn)) { + queue* head = QUEUE_HEAD(&pThrd->conn); + conn = QUEUE_DATA(head, SRpcConn, queue); + QUEUE_REMOVE(&conn->queue); + } + pthread_mutex_unlock(&pThrd->connMtx); + if (conn == NULL) { + tError("except occurred, do nothing"); + return; + } + uv_buf_t wb = uv_buf_init(conn->writeBuf.buf, conn->writeBuf.len); + uv_write(conn->pWriter, (uv_stream_t*)conn->pTcp, &wb, 1, uvOnWriteCb); +} + +void uvOnAcceptCb(uv_stream_t* stream, int status) { + if (status == -1) { + return; + } + SServerObj* pObj = container_of(stream, SServerObj, server); + + uv_tcp_t* cli = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); + uv_tcp_init(pObj->loop, cli); + + if (uv_accept(stream, (uv_stream_t*)cli) == 0) { + uv_write_t* wr = (uv_write_t*)malloc(sizeof(uv_write_t)); + + uv_buf_t buf = uv_buf_init((char*)notify, strlen(notify)); + + pObj->workerIdx = (pObj->workerIdx + 1) % pObj->numOfThread; + tDebug("new conntion accepted by main server, dispatch to %dth worker-thread", pObj->workerIdx); + uv_write2(wr, (uv_stream_t*)&(pObj->pipe[pObj->workerIdx][0]), &buf, 1, (uv_stream_t*)cli, uvOnWriteCb); + } else { + uv_close((uv_handle_t*)cli, NULL); + } +} +void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { + tDebug("connection coming"); + if (nread < 0) { + if (nread != UV_EOF) { + tError("read error %s", uv_err_name(nread)); + } + // TODO(log other failure reason) + uv_close((uv_handle_t*)q, NULL); + return; + } + // free memory allocated by + assert(nread == strlen(notify)); + assert(buf->base[0] == notify[0]); + free(buf->base); + + SThreadObj* pThrd = q->data; + + uv_pipe_t* pipe = (uv_pipe_t*)q; + if (!uv_pipe_pending_count(pipe)) { + tError("No pending count"); + return; + } + + uv_handle_type pending = uv_pipe_pending_type(pipe); + assert(pending == UV_TCP); + + SRpcConn* pConn = connCreate(); + pConn->shandle = pThrd->shandle; + /* init conn timer*/ + pConn->pTimer = malloc(sizeof(uv_timer_t)); + uv_timer_init(pThrd->loop, pConn->pTimer); + pConn->pTimer->data = pConn; + + pConn->hostThread = pThrd; + pConn->pWorkerAsync = pThrd->workerAsync; // thread safty + + // init client handle + pConn->pTcp = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); + uv_tcp_init(pThrd->loop, pConn->pTcp); + pConn->pTcp->data = pConn; + + // init write request, just + pConn->pWriter = calloc(1, sizeof(uv_write_t)); + pConn->pWriter->data = pConn; + + if (uv_accept(q, (uv_stream_t*)(pConn->pTcp)) == 0) { + uv_os_fd_t fd; + uv_fileno((const uv_handle_t*)pConn->pTcp, &fd); + tDebug("new connection created: %d", fd); + uv_read_start((uv_stream_t*)(pConn->pTcp), uvAllocReadBufferCb, uvOnReadCb); + } else { + connDestroy(pConn); + } +} + +void* acceptThread(void* arg) { + // opt + SServerObj* srv = (SServerObj*)arg; + uv_tcp_init(srv->loop, &srv->server); + + struct sockaddr_in bind_addr; + + uv_ip4_addr("0.0.0.0", srv->port, &bind_addr); + uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 0); + int err = 0; + if ((err = uv_listen((uv_stream_t*)&srv->server, 128, uvOnAcceptCb)) != 0) { + tError("Listen error %s\n", uv_err_name(err)); + return NULL; + } + uv_run(srv->loop, UV_RUN_DEFAULT); +} +void* workerThread(void* arg) { + SThreadObj* pThrd = (SThreadObj*)arg; + + pThrd->loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); + uv_loop_init(pThrd->loop); + + uv_pipe_init(pThrd->loop, pThrd->pipe, 1); + uv_pipe_open(pThrd->pipe, pThrd->fd); + + pThrd->pipe->data = pThrd; + + QUEUE_INIT(&pThrd->conn); + + pThrd->workerAsync = malloc(sizeof(uv_async_t)); + uv_async_init(pThrd->loop, pThrd->workerAsync, uvWorkerAsyncCb); + + uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb); + uv_run(pThrd->loop, UV_RUN_DEFAULT); +} +static SRpcConn* connCreate() { + SRpcConn* pConn = (SRpcConn*)calloc(1, sizeof(SRpcConn)); + return pConn; +} +static void connDestroy(SRpcConn* conn) { + if (conn == NULL) { + return; + } + uv_timer_stop(conn->pTimer); + free(conn->pTimer); + uv_close((uv_handle_t*)conn->pTcp, NULL); + free(conn->connBuf.buf); + free(conn->pTcp); + free(conn->pWriter); + free(conn); + // handle +} +static void uvConnDestroy(uv_handle_t* handle) { + SRpcConn* conn = handle->data; + connDestroy(conn); +} +void* rpcOpen(const SRpcInit* pInit) { + SRpcInfo* pRpc = calloc(1, sizeof(SRpcInfo)); + if (pRpc == NULL) { + return NULL; + } + if (pInit->label) { + tstrncpy(pRpc->label, pInit->label, strlen(pInit->label)); + } + pRpc->numOfThreads = pInit->numOfThreads > TSDB_MAX_RPC_THREADS ? TSDB_MAX_RPC_THREADS : pInit->numOfThreads; + pRpc->tcphandle = taosInitServer(0, pInit->localPort, pRpc->label, pRpc->numOfThreads, NULL, pRpc); + return pRpc; +} +void rpcClose(void* arg) { return; } +void* rpcMallocCont(int contLen) { return NULL; } +void rpcFreeCont(void* cont) { return; } +void* rpcReallocCont(void* ptr, int contLen) { return NULL; } + +void rpcSendRequest(void* thandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* rid) { + // impl later + return; +} + +void rpcSendResponse(const SRpcMsg* pMsg) { + SRpcConn* pConn = pMsg->handle; + SThreadObj* pThrd = pConn->hostThread; + + // opt later + pthread_mutex_lock(&pThrd->connMtx); + QUEUE_PUSH(&pThrd->conn, &pConn->queue); + pthread_mutex_unlock(&pThrd->connMtx); + + uv_async_send(pConn->pWorkerAsync); +} + +void rpcSendRedirectRsp(void* pConn, const SEpSet* pEpSet) {} +int rpcGetConnInfo(void* thandle, SRpcConnInfo* pInfo) { return -1; } +void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pReq, SRpcMsg* pRsp) { return; } +int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; } +void rpcCancelRequest(int64_t rid) { return; } + +static int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey) { + T_MD5_CTX context; + int ret = -1; + + tMD5Init(&context); + tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); + tMD5Update(&context, (uint8_t*)pMsg, msgLen); + tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); + tMD5Final(&context); + + if (memcmp(context.digest, pAuth, sizeof(context.digest)) == 0) ret = 0; + + return ret; +} +static void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey) { + T_MD5_CTX context; + + tMD5Init(&context); + tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); + tMD5Update(&context, (uint8_t*)pMsg, msgLen); + tMD5Update(&context, (uint8_t*)pKey, TSDB_PASSWORD_LEN); + tMD5Final(&context); + + memcpy(pAuth, context.digest, sizeof(context.digest)); +} + +static int rpcAddAuthPart(SRpcConn* pConn, char* msg, int msgLen) { + SRpcHead* pHead = (SRpcHead*)msg; + + if (pConn->spi && pConn->secured == 0) { + // add auth part + pHead->spi = pConn->spi; + SRpcDigest* pDigest = (SRpcDigest*)(msg + msgLen); + pDigest->timeStamp = htonl(taosGetTimestampSec()); + msgLen += sizeof(SRpcDigest); + pHead->msgLen = (int32_t)htonl((uint32_t)msgLen); + rpcBuildAuthHead(pHead, msgLen - TSDB_AUTH_LEN, pDigest->auth, pConn->secret); + } else { + pHead->spi = 0; + pHead->msgLen = (int32_t)htonl((uint32_t)msgLen); + } + + return msgLen; +} + +static int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen) { + SRpcHead* pHead = rpcHeadFromCont(pCont); + int32_t finalLen = 0; + int overhead = sizeof(SRpcComp); + + if (!NEEDTO_COMPRESSS_MSG(contLen)) { + return contLen; + } + + char* buf = malloc(contLen + overhead + 8); // 8 extra bytes + if (buf == NULL) { + tError("failed to allocate memory for rpc msg compression, contLen:%d", contLen); + return contLen; + } + + int32_t compLen = LZ4_compress_default(pCont, buf, contLen, contLen + overhead); + tDebug("compress rpc msg, before:%d, after:%d, overhead:%d", contLen, compLen, overhead); + + /* + * only the compressed size is less than the value of contLen - overhead, the compression is applied + * The first four bytes is set to 0, the second four bytes are utilized to keep the original length of message + */ + if (compLen > 0 && compLen < contLen - overhead) { + SRpcComp* pComp = (SRpcComp*)pCont; + pComp->reserved = 0; + pComp->contLen = htonl(contLen); + memcpy(pCont + overhead, buf, compLen); + + pHead->comp = 1; + tDebug("compress rpc msg, before:%d, after:%d", contLen, compLen); + finalLen = compLen + overhead; + } else { + finalLen = contLen; + } + + free(buf); + return finalLen; +} + +static SRpcHead* rpcDecompressRpcMsg(SRpcHead* pHead) { + int overhead = sizeof(SRpcComp); + SRpcHead* pNewHead = NULL; + uint8_t* pCont = pHead->content; + SRpcComp* pComp = (SRpcComp*)pHead->content; + + if (pHead->comp) { + // decompress the content + assert(pComp->reserved == 0); + int contLen = htonl(pComp->contLen); + + // prepare the temporary buffer to decompress message + char* temp = (char*)malloc(contLen + RPC_MSG_OVERHEAD); + pNewHead = (SRpcHead*)(temp + sizeof(SRpcReqContext)); // reserve SRpcReqContext + + if (pNewHead) { + int compLen = rpcContLenFromMsg(pHead->msgLen) - overhead; + int origLen = LZ4_decompress_safe((char*)(pCont + overhead), (char*)pNewHead->content, compLen, contLen); + assert(origLen == contLen); + + memcpy(pNewHead, pHead, sizeof(SRpcHead)); + pNewHead->msgLen = rpcMsgLenFromCont(origLen); + /// rpcFreeMsg(pHead); // free the compressed message buffer + pHead = pNewHead; + tTrace("decomp malloc mem:%p", temp); + } else { + tError("failed to allocate memory to decompress msg, contLen:%d", contLen); + } + } + + return pHead; +} +int32_t rpcInit(void) { + // impl later + return -1; +} + +void rpcCleanup(void) { + // impl later + return; +} +#endif diff --git a/source/libs/transport/test/CMakeLists.txt b/source/libs/transport/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9e58bf08cdeb27ed6f6c6a187fc156bd586dd2a4 --- /dev/null +++ b/source/libs/transport/test/CMakeLists.txt @@ -0,0 +1,21 @@ +add_executable(transportTest "") +target_sources(transportTest + PRIVATE + "transportTests.cc" +) + +target_include_directories(transportTest + PUBLIC + "${CMAKE_SOURCE_DIR}/include/libs/transport" + "${CMAKE_CURRENT_SOURCE_DIR}/../inc" +) + +target_link_libraries (transportTest + os + util + common + gtest_main + transport +) + + diff --git a/source/dnode/vnode/src/inc/metaIdx.h b/source/libs/transport/test/transportTests.cc similarity index 53% rename from source/dnode/vnode/src/inc/metaIdx.h rename to source/libs/transport/test/transportTests.cc index b6afc4cc97f021b4167ddf42531b6330dba1fbf8..468aeba8a9adad92d730bc251b3416eddea7e60f 100644 --- a/source/dnode/vnode/src/inc/metaIdx.h +++ b/source/libs/transport/test/transportTests.cc @@ -2,8 +2,8 @@ * 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. + * 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 @@ -13,24 +13,23 @@ * along with this program. If not, see . */ -#ifndef _TD_META_IDX_H_ -#define _TD_META_IDX_H_ +#include +#include +#include +#include +#include -#include "meta.h" +#include "transportInt.h" +#include "trpc.h" -#ifdef __cplusplus -extern "C" { -#endif +using namespace std; -typedef struct SMetaIdx SMetaIdx; +int main() { + SRpcInit init = {.localPort = 6030, .label = "rpc", .numOfThreads = 5}; + void* p = rpcOpen(&init); -int metaOpenIdx(SMeta *pMeta); -void metaCloseIdx(SMeta *pMeta); -int metaSaveTableToIdx(SMeta *pMeta, const STbCfg *pTbOptions); -int metaRemoveTableFromIdx(SMeta *pMeta, tb_uid_t uid); - -#ifdef __cplusplus + while (1) { + std::cout << "cron task" << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(10 * 1000)); + } } -#endif - -#endif /*_TD_META_IDX_H_*/ \ No newline at end of file diff --git a/source/libs/transport/test/transportTests.cpp b/source/libs/transport/test/transportTests.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index cac80c0a5f578da85b1256cc0b6d4a5ec9687c7d..d63008008697b8d10c3ae0e4f0cb0e587bbb4e6d 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -36,7 +36,7 @@ void* tmemmem(char* haystack, int hlen, char* needle, int nlen) { char* limit; if (nlen == 0 || hlen < nlen) { - return false; + return NULL; } limit = haystack + hlen - nlen + 1; @@ -54,10 +54,12 @@ static inline int64_t walScanLogGetLastVer(SWal* pWal) { ASSERT(pWal->fileInfoSet != NULL); int sz = taosArrayGetSize(pWal->fileInfoSet); ASSERT(sz > 0); +#if 0 for (int i = 0; i < sz; i++) { SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, i); - } +#endif + SWalFileInfo *pLastFileInfo = taosArrayGet(pWal->fileInfoSet, sz-1); char fnameStr[WAL_FILE_LEN]; walBuildLogName(pWal, pLastFileInfo->firstVer, fnameStr); @@ -143,8 +145,6 @@ int walCheckAndRepairMeta(SWal* pWal) { SWalFileInfo fileInfo; memset(&fileInfo, -1, sizeof(SWalFileInfo)); sscanf(name, "%" PRId64 ".log", &fileInfo.firstVer); - //get lastVer - //get size taosArrayPush(pLogInfoArray, &fileInfo); } } @@ -158,60 +158,51 @@ int walCheckAndRepairMeta(SWal* pWal) { oldSz = taosArrayGetSize(pWal->fileInfoSet); } int newSz = taosArrayGetSize(pLogInfoArray); - // case 1. meta file not exist / cannot be parsed - if (oldSz < newSz) { + + if (oldSz > newSz) { + taosArrayPopFrontBatch(pWal->fileInfoSet, oldSz - newSz); + } else if (oldSz < newSz) { for (int i = oldSz; i < newSz; i++) { SWalFileInfo *pFileInfo = taosArrayGet(pLogInfoArray, i); taosArrayPush(pWal->fileInfoSet, pFileInfo); } - - pWal->writeCur = newSz - 1; - pWal->vers.firstVer = ((SWalFileInfo*)taosArrayGet(pLogInfoArray, 0))->firstVer; - pWal->vers.lastVer = walScanLogGetLastVer(pWal); - ((SWalFileInfo*)taosArrayGetLast(pWal->fileInfoSet))->lastVer = pWal->vers.lastVer; - ASSERT(pWal->vers.lastVer != -1); - - int code = walSaveMeta(pWal); - if (code < 0) { - taosArrayDestroy(pLogInfoArray); - return -1; - } } - - // case 2. versions in meta not match log - // or some log not included in meta - // (e.g. program killed) - // - // case 3. other corrupt cases - // -#if 0 - int sz = taosArrayGetSize(pLogInfoArray); - for (int i = 0; i < sz; i++) { - SWalFileInfo* pFileInfo = taosArrayGet(pLogInfoArray, i); - if (i == 0 && pFileInfo->firstVer != walGetFirstVer(pWal)) { - //repair - } - - if (i > 0) { - SWalFileInfo* pLastFileInfo = taosArrayGet(pLogInfoArray, i-1); - if (pLastFileInfo->lastVer != pFileInfo->firstVer) { + taosArrayDestroy(pLogInfoArray); + pWal->writeCur = newSz - 1; + if (newSz > 0) { + pWal->vers.firstVer = ((SWalFileInfo*)taosArrayGet(pWal->fileInfoSet, 0))->firstVer; + + SWalFileInfo *pLastFileInfo = taosArrayGet(pWal->fileInfoSet, newSz-1); + char fnameStr[WAL_FILE_LEN]; + walBuildLogName(pWal, pLastFileInfo->firstVer, fnameStr); + struct stat statbuf; + stat(fnameStr, &statbuf); + + if (oldSz != newSz || pLastFileInfo->fileSize != statbuf.st_size) { + pLastFileInfo->fileSize = statbuf.st_size; + pWal->vers.lastVer = walScanLogGetLastVer(pWal); + ((SWalFileInfo*)taosArrayGetLast(pWal->fileInfoSet))->lastVer = pWal->vers.lastVer; + ASSERT(pWal->vers.lastVer != -1); + + int code = walSaveMeta(pWal); + if (code < 0) { + taosArrayDestroy(pLogInfoArray); + return -1; } } } -#endif - - // get last version of this file - // - // rebuild meta - taosArrayDestroy(pLogInfoArray); + //TODO: set fileSize and lastVer if necessary + return 0; } int walCheckAndRepairIdx(SWal* pWal) { - // iterate all idx files - // check first and last entry of each idx file valid + // TODO: iterate all log files + // if idx not found, scan log and write idx + // if found, check complete by first and last entry of each idx file + // if idx incomplete, binary search last valid entry, and then build other part return 0; } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 5b387ffa46b2792f5b681533ae9ad377a1af61d8..144de08cd0a83ad90ba9f9368b726276cd0a91d9 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -301,12 +301,13 @@ 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_UPDATING, "Database is updating") +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") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_SYNCING, "Database is syncing") TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_TSDB_STATE, "Invalid tsdb state") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_TB_NOT_EXIST, "Table not exists") // tsdb TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, "Invalid table ID") diff --git a/tests/test/c/create_table.c b/tests/test/c/create_table.c index aae4dc7074895eb5c1143058169d1e6362a8f7a4..0376ab70ad1bc0d0bb62d977773ad1566491a6d8 100644 --- a/tests/test/c/create_table.c +++ b/tests/test/c/create_table.c @@ -187,13 +187,19 @@ void *threadFunc(void *param) { int64_t curMs = 0; int64_t beginMs = taosGetTimestampMs(); pInfo->startMs = beginMs; - for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) { - int64_t batch = (pInfo->tableEndIndex - t); - batch = MIN(batch, batchNum); + int64_t t = pInfo->tableBeginIndex; + for (; t <= pInfo->tableEndIndex;) { + //int64_t batch = (pInfo->tableEndIndex - t); + //batch = MIN(batch, batchNum); int32_t len = sprintf(qstr, "create table"); - for (int32_t i = 0; i < batch; ++i) { - len += sprintf(qstr + len, " t%" PRId64 " using %s tags(%" PRId64 ")", t + i, stbName, t + i); + for (int32_t i = 0; i < batchNum;) { + len += sprintf(qstr + len, " %s_t%" PRId64 " using %s tags(%" PRId64 ")", stbName, t, stbName, t); + t++; + i++; + if (t > pInfo->tableEndIndex) { + break; + } } int64_t startTs = taosGetTimestampUs(); @@ -212,11 +218,11 @@ void *threadFunc(void *param) { curMs = taosGetTimestampMs(); if (curMs - beginMs > 10000) { beginMs = curMs; + //printf("==== tableBeginIndex: %"PRId64", t: %"PRId64"\n", pInfo->tableBeginIndex, t); printCreateProgress(pInfo, t); } - t += (batch - 1); } - printCreateProgress(pInfo, pInfo->tableEndIndex); + printCreateProgress(pInfo, t); } if (insertData) {