Merge branch '3.0' into feature/TD-14481-3.0

This commit is contained in:
Cary Xu 2022-04-29 18:41:33 +08:00 committed by GitHub
commit da4f86f368
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
126 changed files with 6111 additions and 2822 deletions

View File

@ -14,7 +14,9 @@
*/ */
#include <assert.h> #include <assert.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "taos.h" #include "taos.h"
@ -24,7 +26,7 @@ static void msg_process(TAOS_RES* msg) {
char buf[1024]; char buf[1024];
memset(buf, 0, 1024); memset(buf, 0, 1024);
printf("topic: %s\n", tmq_get_topic_name(msg)); printf("topic: %s\n", tmq_get_topic_name(msg));
printf("vg:%d\n", tmq_get_vgroup_id(msg)); printf("vg: %d\n", tmq_get_vgroup_id(msg));
while (1) { while (1) {
TAOS_ROW row = taos_fetch_row(msg); TAOS_ROW row = taos_fetch_row(msg);
if (row == NULL) break; if (row == NULL) break;
@ -140,8 +142,8 @@ int32_t create_topic() {
return 0; return 0;
} }
void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets) { void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets, void* param) {
printf("commit %d\n", resp); printf("commit %d tmq %p offsets %p param %p\n", resp, tmq, offsets, param);
} }
tmq_t* build_consumer() { tmq_t* build_consumer() {
@ -161,7 +163,7 @@ tmq_t* build_consumer() {
tmq_conf_set(conf, "td.connect.user", "root"); tmq_conf_set(conf, "td.connect.user", "root");
tmq_conf_set(conf, "td.connect.pass", "taosdata"); tmq_conf_set(conf, "td.connect.pass", "taosdata");
/*tmq_conf_set(conf, "td.connect.db", "abc1");*/ /*tmq_conf_set(conf, "td.connect.db", "abc1");*/
tmq_conf_set_offset_commit_cb(conf, tmq_commit_cb_print); tmq_conf_set_offset_commit_cb(conf, tmq_commit_cb_print, NULL);
tmq_t* tmq = tmq_consumer_new(conf, NULL, 0); tmq_t* tmq = tmq_consumer_new(conf, NULL, 0);
assert(tmq); assert(tmq);
return tmq; return tmq;
@ -215,12 +217,24 @@ void sync_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
return; return;
} }
tmq_list_t* subList = NULL;
tmq_subscription(tmq, &subList);
char** subTopics = tmq_list_to_c_array(subList);
int32_t sz = tmq_list_get_size(subList);
printf("subscribed topics: ");
for (int32_t i = 0; i < sz; i++) {
printf("%s, ", subTopics[i]);
}
printf("\n");
tmq_list_destroy(subList);
while (running) { while (running) {
TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 1000); TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 1000);
if (tmqmessage) { if (tmqmessage) {
msg_process(tmqmessage); msg_process(tmqmessage);
taos_free_result(tmqmessage); taos_free_result(tmqmessage);
tmq_commit(tmq, NULL, 1);
/*if ((++msg_count % MIN_COMMIT_COUNT) == 0) tmq_commit(tmq, NULL, 0);*/ /*if ((++msg_count % MIN_COMMIT_COUNT) == 0) tmq_commit(tmq, NULL, 0);*/
} }
} }

View File

@ -213,7 +213,7 @@ typedef struct tmq_topic_vgroup_list_t tmq_topic_vgroup_list_t;
typedef struct tmq_conf_t tmq_conf_t; typedef struct tmq_conf_t tmq_conf_t;
typedef struct tmq_list_t tmq_list_t; typedef struct tmq_list_t tmq_list_t;
typedef void(tmq_commit_cb(tmq_t *, tmq_resp_err_t, tmq_topic_vgroup_list_t *)); typedef void(tmq_commit_cb(tmq_t *, tmq_resp_err_t, tmq_topic_vgroup_list_t *, void *param));
DLL_EXPORT tmq_list_t *tmq_list_new(); DLL_EXPORT tmq_list_t *tmq_list_new();
DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *);
@ -253,11 +253,11 @@ typedef enum tmq_conf_res_t tmq_conf_res_t;
DLL_EXPORT tmq_conf_t *tmq_conf_new(); DLL_EXPORT tmq_conf_t *tmq_conf_new();
DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value);
DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf);
DLL_EXPORT void tmq_conf_set_offset_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb); DLL_EXPORT void tmq_conf_set_offset_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param);
/* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */ /* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */
DLL_EXPORT char *tmq_get_topic_name(TAOS_RES *res); DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res);
DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res);
// TODO // TODO
#if 0 #if 0

View File

@ -1524,6 +1524,7 @@ typedef struct {
int32_t tEncodeSRSmaParam(SCoder* pCoder, const SRSmaParam* pRSmaParam); int32_t tEncodeSRSmaParam(SCoder* pCoder, const SRSmaParam* pRSmaParam);
int32_t tDecodeSRSmaParam(SCoder* pCoder, SRSmaParam* pRSmaParam); int32_t tDecodeSRSmaParam(SCoder* pCoder, SRSmaParam* pRSmaParam);
// TDMT_VND_CREATE_STB ==============
typedef struct SVCreateStbReq { typedef struct SVCreateStbReq {
const char* name; const char* name;
tb_uid_t suid; tb_uid_t suid;
@ -1536,17 +1537,14 @@ typedef struct SVCreateStbReq {
int tEncodeSVCreateStbReq(SCoder* pCoder, const SVCreateStbReq* pReq); int tEncodeSVCreateStbReq(SCoder* pCoder, const SVCreateStbReq* pReq);
int tDecodeSVCreateStbReq(SCoder* pCoder, SVCreateStbReq* pReq); int tDecodeSVCreateStbReq(SCoder* pCoder, SVCreateStbReq* pReq);
// TDMT_VND_DROP_STB ==============
typedef struct SVDropStbReq { typedef struct SVDropStbReq {
// data const char* name;
#ifdef WINDOWS tb_uid_t suid;
size_t avoidCompilationErrors;
#endif
} SVDropStbReq; } SVDropStbReq;
typedef struct SVCreateStbRsp { int32_t tEncodeSVDropStbReq(SCoder* pCoder, const SVDropStbReq* pReq);
int code; int32_t tDecodeSVDropStbReq(SCoder* pCoder, SVDropStbReq* pReq);
} SVCreateStbRsp;
typedef struct SVCreateTbReq { typedef struct SVCreateTbReq {
tb_uid_t uid; tb_uid_t uid;
@ -1603,19 +1601,37 @@ int tDecodeSVCreateTbBatchRsp(SCoder* pCoder, SVCreateTbBatchRsp* pRsp);
int32_t tSerializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatchRsp* pRsp); int32_t tSerializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatchRsp* pRsp);
int32_t tDeserializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatchRsp* pRsp); int32_t tDeserializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatchRsp* pRsp);
// TDMT_VND_DROP_TABLE =================
typedef struct { typedef struct {
int64_t ver; const char* name;
char* name; int8_t igNotExists;
uint8_t type;
tb_uid_t suid;
} SVDropTbReq; } SVDropTbReq;
typedef struct { typedef struct {
int tmp; // TODO: to avoid compile error int32_t code;
} SVDropTbRsp; } SVDropTbRsp;
int32_t tSerializeSVDropTbReq(void** buf, SVDropTbReq* pReq); typedef struct {
void* tDeserializeSVDropTbReq(void* buf, SVDropTbReq* pReq); int32_t nReqs;
union {
SVDropTbReq* pReqs;
SArray* pArray;
};
} SVDropTbBatchReq;
int32_t tEncodeSVDropTbBatchReq(SCoder* pCoder, const SVDropTbBatchReq* pReq);
int32_t tDecodeSVDropTbBatchReq(SCoder* pCoder, SVDropTbBatchReq* pReq);
typedef struct {
int32_t nRsps;
union {
SVDropTbRsp* pRsps;
SArray* pArray;
};
} SVDropTbBatchRsp;
int32_t tEncodeSVDropTbBatchRsp(SCoder* pCoder, const SVDropTbBatchRsp* pRsp);
int32_t tDecodeSVDropTbBatchRsp(SCoder* pCoder, SVDropTbBatchRsp* pRsp);
typedef struct { typedef struct {
SMsgHead head; SMsgHead head;

View File

@ -170,9 +170,9 @@ enum {
TD_DEF_MSG_TYPE(TDMT_VND_UPDATE_TAG_VAL, "vnode-update-tag-val", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_UPDATE_TAG_VAL, "vnode-update-tag-val", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_TABLE_META, "vnode-table-meta", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TABLE_META, "vnode-table-meta", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_TABLES_META, "vnode-tables-meta", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TABLES_META, "vnode-tables-meta", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_CREATE_STB, "vnode-create-stb", SVCreateTbReq, SVCreateTbRsp) TD_DEF_MSG_TYPE(TDMT_VND_CREATE_STB, "vnode-create-stb", SVCreateStbReq, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_STB, "vnode-alter-stb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_ALTER_STB, "vnode-alter-stb", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_DROP_STB, "vnode-drop-stb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_DROP_STB, "vnode-drop-stb", SVDropStbReq, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONSUME, "vnode-mq-consume", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONSUME, "vnode-mq-consume", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_MQ_QUERY, "vnode-mq-query", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_QUERY, "vnode-mq-query", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONNECT, "vnode-mq-connect", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONNECT, "vnode-mq-connect", NULL, NULL)

View File

@ -28,7 +28,8 @@ extern "C" {
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0) #define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
#define FOREACH(node, list) \ #define FOREACH(node, list) \
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext) for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
(NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode) #define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)
@ -44,15 +45,25 @@ extern "C" {
#define ERASE_NODE(list) cell = nodesListErase((list), cell) #define ERASE_NODE(list) cell = nodesListErase((list), cell)
#define FORBOTH(node1, list1, node2, list2) \ #define FORBOTH(node1, list1, node2, list2) \
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \ for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), \
(NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \ *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \
(NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), \
(NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), \
(node1 != NULL && node2 != NULL); \
cell1 = cell1->pNext, cell2 = cell2->pNext) cell1 = cell1->pNext, cell2 = cell2->pNext)
#define REPLACE_LIST1_NODE(newNode) cell1->pNode = (SNode*)(newNode) #define REPLACE_LIST1_NODE(newNode) cell1->pNode = (SNode*)(newNode)
#define REPLACE_LIST2_NODE(newNode) cell2->pNode = (SNode*)(newNode) #define REPLACE_LIST2_NODE(newNode) cell2->pNode = (SNode*)(newNode)
#define FOREACH_FOR_REWRITE(node, list) \ #define FOREACH_FOR_REWRITE(node, list) \
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext) for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
(NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext)
#define DESTORY_LIST(list) \
do { \
nodesDestroyList(list); \
list = NULL; \
} while (0)
typedef enum ENodeType { typedef enum ENodeType {
// Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN, // Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN,
@ -240,12 +251,7 @@ void nodesDestroyList(SNodeList* pList);
// Only clear the linked list structure, without releasing the elements inside // Only clear the linked list structure, without releasing the elements inside
void nodesClearList(SNodeList* pList); void nodesClearList(SNodeList* pList);
typedef enum EDealRes { typedef enum EDealRes { DEAL_RES_CONTINUE = 1, DEAL_RES_IGNORE_CHILD, DEAL_RES_ERROR, DEAL_RES_END } EDealRes;
DEAL_RES_CONTINUE = 1,
DEAL_RES_IGNORE_CHILD,
DEAL_RES_ERROR,
DEAL_RES_END
} EDealRes;
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext); typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext); void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext);
@ -271,8 +277,8 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode);
int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen); int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen);
int32_t nodesStringToList(const char* pStr, SNodeList** pList); int32_t nodesStringToList(const char* pStr, SNodeList** pList);
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len); int32_t nodesNodeToSQL(SNode* pNode, char* buf, int32_t bufSize, int32_t* len);
char *nodesGetNameFromColumnNode(SNode *pNode); char* nodesGetNameFromColumnNode(SNode* pNode);
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots); int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -88,6 +88,7 @@ typedef struct SValueNode {
double d; double d;
char* p; char* p;
} datum; } datum;
int64_t typeData;
char unit; char unit;
} SValueNode; } SValueNode;
@ -294,13 +295,14 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext); void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext);
typedef enum ECollectColType { COLLECT_COL_TYPE_COL = 1, COLLECT_COL_TYPE_TAG, COLLECT_COL_TYPE_ALL } ECollectColType; typedef enum ECollectColType { COLLECT_COL_TYPE_COL = 1, COLLECT_COL_TYPE_TAG, COLLECT_COL_TYPE_ALL } ECollectColType;
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type, int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
SNodeList** pCols); SNodeList** pCols);
typedef bool (*FFuncClassifier)(int32_t funcId); typedef bool (*FFuncClassifier)(int32_t funcId);
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs); int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs);
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
bool nodesIsExprNode(const SNode* pNode); bool nodesIsExprNode(const SNode* pNode);
bool nodesIsUnaryOp(const SOperatorNode* pOp); bool nodesIsUnaryOp(const SOperatorNode* pOp);
@ -312,6 +314,7 @@ bool nodesIsTimeorderQuery(const SNode* pQuery);
bool nodesIsTimelineQuery(const SNode* pQuery); bool nodesIsTimelineQuery(const SNode* pQuery);
void* nodesGetValueFromNode(SValueNode* pNode); void* nodesGetValueFromNode(SValueNode* pNode);
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value);
char* nodesGetStrValueFromNode(SValueNode* pNode); char* nodesGetStrValueFromNode(SValueNode* pNode);
char* getFillModeString(EFillMode mode); char* getFillModeString(EFillMode mode);
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal); void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);

View File

@ -318,6 +318,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_VND_TB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0515) #define TSDB_CODE_VND_TB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0515)
#define TSDB_CODE_VND_SMA_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0516) #define TSDB_CODE_VND_SMA_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0516)
#define TSDB_CODE_VND_HASH_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x0517) #define TSDB_CODE_VND_HASH_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x0517)
#define TSDB_CODE_VND_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0518)
// tsdb // tsdb
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600)
@ -616,6 +617,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_OFFSET_LESS_ZERO TAOS_DEF_ERROR_CODE(0, 0x2637) #define TSDB_CODE_PAR_OFFSET_LESS_ZERO TAOS_DEF_ERROR_CODE(0, 0x2637)
#define TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY TAOS_DEF_ERROR_CODE(0, 0x2638) #define TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY TAOS_DEF_ERROR_CODE(0, 0x2638)
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639) #define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
//planner //planner
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)

View File

@ -79,17 +79,6 @@ typedef struct {
#define TD_CODER_CURRENT(CODER) ((CODER)->data + (CODER)->pos) #define TD_CODER_CURRENT(CODER) ((CODER)->data + (CODER)->pos)
#define TD_CODER_MOVE_POS(CODER, MOVE) ((CODER)->pos += (MOVE)) #define TD_CODER_MOVE_POS(CODER, MOVE) ((CODER)->pos += (MOVE))
#define TD_CODER_CHECK_CAPACITY_FAILED(CODER, EXPSIZE) (((CODER)->size - (CODER)->pos) < (EXPSIZE)) #define TD_CODER_CHECK_CAPACITY_FAILED(CODER, EXPSIZE) (((CODER)->size - (CODER)->pos) < (EXPSIZE))
// #define TCODER_MALLOC(PCODER, SIZE) \
// ({ \
// void* ptr = NULL; \
// SCoderMem* pMem = (SCoderMem*)taosMemoryMalloc(sizeof(*pMem) + (SIZE)); \
// if (pMem) { \
// pMem->next = (PCODER)->mList; \
// (PCODER)->mList = pMem; \
// ptr = (void*)&pMem[1]; \
// } \
// ptr; \
// })
static FORCE_INLINE void* tCoderMalloc(SCoder* pCoder, int32_t size) { static FORCE_INLINE void* tCoderMalloc(SCoder* pCoder, int32_t size) {
void* ptr = NULL; void* ptr = NULL;
SCoderMem* pMem = (SCoderMem*)taosMemoryMalloc(sizeof(SCoderMem*) + size); SCoderMem* pMem = (SCoderMem*)taosMemoryMalloc(sizeof(SCoderMem*) + size);
@ -102,8 +91,9 @@ static FORCE_INLINE void* tCoderMalloc(SCoder* pCoder, int32_t size) {
} }
#define tEncodeSize(E, S, SIZE, RET) \ #define tEncodeSize(E, S, SIZE, RET) \
do{ \ do { \
SCoder coder = {0}; \ SCoder coder = {0}; \
RET = 0; \
tCoderInit(&coder, TD_LITTLE_ENDIAN, NULL, 0, TD_ENCODER); \ tCoderInit(&coder, TD_LITTLE_ENDIAN, NULL, 0, TD_ENCODER); \
if ((E)(&coder, S) == 0) { \ if ((E)(&coder, S) == 0) { \
SIZE = coder.pos; \ SIZE = coder.pos; \
@ -111,7 +101,7 @@ static FORCE_INLINE void* tCoderMalloc(SCoder* pCoder, int32_t size) {
RET = -1; \ RET = -1; \
} \ } \
tCoderClear(&coder); \ tCoderClear(&coder); \
}while(0) } while (0)
// #define tEncodeSize(E, S, SIZE) \ // #define tEncodeSize(E, S, SIZE) \
// ({ \ // ({ \
// SCoder coder = {0}; \ // SCoder coder = {0}; \

View File

@ -52,54 +52,6 @@ typedef struct SSkipListNode {
#define SL_NODE_GET_FORWARD_POINTER(n, l) (n)->forwards[(l)] #define SL_NODE_GET_FORWARD_POINTER(n, l) (n)->forwards[(l)]
#define SL_NODE_GET_BACKWARD_POINTER(n, l) (n)->forwards[(n)->level + (l)] #define SL_NODE_GET_BACKWARD_POINTER(n, l) (n)->forwards[(n)->level + (l)]
/*
* @version 0.3
* @date 2017/11/12
* the simple version of skip list.
*
* for multi-thread safe purpose, we employ TdThreadRwlock to guarantee to generate
* deterministic result. Later, we will remove the lock in SkipList to further enhance the performance.
* In this case, one should use the concurrent skip list (by using michael-scott algorithm) instead of
* this simple version in a multi-thread environment, to achieve higher performance of read/write operations.
*
* Note: Duplicated primary key situation.
* In case of duplicated primary key, two ways can be employed to handle this situation:
* 1. add as normal insertion without special process.
* 2. add an overflow pointer at each list node, all nodes with the same key will be added in the overflow pointer.
* In this case, the total steps of each search will be reduced significantly.
* Currently, we implement the skip list in a line with the first means, maybe refactor it soon.
*
* Memory consumption: the memory alignment causes many memory wasted. So, employ a memory
* pool will significantly reduce the total memory consumption, as well as the calloc/malloc operation costs.
*
*/
// state struct, record following information:
// number of links in each level.
// avg search steps, for latest 1000 queries
// avg search rsp time, for latest 1000 queries
// total memory size
typedef struct tSkipListState {
// in bytes, sizeof(SSkipList)+sizeof(SSkipListNode)*SSkipList->nSize
uint64_t nTotalMemSize;
uint64_t nLevelNodeCnt[MAX_SKIP_LIST_LEVEL];
uint64_t queryCount; // total query count
/*
* only record latest 1000 queries
* when the value==1000, = 0,
* nTotalStepsForQueries = 0,
* nTotalElapsedTimeForQueries = 0
*/
uint64_t nRecQueries;
uint16_t nTotalStepsForQueries;
uint64_t nTotalElapsedTimeForQueries;
uint16_t nInsertObjs;
uint16_t nTotalStepsForInsert;
uint64_t nTotalElapsedTimeForInsert;
} tSkipListState;
typedef enum { SSkipListPutSuccess = 0, SSkipListPutEarlyStop = 1, SSkipListPutSkipOne = 2 } SSkipListPutStatus; typedef enum { SSkipListPutSuccess = 0, SSkipListPutEarlyStop = 1, SSkipListPutSkipOne = 2 } SSkipListPutStatus;
typedef struct SSkipList { typedef struct SSkipList {
@ -115,9 +67,6 @@ typedef struct SSkipList {
uint32_t size; uint32_t size;
SSkipListNode *pHead; // point to the first element SSkipListNode *pHead; // point to the first element
SSkipListNode *pTail; // point to the last element SSkipListNode *pTail; // point to the last element
#if SKIP_LIST_RECORD_PERFORMANCE
tSkipListState state; // skiplist state
#endif
tGenericSavedFunc *insertHandleFn; tGenericSavedFunc *insertHandleFn;
} SSkipList; } SSkipList;

View File

@ -46,11 +46,12 @@ typedef struct SStmtTableCache {
void* boundTags; void* boundTags;
} SStmtTableCache; } SStmtTableCache;
typedef struct SQueryFields { typedef struct SStmtQueryResInfo {
TAOS_FIELD* fields; TAOS_FIELD* fields;
TAOS_FIELD* userFields; TAOS_FIELD* userFields;
uint32_t numOfCols; uint32_t numOfCols;
} SQueryFields; int32_t precision;
} SStmtQueryResInfo;
typedef struct SStmtBindInfo { typedef struct SStmtBindInfo {
bool needParse; bool needParse;
@ -82,7 +83,7 @@ typedef struct SStmtSQLInfo {
int32_t sqlLen; int32_t sqlLen;
SArray* nodeList; SArray* nodeList;
SQueryPlan* pQueryPlan; SQueryPlan* pQueryPlan;
SQueryFields fields; SStmtQueryResInfo queryRes;
} SStmtSQLInfo; } SStmtSQLInfo;
typedef struct STscStmt { typedef struct STscStmt {

View File

@ -74,17 +74,44 @@ int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) {
} }
int32_t stmtBackupQueryFields(STscStmt* pStmt) { int32_t stmtBackupQueryFields(STscStmt* pStmt) {
SQueryFields *pFields = &pStmt->sql.fields; SStmtQueryResInfo *pRes = &pStmt->sql.queryRes;
int32_t size = pFields->numOfCols * sizeof(TAOS_FIELD); pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols;
pRes->precision = pStmt->exec.pRequest->body.resInfo.precision;
pFields->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols; int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
pFields->fields = taosMemoryMalloc(size); pRes->fields = taosMemoryMalloc(size);
pFields->userFields = taosMemoryMalloc(size); pRes->userFields = taosMemoryMalloc(size);
if (NULL == pFields->fields || NULL == pFields->userFields) { if (NULL == pRes->fields || NULL == pRes->userFields) {
STMT_ERR_RET(TSDB_CODE_TSC_OUT_OF_MEMORY); STMT_ERR_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
} }
memcpy(pFields->fields, pStmt->exec.pRequest->body.resInfo.fields, size); memcpy(pRes->fields, pStmt->exec.pRequest->body.resInfo.fields, size);
memcpy(pFields->userFields, pStmt->exec.pRequest->body.resInfo.userFields, size); memcpy(pRes->userFields, pStmt->exec.pRequest->body.resInfo.userFields, size);
return TSDB_CODE_SUCCESS;
}
int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
SStmtQueryResInfo *pRes = &pStmt->sql.queryRes;
int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
pStmt->exec.pRequest->body.resInfo.numOfCols = pRes->numOfCols;
pStmt->exec.pRequest->body.resInfo.precision = pRes->precision;
if (NULL == pStmt->exec.pRequest->body.resInfo.fields) {
pStmt->exec.pRequest->body.resInfo.fields = taosMemoryMalloc(size);
if (NULL == pStmt->exec.pRequest->body.resInfo.fields) {
STMT_ERR_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
}
memcpy(pStmt->exec.pRequest->body.resInfo.fields, pRes->fields, size);
}
if (NULL == pStmt->exec.pRequest->body.resInfo.userFields) {
pStmt->exec.pRequest->body.resInfo.userFields = taosMemoryMalloc(size);
if (NULL == pStmt->exec.pRequest->body.resInfo.userFields) {
STMT_ERR_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
}
memcpy(pStmt->exec.pRequest->body.resInfo.userFields, pRes->userFields, size);
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -235,6 +262,8 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) {
} }
int32_t stmtCleanSQLInfo(STscStmt* pStmt) { int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
taosMemoryFree(pStmt->sql.queryRes.fields);
taosMemoryFree(pStmt->sql.queryRes.userFields);
taosMemoryFree(pStmt->sql.sqlStr); taosMemoryFree(pStmt->sql.sqlStr);
qDestroyQuery(pStmt->sql.pQuery); qDestroyQuery(pStmt->sql.pQuery);
qDestroyQueryPlan(pStmt->sql.pQueryPlan); qDestroyQueryPlan(pStmt->sql.pQueryPlan);
@ -497,6 +526,8 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag; pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag;
pStmt->exec.pRequest->body.pDag = NULL; pStmt->exec.pRequest->body.pDag = NULL;
STMT_ERR_RET(stmtBackupQueryFields(pStmt)); STMT_ERR_RET(stmtBackupQueryFields(pStmt));
} else {
STMT_ERR_RET(stmtRestoreQueryFields(pStmt));
} }
STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId)); STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId));
@ -509,7 +540,11 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
} }
if (colIdx < 0) { if (colIdx < 0) {
qBindStmtColsValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen); int32_t code = qBindStmtColsValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen);
if (code) {
tscError("qBindStmtColsValue failed, error:%s", tstrerror(code));
STMT_ERR_RET(code);
}
} else { } else {
if (colIdx != (pStmt->bInfo.sBindLastIdx + 1) && colIdx != 0) { if (colIdx != (pStmt->bInfo.sBindLastIdx + 1) && colIdx != 0) {
tscError("bind column index not in sequence"); tscError("bind column index not in sequence");

View File

@ -68,6 +68,7 @@ struct tmq_conf_t {
char* pass; char* pass;
char* db; char* db;
tmq_commit_cb* commitCb; tmq_commit_cb* commitCb;
void* commitCbUserParam;
}; };
struct tmq_t { struct tmq_t {
@ -78,7 +79,8 @@ struct tmq_t {
int32_t autoCommitInterval; int32_t autoCommitInterval;
int32_t resetOffsetCfg; int32_t resetOffsetCfg;
int64_t consumerId; int64_t consumerId;
tmq_commit_cb* commit_cb; tmq_commit_cb* commitCb;
void* commitCbUserParam;
// status // status
int8_t status; int8_t status;
@ -372,10 +374,18 @@ int32_t tmqSubscribeCb(void* param, const SDataBuf* pMsg, int32_t code) {
int32_t tmqCommitCb(void* param, const SDataBuf* pMsg, int32_t code) { int32_t tmqCommitCb(void* param, const SDataBuf* pMsg, int32_t code) {
SMqCommitCbParam* pParam = (SMqCommitCbParam*)param; SMqCommitCbParam* pParam = (SMqCommitCbParam*)param;
pParam->rspErr = code == 0 ? TMQ_RESP_ERR__SUCCESS : TMQ_RESP_ERR__FAIL; pParam->rspErr = code == 0 ? TMQ_RESP_ERR__SUCCESS : TMQ_RESP_ERR__FAIL;
if (pParam->tmq->commit_cb) { if (pParam->tmq->commitCb) {
pParam->tmq->commit_cb(pParam->tmq, pParam->rspErr, NULL); pParam->tmq->commitCb(pParam->tmq, pParam->rspErr, NULL, pParam->tmq->commitCbUserParam);
}
if (!pParam->async)
tsem_post(&pParam->rspSem);
else {
tsem_destroy(&pParam->rspSem);
/*if (pParam->pArray) {*/
/*taosArrayDestroy(pParam->pArray);*/
/*}*/
taosMemoryFree(pParam);
} }
if (!pParam->async) tsem_post(&pParam->rspSem);
return 0; return 0;
} }
@ -384,7 +394,7 @@ tmq_resp_err_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
*topics = tmq_list_new(); *topics = tmq_list_new();
} }
for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) { for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) {
SMqClientTopic* topic = taosArrayGetP(tmq->clientTopics, i); SMqClientTopic* topic = taosArrayGet(tmq->clientTopics, i);
tmq_list_append(*topics, topic->topicName); tmq_list_append(*topics, topic->topicName);
} }
return TMQ_RESP_ERR__SUCCESS; return TMQ_RESP_ERR__SUCCESS;
@ -477,7 +487,8 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
strcpy(pTmq->groupId, conf->groupId); strcpy(pTmq->groupId, conf->groupId);
pTmq->autoCommit = conf->autoCommit; pTmq->autoCommit = conf->autoCommit;
pTmq->autoCommitInterval = conf->autoCommitInterval; pTmq->autoCommitInterval = conf->autoCommitInterval;
pTmq->commit_cb = conf->commitCb; pTmq->commitCb = conf->commitCb;
pTmq->commitCbUserParam = conf->commitCbUserParam;
pTmq->resetOffsetCfg = conf->resetOffset; pTmq->resetOffsetCfg = conf->resetOffset;
// assign consumerId // assign consumerId
@ -557,7 +568,7 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in
tscError("failed to malloc request"); tscError("failed to malloc request");
} }
SMqCommitCbParam* pParam = taosMemoryMalloc(sizeof(SMqCommitCbParam)); SMqCommitCbParam* pParam = taosMemoryCalloc(1, sizeof(SMqCommitCbParam));
if (pParam == NULL) { if (pParam == NULL) {
return -1; return -1;
} }
@ -572,6 +583,7 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in
}; };
SMsgSendInfo* sendInfo = buildMsgInfoImpl(pRequest); SMsgSendInfo* sendInfo = buildMsgInfoImpl(pRequest);
sendInfo->requestObjRefId = 0;
sendInfo->param = pParam; sendInfo->param = pParam;
sendInfo->fp = tmqCommitCb; sendInfo->fp = tmqCommitCb;
SEpSet epSet = getEpSet_s(&tmq->pTscObj->pAppInfo->mgmtEp); SEpSet epSet = getEpSet_s(&tmq->pTscObj->pAppInfo->mgmtEp);
@ -582,14 +594,13 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in
if (!async) { if (!async) {
tsem_wait(&pParam->rspSem); tsem_wait(&pParam->rspSem);
resp = pParam->rspErr; resp = pParam->rspErr;
}
tsem_destroy(&pParam->rspSem); tsem_destroy(&pParam->rspSem);
taosMemoryFree(pParam); taosMemoryFree(pParam);
if (pArray) { if (pArray) {
taosArrayDestroy(pArray); taosArrayDestroy(pArray);
} }
}
return resp; return resp;
} }
@ -688,9 +699,10 @@ FAIL:
return code; return code;
} }
void tmq_conf_set_offset_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb) { void tmq_conf_set_offset_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb, void* param) {
// //
conf->commitCb = cb; conf->commitCb = cb;
conf->commitCbUserParam = param;
} }
#if 0 #if 0
@ -1306,10 +1318,10 @@ const char* tmq_err2str(tmq_resp_err_t err) {
return "fail"; return "fail";
} }
char* tmq_get_topic_name(TAOS_RES* res) { const char* tmq_get_topic_name(TAOS_RES* res) {
if (TD_RES_TMQ(res)) { if (TD_RES_TMQ(res)) {
SMqRspObj* pRspObj = (SMqRspObj*)res; SMqRspObj* pRspObj = (SMqRspObj*)res;
return pRspObj->topic; return strchr(pRspObj->topic, '.') + 1;
} else { } else {
return NULL; return NULL;
} }

View File

@ -490,21 +490,6 @@ int32_t tDeserializeSClientHbBatchRsp(void *buf, int32_t bufLen, SClientHbBatchR
return 0; return 0;
} }
int32_t tSerializeSVDropTbReq(void **buf, SVDropTbReq *pReq) {
int32_t tlen = 0;
tlen += taosEncodeFixedI64(buf, pReq->ver);
tlen += taosEncodeString(buf, pReq->name);
tlen += taosEncodeFixedU8(buf, pReq->type);
return tlen;
}
void *tDeserializeSVDropTbReq(void *buf, SVDropTbReq *pReq) {
buf = taosDecodeFixedI64(buf, &pReq->ver);
buf = taosDecodeString(buf, &pReq->name);
buf = taosDecodeFixedU8(buf, &pReq->type);
return buf;
}
int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq) { int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq) {
SCoder encoder = {0}; SCoder encoder = {0};
tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_ENCODER); tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_ENCODER);
@ -3811,3 +3796,119 @@ int tDecodeSVCreateTbRsp(SCoder *pCoder, SVCreateTbRsp *pRsp) {
tEndDecode(pCoder); tEndDecode(pCoder);
return 0; return 0;
} }
// TDMT_VND_DROP_TABLE =================
static int32_t tEncodeSVDropTbReq(SCoder *pCoder, const SVDropTbReq *pReq) {
if (tStartEncode(pCoder) < 0) return -1;
if (tEncodeCStr(pCoder, pReq->name) < 0) return -1;
if (tEncodeI8(pCoder, pReq->igNotExists) < 0) return -1;
tEndEncode(pCoder);
return 0;
}
static int32_t tDecodeSVDropTbReq(SCoder *pCoder, SVDropTbReq *pReq) {
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeCStr(pCoder, &pReq->name) < 0) return -1;
if (tDecodeI8(pCoder, &pReq->igNotExists) < 0) return -1;
tEndDecode(pCoder);
return 0;
}
static int32_t tEncodeSVDropTbRsp(SCoder *pCoder, const SVDropTbRsp *pReq) {
if (tStartEncode(pCoder) < 0) return -1;
if (tEncodeI32(pCoder, pReq->code) < 0) return -1;
tEndEncode(pCoder);
return 0;
}
static int32_t tDecodeSVDropTbRsp(SCoder *pCoder, SVDropTbRsp *pReq) {
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeI32(pCoder, &pReq->code) < 0) return -1;
tEndDecode(pCoder);
return 0;
}
int32_t tEncodeSVDropTbBatchReq(SCoder *pCoder, const SVDropTbBatchReq *pReq) {
int32_t nReqs = taosArrayGetSize(pReq->pArray);
SVDropTbReq *pDropTbReq;
if (tStartEncode(pCoder) < 0) return -1;
if (tEncodeI32v(pCoder, nReqs) < 0) return -1;
for (int iReq = 0; iReq < nReqs; iReq++) {
pDropTbReq = (SVDropTbReq *)taosArrayGet(pReq->pArray, iReq);
if (tEncodeSVDropTbReq(pCoder, pDropTbReq) < 0) return -1;
}
tEndEncode(pCoder);
return 0;
}
int32_t tDecodeSVDropTbBatchReq(SCoder *pCoder, SVDropTbBatchReq *pReq) {
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeI32v(pCoder, &pReq->nReqs) < 0) return -1;
pReq->pReqs = (SVDropTbReq *)tCoderMalloc(pCoder, sizeof(SVDropTbReq) * pReq->nReqs);
if (pReq->pReqs == NULL) return -1;
for (int iReq = 0; iReq < pReq->nReqs; iReq++) {
if (tDecodeSVDropTbReq(pCoder, pReq->pReqs + iReq) < 0) return -1;
}
tEndDecode(pCoder);
return 0;
}
int32_t tEncodeSVDropTbBatchRsp(SCoder *pCoder, const SVDropTbBatchRsp *pRsp) {
int32_t nRsps = taosArrayGetSize(pRsp->pArray);
if (tStartEncode(pCoder) < 0) return -1;
if (tEncodeI32v(pCoder, nRsps) < 0) return -1;
for (int iRsp = 0; iRsp < nRsps; iRsp++) {
if (tEncodeSVDropTbRsp(pCoder, (SVDropTbRsp *)taosArrayGet(pRsp->pArray, iRsp)) < 0) return -1;
}
tEndEncode(pCoder);
return 0;
}
int32_t tDecodeSVDropTbBatchRsp(SCoder *pCoder, SVDropTbBatchRsp *pRsp) {
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeI32v(pCoder, &pRsp->nRsps) < 0) return -1;
pRsp->pRsps = (SVDropTbRsp *)tCoderMalloc(pCoder, sizeof(SVDropTbRsp) * pRsp->nRsps);
if (pRsp->pRsps == NULL) return -1;
for (int iRsp = 0; iRsp < pRsp->nRsps; iRsp++) {
if (tDecodeSVDropTbRsp(pCoder, pRsp->pRsps + iRsp) < 0) return -1;
}
tEndDecode(pCoder);
return 0;
}
int32_t tEncodeSVDropStbReq(SCoder *pCoder, const SVDropStbReq *pReq) {
if (tStartEncode(pCoder) < 0) return -1;
if (tEncodeCStr(pCoder, pReq->name) < 0) return -1;
if (tEncodeI64(pCoder, pReq->suid) < 0) return -1;
tEndEncode(pCoder);
return 0;
}
int32_t tDecodeSVDropStbReq(SCoder *pCoder, SVDropStbReq *pReq) {
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeCStr(pCoder, &pReq->name) < 0) return -1;
if (tDecodeI64(pCoder, &pReq->suid) < 0) return -1;
tEndDecode(pCoder);
return 0;
}

View File

@ -254,8 +254,17 @@ static void dmSendRpcRedirectRsp(SDnode *pDnode, const SRpcMsg *pReq) {
epSet.eps[i].port = htons(epSet.eps[i].port); epSet.eps[i].port = htons(epSet.eps[i].port);
} }
SRpcMsg resp;
SMEpSet msg = {.epSet = epSet};
int32_t len = tSerializeSMEpSet(NULL, 0, &msg);
resp.pCont = rpcMallocCont(len);
resp.contLen = len;
tSerializeSMEpSet(resp.pCont, len, &msg);
rpcSendRedirectRsp(pReq->handle, &epSet); resp.code = TSDB_CODE_RPC_REDIRECT;
resp.handle = pReq->handle;
resp.refId = pReq->refId;
rpcSendResponse(&resp);
} }
static inline void dmSendRpcRsp(SDnode *pDnode, const SRpcMsg *pRsp) { static inline void dmSendRpcRsp(SDnode *pDnode, const SRpcMsg *pRsp) {

View File

@ -47,7 +47,7 @@ typedef int32_t (*MndInitFp)(SMnode *pMnode);
typedef void (*MndCleanupFp)(SMnode *pMnode); typedef void (*MndCleanupFp)(SMnode *pMnode);
typedef int32_t (*ShowRetrieveFp)(SNodeMsg *pMsg, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); typedef int32_t (*ShowRetrieveFp)(SNodeMsg *pMsg, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
typedef void (*ShowFreeIterFp)(SMnode *pMnode, void *pIter); typedef void (*ShowFreeIterFp)(SMnode *pMnode, void *pIter);
typedef struct SQWorkerMgmt SQHandle; typedef struct SQWorker SQHandle;
typedef struct { typedef struct {
const char *name; const char *name;

View File

@ -429,16 +429,22 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) { static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
SName name = {0}; SName name = {0};
SVDropStbReq req = {0};
int32_t contLen = 0;
int32_t ret = 0;
SMsgHead *pHead = NULL;
SCoder coder = {0};
tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); tNameFromString(&name, pStb->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
SVDropTbReq req = {0};
req.ver = 0;
req.name = (char *)tNameGetTableName(&name); req.name = (char *)tNameGetTableName(&name);
req.type = TD_SUPER_TABLE;
req.suid = pStb->uid; req.suid = pStb->uid;
int32_t contLen = tSerializeSVDropTbReq(NULL, &req) + sizeof(SMsgHead); tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
SMsgHead *pHead = taosMemoryMalloc(contLen); if (ret < 0) return NULL;
contLen += sizeof(SMsgHead);
pHead = taosMemoryMalloc(contLen);
if (pHead == NULL) { if (pHead == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL; return NULL;
@ -448,7 +454,10 @@ static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb,
pHead->vgId = htonl(pVgroup->vgId); pHead->vgId = htonl(pVgroup->vgId);
void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead)); void *pBuf = POINTER_SHIFT(pHead, sizeof(SMsgHead));
tSerializeSVDropTbReq(&pBuf, &req);
tCoderInit(&coder, TD_LITTLE_ENDIAN, pBuf, contLen - sizeof(SMsgHead), TD_ENCODER);
tEncodeSVDropStbReq(&coder, &req);
tCoderClear(&coder);
*pContLen = contLen; *pContLen = contLen;
return pHead; return pHead;

View File

@ -144,6 +144,10 @@ static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SM
int32_t vgId = pRebVg->pVgEp->vgId; int32_t vgId = pRebVg->pVgEp->vgId;
SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId); SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId);
if (pVgObj == NULL) {
taosMemoryFree(buf);
return -1;
}
STransAction action = {0}; STransAction action = {0};
action.epSet = mndGetVgroupEpset(pMnode, pVgObj); action.epSet = mndGetVgroupEpset(pMnode, pVgObj);
@ -509,7 +513,9 @@ static int32_t mndProcessRebalanceReq(SNodeMsg *pMsg) {
/*ASSERT(taosArrayGetSize(rebOutput.rebVgs) != 0);*/ /*ASSERT(taosArrayGetSize(rebOutput.rebVgs) != 0);*/
// TODO replace assert with error check // TODO replace assert with error check
ASSERT(mndPersistRebResult(pMnode, pMsg, &rebOutput) == 0); if (mndPersistRebResult(pMnode, pMsg, &rebOutput) < 0) {
mError("persist rebalance output error, possibly vnode splitted or dropped");
}
if (rebInput.pTopic) { if (rebInput.pTopic) {
SMqTopicObj *pTopic = (SMqTopicObj *)rebInput.pTopic; SMqTopicObj *pTopic = (SMqTopicObj *)rebInput.pTopic;

View File

@ -29,7 +29,7 @@
extern "C" { extern "C" {
#endif #endif
typedef struct SQWorkerMgmt SQHandle; typedef struct SQWorker SQHandle;
typedef struct SQnode { typedef struct SQnode {
int32_t qndId; int32_t qndId;

View File

@ -8,7 +8,6 @@ target_sources(
"src/vnd/vnodeBufPool.c" "src/vnd/vnodeBufPool.c"
"src/vnd/vnodeCfg.c" "src/vnd/vnodeCfg.c"
"src/vnd/vnodeCommit.c" "src/vnd/vnodeCommit.c"
"src/vnd/vnodeInt.c"
"src/vnd/vnodeQuery.c" "src/vnd/vnodeQuery.c"
"src/vnd/vnodeStateMgr.c" "src/vnd/vnodeStateMgr.c"
"src/vnd/vnodeModule.c" "src/vnd/vnodeModule.c"
@ -33,7 +32,6 @@ target_sources(
"src/tsdb/tsdbMemTable.c" "src/tsdb/tsdbMemTable.c"
"src/tsdb/tsdbRead.c" "src/tsdb/tsdbRead.c"
"src/tsdb/tsdbReadImpl.c" "src/tsdb/tsdbReadImpl.c"
"src/tsdb/tsdbScan.c"
"src/tsdb/tsdbSma.c" "src/tsdb/tsdbSma.c"
"src/tsdb/tsdbWrite.c" "src/tsdb/tsdbWrite.c"

View File

@ -32,7 +32,7 @@
#include "tmsg.h" #include "tmsg.h"
#include "trow.h" #include "trow.h"
#include "tdbInt.h" #include "tdb.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -57,9 +57,6 @@ int vnodeProcessCMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
int vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg); int vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg);
int vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo); int vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo);
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg);
int32_t vnodeCompact(SVnode *pVnode);
int32_t vnodeSync(SVnode *pVnode);
int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad); int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad);
int vnodeValidateTableHash(SVnode *pVnode, char *tableFName); int vnodeValidateTableHash(SVnode *pVnode, char *tableFName);

View File

@ -43,7 +43,6 @@ int metaEncodeEntry(SCoder* pCoder, const SMetaEntry* pME);
int metaDecodeEntry(SCoder* pCoder, SMetaEntry* pME); int metaDecodeEntry(SCoder* pCoder, SMetaEntry* pME);
// metaTable ================== // metaTable ==================
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
// metaQuery ================== // metaQuery ==================
int metaGetTableEntryByVersion(SMetaReader* pReader, int64_t version, tb_uid_t uid); int metaGetTableEntryByVersion(SMetaReader* pReader, int64_t version, tb_uid_t uid);

View File

@ -73,7 +73,6 @@ struct STsdb {
SVnode *pVnode; SVnode *pVnode;
bool repoLocked; bool repoLocked;
TdThreadMutex mutex; TdThreadMutex mutex;
STsdbCfg config;
STsdbMemTable *mem; STsdbMemTable *mem;
STsdbMemTable *imem; STsdbMemTable *imem;
SRtn rtn; SRtn rtn;
@ -185,7 +184,7 @@ struct STsdbFS {
}; };
#define REPO_ID(r) TD_VID((r)->pVnode) #define REPO_ID(r) TD_VID((r)->pVnode)
#define REPO_CFG(r) (&(r)->config) #define REPO_CFG(r) (&(r)->pVnode->config.tsdbCfg)
#define REPO_FS(r) ((r)->fs) #define REPO_FS(r) ((r)->fs)
#define REPO_META(r) ((r)->pVnode->pMeta) #define REPO_META(r) ((r)->pVnode->pMeta)
#define REPO_TFS(r) ((r)->pVnode->pTfs) #define REPO_TFS(r) ((r)->pVnode->pTfs)
@ -534,23 +533,6 @@ static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
} }
} }
// tsdbDBDef
// typedef struct SDBFile SDBFile;
// typedef DB_ENV* TDBEnv;
// struct SDBFile {
// int32_t fid;
// DB* pDB;
// char* path;
// };
// int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile* pDBF);
// void tsdbCloseDBF(SDBFile* pDBF);
// int32_t tsdbOpenBDBEnv(DB_ENV** ppEnv, const char* path);
// void tsdbCloseBDBEnv(DB_ENV* pEnv);
// int32_t tsdbSaveSmaToDB(SDBFile* pDBF, void* key, uint32_t keySize, void* data, uint32_t dataSize);
// void* tsdbGetSmaDataByKey(SDBFile* pDBF, void* key, uint32_t keySize, uint32_t* valueSize);
// tsdbFile // tsdbFile
#define TSDB_FILE_HEAD_SIZE 512 #define TSDB_FILE_HEAD_SIZE 512
#define TSDB_FILE_DELIMITER 0xF00AFA0F #define TSDB_FILE_DELIMITER 0xF00AFA0F

View File

@ -25,7 +25,7 @@
#include "tcompare.h" #include "tcompare.h"
#include "tcompression.h" #include "tcompression.h"
#include "tdatablock.h" #include "tdatablock.h"
#include "tdbInt.h" #include "tdb.h"
#include "tencode.h" #include "tencode.h"
#include "tfs.h" #include "tfs.h"
#include "tglobal.h" #include "tglobal.h"
@ -52,7 +52,7 @@ typedef struct STsdb STsdb;
typedef struct STQ STQ; typedef struct STQ STQ;
typedef struct SVState SVState; typedef struct SVState SVState;
typedef struct SVBufPool SVBufPool; typedef struct SVBufPool SVBufPool;
typedef struct SQWorkerMgmt SQHandle; typedef struct SQWorker SQHandle;
#define VNODE_META_DIR "meta" #define VNODE_META_DIR "meta"
#define VNODE_TSDB_DIR "tsdb" #define VNODE_TSDB_DIR "tsdb"
@ -75,6 +75,7 @@ int metaClose(SMeta* pMeta);
int metaBegin(SMeta* pMeta); int metaBegin(SMeta* pMeta);
int metaCommit(SMeta* pMeta); int metaCommit(SMeta* pMeta);
int metaCreateSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq); int metaCreateSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq); int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq);
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline); SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver); STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);

View File

@ -47,66 +47,66 @@ int metaOpen(SVnode *pVnode, SMeta **ppMeta) {
// open env // open env
ret = tdbEnvOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv); ret = tdbEnvOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta env since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta env since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pTbDb // open pTbDb
ret = tdbDbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb); ret = tdbDbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta table db since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta table db since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pSkmDb // open pSkmDb
ret = tdbDbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb); ret = tdbDbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta schema db since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta schema db since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pUidIdx // open pUidIdx
ret = tdbDbOpen("uid.idx", sizeof(tb_uid_t), sizeof(int64_t), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx); ret = tdbDbOpen("uid.idx", sizeof(tb_uid_t), sizeof(int64_t), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta uid idx since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta uid idx since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pNameIdx // open pNameIdx
ret = tdbDbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx); ret = tdbDbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta name index since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta name index since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pCtbIdx // open pCtbIdx
ret = tdbDbOpen("ctb.idx", sizeof(SCtbIdxKey), 0, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx); ret = tdbDbOpen("ctb.idx", sizeof(SCtbIdxKey), 0, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta child table index since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta child table index since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pTagIdx // open pTagIdx
ret = tdbDbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx); ret = tdbDbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta tag index since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta tag index since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open pTtlIdx // open pTtlIdx
ret = tdbDbOpen("ttl.idx", sizeof(STtlIdxKey), 0, ttlIdxKeyCmpr, pMeta->pEnv, &pMeta->pTtlIdx); ret = tdbDbOpen("ttl.idx", sizeof(STtlIdxKey), 0, ttlIdxKeyCmpr, pMeta->pEnv, &pMeta->pTtlIdx);
if (ret < 0) { if (ret < 0) {
metaError("vgId: %d failed to open meta ttl index since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta ttl index since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open index // open index
if (metaOpenIdx(pMeta) < 0) { if (metaOpenIdx(pMeta) < 0) {
metaError("vgId: %d failed to open meta index since %s", TD_VID(pVnode), tstrerror(terrno)); metaError("vgId:%d failed to open meta index since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
metaDebug("vgId: %d meta is opened", TD_VID(pVnode)); metaDebug("vgId:%d meta is opened", TD_VID(pVnode));
*ppMeta = pMeta; *ppMeta = pMeta;
return 0; return 0;

View File

@ -23,7 +23,7 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
void metaReaderClear(SMetaReader *pReader) { void metaReaderClear(SMetaReader *pReader) {
tCoderClear(&pReader->coder); tCoderClear(&pReader->coder);
TDB_FREE(pReader->pBuf); tdbFree(pReader->pBuf);
} }
int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) { int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) {
@ -96,15 +96,17 @@ SMTbCursor *metaOpenTbCursor(SMeta *pMeta) {
metaReaderInit(&pTbCur->mr, pMeta, 0); metaReaderInit(&pTbCur->mr, pMeta, 0);
tdbDbcOpen(pMeta->pUidIdx, &pTbCur->pDbc); tdbDbcOpen(pMeta->pUidIdx, &pTbCur->pDbc, NULL);
tdbDbcMoveToFirst(pTbCur->pDbc);
return pTbCur; return pTbCur;
} }
void metaCloseTbCursor(SMTbCursor *pTbCur) { void metaCloseTbCursor(SMTbCursor *pTbCur) {
if (pTbCur) { if (pTbCur) {
TDB_FREE(pTbCur->pKey); tdbFree(pTbCur->pKey);
TDB_FREE(pTbCur->pVal); tdbFree(pTbCur->pVal);
metaReaderClear(&pTbCur->mr); metaReaderClear(&pTbCur->mr);
if (pTbCur->pDbc) { if (pTbCur->pDbc) {
tdbDbcClose(pTbCur->pDbc); tdbDbcClose(pTbCur->pDbc);
@ -119,7 +121,7 @@ int metaTbCursorNext(SMTbCursor *pTbCur) {
STbCfg tbCfg; STbCfg tbCfg;
for (;;) { for (;;) {
ret = tdbDbNext(pTbCur->pDbc, &pTbCur->pKey, &pTbCur->kLen, &pTbCur->pVal, &pTbCur->vLen); ret = tdbDbcNext(pTbCur->pDbc, &pTbCur->pKey, &pTbCur->kLen, &pTbCur->pVal, &pTbCur->vLen);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -169,7 +171,7 @@ SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, boo
pSW->pSchema = pSchema; pSW->pSchema = pSchema;
TDB_FREE(pVal); tdbFree(pVal);
return pSW; return pSW;
} }
@ -185,7 +187,9 @@ struct SMCtbCursor {
SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) { SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
SMCtbCursor *pCtbCur = NULL; SMCtbCursor *pCtbCur = NULL;
SCtbIdxKey ctbIdxKey;
int ret; int ret;
int c;
pCtbCur = (SMCtbCursor *)taosMemoryCalloc(1, sizeof(*pCtbCur)); pCtbCur = (SMCtbCursor *)taosMemoryCalloc(1, sizeof(*pCtbCur));
if (pCtbCur == NULL) { if (pCtbCur == NULL) {
@ -193,12 +197,20 @@ SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
} }
pCtbCur->suid = uid; pCtbCur->suid = uid;
ret = tdbDbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur); ret = tdbDbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL);
if (ret < 0) { if (ret < 0) {
taosMemoryFree(pCtbCur); taosMemoryFree(pCtbCur);
return NULL; return NULL;
} }
// move to the suid
ctbIdxKey.suid = uid;
ctbIdxKey.uid = INT64_MIN;
tdbDbcMoveTo(pCtbCur->pCur, &ctbIdxKey, sizeof(ctbIdxKey), &c);
if (c > 0) {
tdbDbcMoveToNext(pCtbCur->pCur);
}
return pCtbCur; return pCtbCur;
} }
@ -207,8 +219,8 @@ void metaCloseCtbCurosr(SMCtbCursor *pCtbCur) {
if (pCtbCur->pCur) { if (pCtbCur->pCur) {
tdbDbcClose(pCtbCur->pCur); tdbDbcClose(pCtbCur->pCur);
TDB_FREE(pCtbCur->pKey); tdbFree(pCtbCur->pKey);
TDB_FREE(pCtbCur->pVal); tdbFree(pCtbCur->pVal);
} }
taosMemoryFree(pCtbCur); taosMemoryFree(pCtbCur);
@ -219,12 +231,15 @@ tb_uid_t metaCtbCursorNext(SMCtbCursor *pCtbCur) {
int ret; int ret;
SCtbIdxKey *pCtbIdxKey; SCtbIdxKey *pCtbIdxKey;
ret = tdbDbNext(pCtbCur->pCur, &pCtbCur->pKey, &pCtbCur->kLen, &pCtbCur->pVal, &pCtbCur->vLen); ret = tdbDbcNext(pCtbCur->pCur, &pCtbCur->pKey, &pCtbCur->kLen, &pCtbCur->pVal, &pCtbCur->vLen);
if (ret < 0) { if (ret < 0) {
return 0; return 0;
} }
pCtbIdxKey = pCtbCur->pKey; pCtbIdxKey = pCtbCur->pKey;
if (pCtbIdxKey->suid > pCtbCur->suid) {
return 0;
}
return pCtbIdxKey->uid; return pCtbIdxKey->uid;
} }
@ -283,7 +298,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
while (true) { while (true) {
// TODO: lock during iterate? // TODO: lock during iterate?
if (tdbDbNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) { if (tdbDbcNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) {
pSmaIdxKey = pCur->pKey; pSmaIdxKey = pCur->pKey;
ASSERT(pSmaIdxKey != NULL); ASSERT(pSmaIdxKey != NULL);
@ -297,7 +312,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
++pSW->number; ++pSW->number;
STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma)); STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma));
if (tptr == NULL) { if (tptr == NULL) {
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
metaCloseSmaCursor(pCur); metaCloseSmaCursor(pCur);
tdDestroyTSmaWrapper(pSW); tdDestroyTSmaWrapper(pSW);
taosMemoryFreeClear(pSW); taosMemoryFreeClear(pSW);
@ -306,13 +321,13 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
pSW->tSma = tptr; pSW->tSma = tptr;
pBuf = pSmaVal; pBuf = pSmaVal;
if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) { if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) {
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
metaCloseSmaCursor(pCur); metaCloseSmaCursor(pCur);
tdDestroyTSmaWrapper(pSW); tdDestroyTSmaWrapper(pSW);
taosMemoryFreeClear(pSW); taosMemoryFreeClear(pSW);
return NULL; return NULL;
} }
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
continue; continue;
} }
break; break;
@ -354,7 +369,7 @@ SArray *metaGetSmaTbUids(SMeta *pMeta, bool isDup) {
tb_uid_t uid = 0; tb_uid_t uid = 0;
while (true) { while (true) {
// TODO: lock during iterate? // TODO: lock during iterate?
if (tdbDbNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) { if (tdbDbcNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) {
ASSERT(pSmaIdxKey != NULL); ASSERT(pSmaIdxKey != NULL);
pSmaIdxKey = pCur->pKey; pSmaIdxKey = pCur->pKey;
@ -425,11 +440,11 @@ void *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid, bool isDecode) {
if (tDecodeTSma(pBuf, pCfg) == NULL) { if (tDecodeTSma(pBuf, pCfg) == NULL) {
tdDestroyTSma(pCfg); tdDestroyTSma(pCfg);
taosMemoryFree(pCfg); taosMemoryFree(pCfg);
TDB_FREE(pVal); tdbFree(pVal);
return NULL; return NULL;
} }
TDB_FREE(pVal); tdbFree(pVal);
return pCfg; return pCfg;
#endif #endif
#endif #endif

View File

@ -289,7 +289,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
pVal = pBuf = buf; pVal = pBuf = buf;
metaEncodeTbInfo(&pBuf, pTbCfg); metaEncodeTbInfo(&pBuf, pTbCfg);
vLen = POINTER_DISTANCE(pBuf, buf); vLen = POINTER_DISTANCE(pBuf, buf);
ret = tdbDbInsert(pMetaDb->pTbDB, pKey, kLen, pVal, vLen, &pMetaDb->txn); ret = tdbDbPut(pMetaDb->pTbDB, pKey, kLen, pVal, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -311,7 +311,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
pVal = pBuf = buf; pVal = pBuf = buf;
metaEncodeSchemaEx(&pBuf, &schemaWrapper); metaEncodeSchemaEx(&pBuf, &schemaWrapper);
vLen = POINTER_DISTANCE(pBuf, buf); vLen = POINTER_DISTANCE(pBuf, buf);
ret = tdbDbInsert(pMetaDb->pSchemaDB, pKey, kLen, pVal, vLen, &pMeta->pDB->txn); ret = tdbDbPut(pMetaDb->pSchemaDB, pKey, kLen, pVal, vLen, &pMeta->pDB->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -325,7 +325,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
kLen = nameLen + 1 + sizeof(uid); kLen = nameLen + 1 + sizeof(uid);
pVal = NULL; pVal = NULL;
vLen = 0; vLen = 0;
ret = tdbDbInsert(pMetaDb->pNameIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn); ret = tdbDbPut(pMetaDb->pNameIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -336,7 +336,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
kLen = sizeof(uid); kLen = sizeof(uid);
pVal = NULL; pVal = NULL;
vLen = 0; vLen = 0;
ret = tdbDbInsert(pMetaDb->pStbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn); ret = tdbDbPut(pMetaDb->pStbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -347,7 +347,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
kLen = sizeof(ctbIdxKey); kLen = sizeof(ctbIdxKey);
pVal = NULL; pVal = NULL;
vLen = 0; vLen = 0;
ret = tdbDbInsert(pMetaDb->pCtbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn); ret = tdbDbPut(pMetaDb->pCtbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -362,7 +362,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
kLen = sizeof(uid); kLen = sizeof(uid);
pVal = NULL; pVal = NULL;
vLen = 0; vLen = 0;
ret = tdbDbInsert(pMetaDb->pNtbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn); ret = tdbDbPut(pMetaDb->pNtbIdx, pKey, kLen, pVal, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
@ -407,7 +407,7 @@ static SSchemaWrapper *metaGetTableSchemaImpl(SMeta *pMeta, tb_uid_t uid, int32_
pSchemaWrapper = taosMemoryMalloc(sizeof(*pSchemaWrapper)); pSchemaWrapper = taosMemoryMalloc(sizeof(*pSchemaWrapper));
metaDecodeSchemaEx(pBuf, pSchemaWrapper, isGetEx); metaDecodeSchemaEx(pBuf, pSchemaWrapper, isGetEx);
TDB_FREE(pVal); tdbFree(pVal);
return pSchemaWrapper; return pSchemaWrapper;
} }
@ -438,7 +438,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
while (true) { while (true) {
// TODO: lock during iterate? // TODO: lock during iterate?
if (tdbDbNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) { if (tdbDbcNext(pCur->pCur, &pCur->pKey, &pCur->kLen, NULL, &pCur->vLen) == 0) {
pSmaIdxKey = pCur->pKey; pSmaIdxKey = pCur->pKey;
ASSERT(pSmaIdxKey != NULL); ASSERT(pSmaIdxKey != NULL);
@ -450,7 +450,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
} }
if ((pSW == NULL) && ((pSW = taosMemoryCalloc(1, sizeof(*pSW))) == NULL)) { if ((pSW == NULL) && ((pSW = taosMemoryCalloc(1, sizeof(*pSW))) == NULL)) {
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
metaCloseSmaCursor(pCur); metaCloseSmaCursor(pCur);
return NULL; return NULL;
} }
@ -458,7 +458,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
++pSW->number; ++pSW->number;
STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma)); STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma));
if (tptr == NULL) { if (tptr == NULL) {
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
metaCloseSmaCursor(pCur); metaCloseSmaCursor(pCur);
tdDestroyTSmaWrapper(pSW); tdDestroyTSmaWrapper(pSW);
taosMemoryFreeClear(pSW); taosMemoryFreeClear(pSW);
@ -467,13 +467,13 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
pSW->tSma = tptr; pSW->tSma = tptr;
pBuf = pSmaVal; pBuf = pSmaVal;
if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) { if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) {
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
metaCloseSmaCursor(pCur); metaCloseSmaCursor(pCur);
tdDestroyTSmaWrapper(pSW); tdDestroyTSmaWrapper(pSW);
taosMemoryFreeClear(pSW); taosMemoryFreeClear(pSW);
return NULL; return NULL;
} }
TDB_FREE(pSmaVal); tdbFree(pSmaVal);
continue; continue;
} }
break; break;
@ -530,7 +530,7 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
int32_t kLen = sizeof(pSmaCfg->indexUid); int32_t kLen = sizeof(pSmaCfg->indexUid);
int32_t vLen = POINTER_DISTANCE(qBuf, pBuf); int32_t vLen = POINTER_DISTANCE(qBuf, pBuf);
ret = tdbDbInsert(pMeta->pDB->pSmaDB, key, kLen, val, vLen, &pMetaDb->txn); ret = tdbDbPut(pMeta->pDB->pSmaDB, key, kLen, val, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
taosMemoryFreeClear(pBuf); taosMemoryFreeClear(pBuf);
return -1; return -1;
@ -545,7 +545,7 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
val = NULL; val = NULL;
vLen = 0; vLen = 0;
ret = tdbDbInsert(pMeta->pDB->pSmaIdx, key, kLen, val, vLen, &pMetaDb->txn); ret = tdbDbPut(pMeta->pDB->pSmaIdx, key, kLen, val, vLen, &pMetaDb->txn);
if (ret < 0) { if (ret < 0) {
taosMemoryFreeClear(pBuf); taosMemoryFreeClear(pBuf);
return -1; return -1;
@ -613,7 +613,7 @@ int64_t metaSmaCursorNext(SMSmaCursor *pCur) {
void *pBuf; void *pBuf;
SSmaIdxKey *smaIdxKey; SSmaIdxKey *smaIdxKey;
ret = tdbDbNext(pCur->pCur, &pCur->pKey, &pCur->kLen, &pCur->pVal, &pCur->vLen); ret = tdbDbcNext(pCur->pCur, &pCur->pKey, &pCur->kLen, &pCur->pVal, &pCur->vLen);
if (ret < 0) { if (ret < 0) {
return 0; return 0;
} }

View File

@ -61,19 +61,58 @@ int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
if (metaHandleEntry(pMeta, &me) < 0) goto _err; if (metaHandleEntry(pMeta, &me) < 0) goto _err;
metaDebug("vgId: %d super table is created, name:%s uid: %" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid); metaDebug("vgId:%d super table is created, name:%s uid: %" PRId64, TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
return 0; return 0;
_err: _err:
metaError("vgId: %d failed to create super table: %s uid: %" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, metaError("vgId:%d failed to create super table: %s uid: %" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
pReq->suid, tstrerror(terrno)); pReq->suid, tstrerror(terrno));
return -1; return -1;
} }
int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) { int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
// TODO SMetaReader mr = {0};
// validate req
metaReaderInit(&mr, pMeta, 0);
if (metaGetTableEntryByUid(&mr, pReq->suid) < 0) {
terrno = TSDB_CODE_VND_TABLE_NOT_EXIST;
goto _err;
}
// do drop
// drop from pTbDb
// drop from pSkmDb
// drop from pUidIdx
// drop from pNameIdx
// {
// TDBC *pDbc1 = NULL;
// void *pKey = NULL;
// void *pVal = NULL;
// int kLen = 0;
// int vLen = 0;
// int ret = 0;
// // drop from pCtbIdx
// ret = tdbDbcOpen(pMeta->pCtbIdx, &pDbc1);
// tdbDbcMoveTo(pDbc1, &pReq->suid, sizeof(pReq->suid), NULL /*cmpr*/, 0 /*TDB_FORWARD_SEARCH*/);
// tdbDbcGet(pDbc1, &pKey, &kLen, &pVal, vLen);
// tdbDbcDrop(pDbc1);
// // drop from pTagIdx
// // drop from pTtlIdx
// }
// clear and return
metaReaderClear(&mr);
metaError("vgId:%d super table %s uid:%" PRId64 " is dropped", TD_VID(pMeta->pVnode), pReq->name, pReq->suid);
return 0; return 0;
_err:
metaReaderClear(&mr);
metaError("vgId:%d failed to drop super table %s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name,
pReq->suid, tstrerror(terrno));
return -1;
} }
int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) { int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
@ -179,7 +218,7 @@ static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
tCoderClear(&coder); tCoderClear(&coder);
// write to table.db // write to table.db
if (tdbDbInsert(pMeta->pTbDb, pKey, kLen, pVal, vLen, &pMeta->txn) < 0) { if (tdbDbPut(pMeta->pTbDb, pKey, kLen, pVal, vLen, &pMeta->txn) < 0) {
goto _err; goto _err;
} }
@ -192,11 +231,11 @@ _err:
} }
static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) { static int metaUpdateUidIdx(SMeta *pMeta, const SMetaEntry *pME) {
return tdbDbInsert(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &pME->version, sizeof(int64_t), &pMeta->txn); return tdbDbPut(pMeta->pUidIdx, &pME->uid, sizeof(tb_uid_t), &pME->version, sizeof(int64_t), &pMeta->txn);
} }
static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) { static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME) {
return tdbDbInsert(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), &pMeta->txn); return tdbDbPut(pMeta->pNameIdx, pME->name, strlen(pME->name) + 1, &pME->uid, sizeof(tb_uid_t), &pMeta->txn);
} }
static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) { static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
@ -219,12 +258,12 @@ static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
ttlKey.dtime = ctime + ttlDays * 24 * 60 * 60; ttlKey.dtime = ctime + ttlDays * 24 * 60 * 60;
ttlKey.uid = pME->uid; ttlKey.uid = pME->uid;
return tdbDbInsert(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn); return tdbDbPut(pMeta->pTtlIdx, &ttlKey, sizeof(ttlKey), NULL, 0, &pMeta->txn);
} }
static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) { static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid}; SCtbIdxKey ctbIdxKey = {.suid = pME->ctbEntry.suid, .uid = pME->uid};
return tdbDbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn); return tdbDbPut(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn);
} }
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME) { static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME) {
@ -265,7 +304,7 @@ static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
tCoderInit(&coder, TD_LITTLE_ENDIAN, pVal, vLen, TD_ENCODER); tCoderInit(&coder, TD_LITTLE_ENDIAN, pVal, vLen, TD_ENCODER);
tEncodeSSchemaWrapper(&coder, pSW); tEncodeSSchemaWrapper(&coder, pSW);
if (tdbDbInsert(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, &pMeta->txn) < 0) { if (tdbDbPut(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), pVal, vLen, &pMeta->txn) < 0) {
rcode = -1; rcode = -1;
goto _exit; goto _exit;
} }

View File

@ -91,16 +91,8 @@ int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* p
int32_t sversion = 0; int32_t sversion = 0;
if (pHandle->sver != sversion) { if (pHandle->sver != sversion) {
pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion); pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion);
#if 0
tb_uid_t quid; // this interface use suid instead of uid
STbCfg* pTbCfg = metaGetTbInfoByUid(pHandle->pVnodeMeta, pHandle->msgIter.uid);
if (pTbCfg->type == META_CHILD_TABLE) {
quid = pTbCfg->ctbCfg.suid;
} else {
quid = pHandle->msgIter.uid;
}
pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, quid, sversion, true);
#endif
pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true); pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true);
pHandle->sver = sversion; pHandle->sver = sversion;
} }

View File

@ -55,7 +55,7 @@ typedef struct {
#define TSDB_COMMIT_BUF(ch) TSDB_READ_BUF(&((ch)->readh)) #define TSDB_COMMIT_BUF(ch) TSDB_READ_BUF(&((ch)->readh))
#define TSDB_COMMIT_COMP_BUF(ch) TSDB_READ_COMP_BUF(&((ch)->readh)) #define TSDB_COMMIT_COMP_BUF(ch) TSDB_READ_COMP_BUF(&((ch)->readh))
#define TSDB_COMMIT_EXBUF(ch) TSDB_READ_EXBUF(&((ch)->readh)) #define TSDB_COMMIT_EXBUF(ch) TSDB_READ_EXBUF(&((ch)->readh))
#define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->config.maxRows) #define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->pVnode->config.tsdbCfg.maxRows)
#define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch))) #define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch)))
static void tsdbStartCommit(STsdb *pRepo); static void tsdbStartCommit(STsdb *pRepo);

View File

@ -56,9 +56,8 @@ int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir) {
dir); dir);
pTsdb->pVnode = pVnode; pTsdb->pVnode = pVnode;
pTsdb->repoLocked = false; pTsdb->repoLocked = false;
tdbMutexInit(&pTsdb->mutex, NULL); taosThreadMutexInit(&pTsdb->mutex, NULL);
pTsdb->config = pVnode->config.tsdbCfg; pTsdb->fs = tsdbNewFS(REPO_CFG(pTsdb));
pTsdb->fs = tsdbNewFS(&pTsdb->config);
// create dir (TODO: use tfsMkdir) // create dir (TODO: use tfsMkdir)
taosMkDir(pTsdb->path); taosMkDir(pTsdb->path);

View File

@ -311,7 +311,7 @@ static bool emptyQueryTimewindow(STsdbReadHandle* pTsdbReadHandle) {
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return // Update the query time window according to the data time to live(TTL) information, in order to avoid to return
// the expired data to client, even it is queried already. // the expired data to client, even it is queried already.
static int64_t getEarliestValidTimestamp(STsdb* pTsdb) { static int64_t getEarliestValidTimestamp(STsdb* pTsdb) {
STsdbCfg* pCfg = &pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdb);
int64_t now = taosGetTimestamp(pCfg->precision); int64_t now = taosGetTimestamp(pCfg->precision);
return now - (tsTickPerDay[pCfg->precision] * pCfg->keep2) + 1; // needs to add one tick return now - (tsTickPerDay[pCfg->precision] * pCfg->keep2) + 1; // needs to add one tick
@ -404,7 +404,7 @@ static STsdbReadHandle* tsdbQueryTablesImpl(STsdb* tsdb, SQueryTableDataCond* pC
pReadHandle->defaultLoadColumn = getDefaultLoadColumns(pReadHandle, true); pReadHandle->defaultLoadColumn = getDefaultLoadColumns(pReadHandle, true);
} }
pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->config.maxRows); pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->pVnode->config.tsdbCfg.maxRows);
if (pReadHandle->pDataCols == NULL) { if (pReadHandle->pDataCols == NULL) {
tsdbError("%p failed to malloc buf for pDataCols, %s", pReadHandle, pReadHandle->idStr); tsdbError("%p failed to malloc buf for pDataCols, %s", pReadHandle, pReadHandle->idStr);
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
@ -889,7 +889,7 @@ static bool moveToNextRowInMem(STableCheckInfo* pCheckInfo) {
} }
static bool hasMoreDataInCache(STsdbReadHandle* pHandle) { static bool hasMoreDataInCache(STsdbReadHandle* pHandle) {
STsdbCfg* pCfg = &pHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pHandle->pTsdb);
size_t size = taosArrayGetSize(pHandle->pTableCheckInfo); size_t size = taosArrayGetSize(pHandle->pTableCheckInfo);
assert(pHandle->activeIndex < size && pHandle->activeIndex >= 0 && size >= 1); assert(pHandle->activeIndex < size && pHandle->activeIndex >= 0 && size >= 1);
pHandle->cur.fid = INT32_MIN; pHandle->cur.fid = INT32_MIN;
@ -1169,7 +1169,7 @@ static void copyAllRemainRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle,
static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo) { static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo) {
SQueryFilePos* cur = &pTsdbReadHandle->cur; SQueryFilePos* cur = &pTsdbReadHandle->cur;
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock); SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
TSKEY key; TSKEY key;
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
@ -1756,7 +1756,7 @@ int32_t getEndPosInDataBlock(STsdbReadHandle* pTsdbReadHandle, SDataBlockInfo* p
static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock) { static void doMergeTwoLevelData(STsdbReadHandle* pTsdbReadHandle, STableCheckInfo* pCheckInfo, SBlock* pBlock) {
SQueryFilePos* cur = &pTsdbReadHandle->cur; SQueryFilePos* cur = &pTsdbReadHandle->cur;
SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock); SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
initTableMemIterator(pTsdbReadHandle, pCheckInfo); initTableMemIterator(pTsdbReadHandle, pCheckInfo);
@ -2200,7 +2200,7 @@ static int32_t getFirstFileDataBlock(STsdbReadHandle* pTsdbReadHandle, bool* exi
int32_t numOfBlocks = 0; int32_t numOfBlocks = 0;
int32_t numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo); int32_t numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
STimeWindow win = TSWINDOW_INITIALIZER; STimeWindow win = TSWINDOW_INITIALIZER;
while (true) { while (true) {
@ -2306,7 +2306,7 @@ int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT* queryHandle, STableBlockDistInfo*
// find the start data block in file // find the start data block in file
pTsdbReadHandle->locateStart = true; pTsdbReadHandle->locateStart = true;
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
int32_t fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision); int32_t fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision);
tsdbRLockFS(pFileHandle); tsdbRLockFS(pFileHandle);
@ -2407,7 +2407,7 @@ static int32_t getDataBlocksInFiles(STsdbReadHandle* pTsdbReadHandle, bool* exis
// find the start data block in file // find the start data block in file
if (!pTsdbReadHandle->locateStart) { if (!pTsdbReadHandle->locateStart) {
pTsdbReadHandle->locateStart = true; pTsdbReadHandle->locateStart = true;
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
int32_t fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision); int32_t fid = getFileIdFromKey(pTsdbReadHandle->window.skey, pCfg->days, pCfg->precision);
tsdbRLockFS(pFileHandle); tsdbRLockFS(pFileHandle);
@ -2498,7 +2498,7 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
STsdbReadHandle* pTsdbReadHandle) { STsdbReadHandle* pTsdbReadHandle) {
int numOfRows = 0; int numOfRows = 0;
int32_t numOfCols = (int32_t)taosArrayGetSize(pTsdbReadHandle->pColumns); int32_t numOfCols = (int32_t)taosArrayGetSize(pTsdbReadHandle->pColumns);
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config; STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
win->skey = TSKEY_INITIAL_VAL; win->skey = TSKEY_INITIAL_VAL;
int64_t st = taosGetTimestampUs(); int64_t st = taosGetTimestampUs();

View File

@ -248,7 +248,8 @@ int tsdbLoadBlockInfo(SReadH *pReadh, void *pTarget) {
int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) { int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
ASSERT(pBlock->numOfSubBlocks > 0); ASSERT(pBlock->numOfSubBlocks > 0);
int8_t update = pReadh->pRepo->config.update; STsdbCfg *pCfg = REPO_CFG(pReadh->pRepo);
int8_t update = pCfg->update;
SBlock *iBlock = pBlock; SBlock *iBlock = pBlock;
if (pBlock->numOfSubBlocks > 1) { if (pBlock->numOfSubBlocks > 1) {
@ -279,7 +280,7 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo, const int16_t *colIds, int numOfColsIds, int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo, const int16_t *colIds, int numOfColsIds,
bool mergeBitmap) { bool mergeBitmap) {
ASSERT(pBlock->numOfSubBlocks > 0); ASSERT(pBlock->numOfSubBlocks > 0);
int8_t update = pReadh->pRepo->config.update; int8_t update = pReadh->pRepo->pVnode->config.tsdbCfg.update;
SBlock *iBlock = pBlock; SBlock *iBlock = pBlock;
if (pBlock->numOfSubBlocks > 1) { if (pBlock->numOfSubBlocks > 1) {

View File

@ -223,7 +223,7 @@ static FORCE_INLINE int32_t tsdbUnLockSma(SSmaEnv *pEnv) {
} }
static SPoolMem *openPool() { static SPoolMem *openPool() {
SPoolMem *pPool = (SPoolMem *)tdbOsMalloc(sizeof(*pPool)); SPoolMem *pPool = (SPoolMem *)taosMemoryMalloc(sizeof(*pPool));
pPool->prev = pPool->next = pPool; pPool->prev = pPool->next = pPool;
pPool->size = 0; pPool->size = 0;
@ -245,7 +245,7 @@ static void clearPool(SPoolMem *pPool) {
pMem->prev->next = pMem->next; pMem->prev->next = pMem->next;
pPool->size -= pMem->size; pPool->size -= pMem->size;
tdbOsFree(pMem); taosMemoryFree(pMem);
} while (1); } while (1);
assert(pPool->size == 0); assert(pPool->size == 0);
@ -254,7 +254,7 @@ static void clearPool(SPoolMem *pPool) {
static void closePool(SPoolMem *pPool) { static void closePool(SPoolMem *pPool) {
if (pPool) { if (pPool) {
clearPool(pPool); clearPool(pPool);
tdbOsFree(pPool); taosMemoryFree(pPool);
} }
} }
@ -263,7 +263,7 @@ static void *poolMalloc(void *arg, size_t size) {
SPoolMem *pPool = (SPoolMem *)arg; SPoolMem *pPool = (SPoolMem *)arg;
SPoolMem *pMem; SPoolMem *pMem;
pMem = (SPoolMem *)tdbOsMalloc(sizeof(*pMem) + size); pMem = (SPoolMem *)taosMemoryMalloc(sizeof(*pMem) + size);
if (!pMem) { if (!pMem) {
assert(0); assert(0);
} }
@ -290,7 +290,7 @@ static void poolFree(void *arg, void *ptr) {
pMem->prev->next = pMem->next; pMem->prev->next = pMem->next;
pPool->size -= pMem->size; pPool->size -= pMem->size;
tdbOsFree(pMem); taosMemoryFree(pMem);
} }
int32_t tsdbInitSma(STsdb *pTsdb) { int32_t tsdbInitSma(STsdb *pTsdb) {

View File

@ -56,11 +56,11 @@ static inline int tsdbSmaKeyCmpr(const void *arg1, int len1, const void *arg2, i
static int32_t tsdbOpenDBDb(TDB **ppDB, TENV *pEnv, const char *pFName) { static int32_t tsdbOpenDBDb(TDB **ppDB, TENV *pEnv, const char *pFName) {
int ret; int ret;
FKeyComparator compFunc; tdb_cmpr_fn_t compFunc;
// Create a database // Create a database
compFunc = tsdbSmaKeyCmpr; compFunc = tsdbSmaKeyCmpr;
ret = tdbDbOpen(pFName, TDB_VARIANT_LEN, TDB_VARIANT_LEN, compFunc, pEnv, ppDB); ret = tdbDbOpen(pFName, -1, -1, compFunc, pEnv, ppDB);
return 0; return 0;
} }
@ -97,7 +97,7 @@ int32_t tsdbCloseDBF(SDBFile *pDBF) {
int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *pKey, int32_t keyLen, void *pVal, int32_t valLen, TXN *txn) { int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *pKey, int32_t keyLen, void *pVal, int32_t valLen, TXN *txn) {
int32_t ret; int32_t ret;
ret = tdbDbInsert(pDBF->pDB, pKey, keyLen, pVal, valLen, txn); ret = tdbDbPut(pDBF->pDB, pKey, keyLen, pVal, valLen, txn);
if (ret < 0) { if (ret < 0) {
tsdbError("Failed to create insert sma data into db, ret = %d", ret); tsdbError("Failed to create insert sma data into db, ret = %d", ret);
return -1; return -1;

View File

@ -60,9 +60,10 @@ static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg) {
SSubmitBlk *pBlock = NULL; SSubmitBlk *pBlock = NULL;
SSubmitBlkIter blkIter = {0}; SSubmitBlkIter blkIter = {0};
STSRow *row = NULL; STSRow *row = NULL;
TSKEY now = taosGetTimestamp(pTsdb->config.precision); STsdbCfg *pCfg = REPO_CFG(pTsdb);
TSKEY minKey = now - tsTickPerDay[pTsdb->config.precision] * pTsdb->config.keep2; TSKEY now = taosGetTimestamp(pCfg->precision);
TSKEY maxKey = now + tsTickPerDay[pTsdb->config.precision] * pTsdb->config.days; TSKEY minKey = now - tsTickPerDay[pCfg->precision] * pCfg->keep2;
TSKEY maxKey = now + tsTickPerDay[pCfg->precision] * pCfg->days;
terrno = TSDB_CODE_SUCCESS; terrno = TSDB_CODE_SUCCESS;
pMsg->length = htonl(pMsg->length); pMsg->length = htonl(pMsg->length);

View File

@ -42,13 +42,13 @@ int vnodeBegin(SVnode *pVnode) {
// begin meta // begin meta
if (metaBegin(pVnode->pMeta) < 0) { if (metaBegin(pVnode->pMeta) < 0) {
vError("vgId: %d failed to begin meta since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to begin meta since %s", TD_VID(pVnode), tstrerror(terrno));
return -1; return -1;
} }
// begin tsdb // begin tsdb
if (tsdbBegin(pVnode->pTsdb) < 0) { if (tsdbBegin(pVnode->pTsdb) < 0) {
vError("vgId: %d failed to begin tsdb since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to begin tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
return -1; return -1;
} }
@ -93,7 +93,7 @@ int vnodeSaveInfo(const char *dir, const SVnodeInfo *pInfo) {
// free info binary // free info binary
taosMemoryFree(data); taosMemoryFree(data);
vInfo("vgId: %d vnode info is saved, fname: %s", pInfo->config.vgId, fname); vInfo("vgId:%d vnode info is saved, fname: %s", pInfo->config.vgId, fname);
return 0; return 0;
@ -115,7 +115,7 @@ int vnodeCommitInfo(const char *dir, const SVnodeInfo *pInfo) {
return -1; return -1;
} }
vInfo("vgId: %d vnode info is committed", pInfo->config.vgId); vInfo("vgId:%d vnode info is committed", pInfo->config.vgId);
return 0; return 0;
} }

View File

@ -23,13 +23,13 @@ int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
// check config // check config
if (vnodeCheckCfg(pCfg) < 0) { if (vnodeCheckCfg(pCfg) < 0) {
vError("vgId: %d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno)); vError("vgId:%d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno));
return -1; return -1;
} }
// create vnode env // create vnode env
if (tfsMkdir(pTfs, path) < 0) { if (tfsMkdir(pTfs, path) < 0) {
vError("vgId: %d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno)); vError("vgId:%d failed to create vnode since: %s", pCfg->vgId, tstrerror(terrno));
return -1; return -1;
} }
@ -39,11 +39,11 @@ int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
info.state.applied = -1; info.state.applied = -1;
if (vnodeSaveInfo(dir, &info) < 0 || vnodeCommitInfo(dir, &info) < 0) { if (vnodeSaveInfo(dir, &info) < 0 || vnodeCommitInfo(dir, &info) < 0) {
vError("vgId: %d failed to save vnode config since %s", pCfg->vgId, tstrerror(terrno)); vError("vgId:%d failed to save vnode config since %s", pCfg->vgId, tstrerror(terrno));
return -1; return -1;
} }
vInfo("vgId: %d vnode is created", pCfg->vgId); vInfo("vgId:%d vnode is created", pCfg->vgId);
return 0; return 0;
} }
@ -70,7 +70,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
pVnode = (SVnode *)taosMemoryCalloc(1, sizeof(*pVnode) + strlen(path) + 1); pVnode = (SVnode *)taosMemoryCalloc(1, sizeof(*pVnode) + strlen(path) + 1);
if (pVnode == NULL) { if (pVnode == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
vError("vgId: %d failed to open vnode since %s", info.config.vgId, tstrerror(terrno)); vError("vgId:%d failed to open vnode since %s", info.config.vgId, tstrerror(terrno));
return NULL; return NULL;
} }
@ -85,13 +85,13 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
// open buffer pool // open buffer pool
if (vnodeOpenBufPool(pVnode, pVnode->config.isHeap ? 0 : pVnode->config.szBuf / 3) < 0) { if (vnodeOpenBufPool(pVnode, pVnode->config.isHeap ? 0 : pVnode->config.szBuf / 3) < 0) {
vError("vgId: %d failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open meta // open meta
if (metaOpen(pVnode, &pVnode->pMeta) < 0) { if (metaOpen(pVnode, &pVnode->pMeta) < 0) {
vError("vgId: %d failed to open vnode meta since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open vnode meta since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
@ -122,7 +122,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_WAL_DIR); sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_WAL_DIR);
pVnode->pWal = walOpen(tdir, &(pVnode->config.walCfg)); pVnode->pWal = walOpen(tdir, &(pVnode->config.walCfg));
if (pVnode->pWal == NULL) { if (pVnode->pWal == NULL) {
vError("vgId: %d failed to open vnode wal since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open vnode wal since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
@ -130,25 +130,25 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_TQ_DIR); sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_TQ_DIR);
pVnode->pTq = tqOpen(tdir, pVnode, pVnode->pWal); pVnode->pTq = tqOpen(tdir, pVnode, pVnode->pWal);
if (pVnode->pTq == NULL) { if (pVnode->pTq == NULL) {
vError("vgId: %d failed to open vnode tq since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open vnode tq since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open query // open query
if (vnodeQueryOpen(pVnode)) { if (vnodeQueryOpen(pVnode)) {
vError("vgId: %d failed to open vnode query since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open vnode query since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// vnode begin // vnode begin
if (vnodeBegin(pVnode) < 0) { if (vnodeBegin(pVnode) < 0) {
vError("vgId: %d failed to begin since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to begin since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
// open sync // open sync
if (vnodeSyncOpen(pVnode, dir)) { if (vnodeSyncOpen(pVnode, dir)) {
vError("vgId: %d failed to open sync since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to open sync since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }

View File

@ -17,10 +17,10 @@
static int vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp); static int vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp);
static int vnodeProcessAlterStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp); static int vnodeProcessAlterStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessDropStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp); static int vnodeProcessDropStbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp); static int vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp);
static int vnodeProcessAlterTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp); static int vnodeProcessAlterTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessDropTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp); static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp); static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) { int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) {
@ -45,6 +45,47 @@ int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) {
#endif #endif
return 0; return 0;
} }
static void tdSRowDemo() {
#define DEMO_N_COLS 3
int16_t schemaVersion = 0;
int32_t numOfCols = DEMO_N_COLS; // ts + int
SRowBuilder rb = {0};
SSchema schema[DEMO_N_COLS] = {
{.type = TSDB_DATA_TYPE_TIMESTAMP, .colId = 1, .name = "ts", .bytes = 8, .flags = SCHEMA_SMA_ON},
{.type = TSDB_DATA_TYPE_INT, .colId = 2, .name = "c1", .bytes = 4, .flags = SCHEMA_SMA_ON},
{.type = TSDB_DATA_TYPE_INT, .colId = 3, .name = "c2", .bytes = 4, .flags = SCHEMA_SMA_ON}};
SSchema *pSchema = schema;
STSchema *pTSChema = tdGetSTSChemaFromSSChema(&pSchema, numOfCols);
tdSRowInit(&rb, schemaVersion);
tdSRowSetTpInfo(&rb, numOfCols, pTSChema->flen);
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSChema);
void *row = taosMemoryCalloc(1, maxLen); // make sure the buffer is enough
// set row buf
tdSRowResetBuf(&rb, row);
for (int32_t idx = 0; idx < pTSChema->numOfCols; ++idx) {
STColumn *pColumn = pTSChema->columns + idx;
if (idx == 0) {
int64_t tsKey = 1651234567;
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, &tsKey, true, pColumn->offset, idx);
} else if (idx == 1) {
int32_t val1 = 10;
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, &val1, true, pColumn->offset, idx);
} else {
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NONE, NULL, true, pColumn->offset, idx);
}
}
// print
tdSRowPrint(row, pTSChema, __func__);
taosMemoryFree(pTSChema);
}
int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg *pRsp) { int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg *pRsp) {
void *ptr = NULL; void *ptr = NULL;
@ -52,7 +93,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
int len; int len;
int ret; int ret;
vTrace("vgId: %d start to process write request %s, version %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), vTrace("vgId:%d start to process write request %s, version %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
version); version);
pVnode->state.applied = version; pVnode->state.applied = version;
@ -62,7 +103,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
len = pMsg->contLen - sizeof(SMsgHead); len = pMsg->contLen - sizeof(SMsgHead);
if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) { if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) {
vError("vgId: %d failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno));
return -1; return -1;
} }
@ -75,7 +116,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
if (vnodeProcessAlterStbReq(pVnode, pReq, len, pRsp) < 0) goto _err; if (vnodeProcessAlterStbReq(pVnode, pReq, len, pRsp) < 0) goto _err;
break; break;
case TDMT_VND_DROP_STB: case TDMT_VND_DROP_STB:
if (vnodeProcessDropStbReq(pVnode, pReq, len, pRsp) < 0) goto _err; if (vnodeProcessDropStbReq(pVnode, version, pReq, len, pRsp) < 0) goto _err;
break; break;
case TDMT_VND_CREATE_TABLE: case TDMT_VND_CREATE_TABLE:
if (vnodeProcessCreateTbReq(pVnode, version, pReq, len, pRsp) < 0) goto _err; if (vnodeProcessCreateTbReq(pVnode, version, pReq, len, pRsp) < 0) goto _err;
@ -84,7 +125,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
if (vnodeProcessAlterTbReq(pVnode, pReq, len, pRsp) < 0) goto _err; if (vnodeProcessAlterTbReq(pVnode, pReq, len, pRsp) < 0) goto _err;
break; break;
case TDMT_VND_DROP_TABLE: case TDMT_VND_DROP_TABLE:
if (vnodeProcessDropTbReq(pVnode, pReq, len, pRsp) < 0) goto _err; if (vnodeProcessDropTbReq(pVnode, version, pReq, len, pRsp) < 0) goto _err;
break; break;
case TDMT_VND_CREATE_SMA: { // timeRangeSMA case TDMT_VND_CREATE_SMA: { // timeRangeSMA
if (tsdbCreateTSma(pVnode->pTsdb, POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead))) < 0) { if (tsdbCreateTSma(pVnode->pTsdb, POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead))) < 0) {
@ -119,7 +160,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
break; break;
} }
vDebug("vgId: %d process %s request success, version: %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), version); vDebug("vgId:%d process %s request success, version: %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), version);
// commit if need // commit if need
if (vnodeShouldCommit(pVnode)) { if (vnodeShouldCommit(pVnode)) {
@ -134,7 +175,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
return 0; return 0;
_err: _err:
vDebug("vgId: %d process %s request failed since %s, version: %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), vDebug("vgId:%d process %s request failed since %s, version: %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
tstrerror(terrno), version); tstrerror(terrno), version);
return -1; return -1;
} }
@ -409,9 +450,32 @@ static int vnodeProcessAlterStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpc
return 0; return 0;
} }
static int vnodeProcessDropStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp) { static int vnodeProcessDropStbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
// TODO SVDropStbReq req = {0};
// ASSERT(0); int rcode = TSDB_CODE_SUCCESS;
SCoder coder = {0};
pRsp->msgType = TDMT_VND_CREATE_STB_RSP;
pRsp->pCont = NULL;
pRsp->contLen = 0;
// decode request
tCoderInit(&coder, TD_LITTLE_ENDIAN, pReq, len, TD_DECODER);
if (tDecodeSVDropStbReq(&coder, &req) < 0) {
rcode = TSDB_CODE_INVALID_MSG;
goto _exit;
}
// process request
// if (metaDropSTable(pVnode->pMeta, version, &req) < 0) {
// rcode = terrno;
// goto _exit;
// }
// return rsp
_exit:
pRsp->code = rcode;
tCoderClear(&coder);
return 0; return 0;
} }
@ -421,9 +485,15 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcM
return 0; return 0;
} }
static int vnodeProcessDropTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp) { static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
// TODO SVDropTbReq req = {0};
ASSERT(0); SVDropTbReq rsp = {0};
// decode req
// process req
// return rsp
return 0; return 0;
} }

View File

@ -375,6 +375,7 @@ typedef struct SStreamBlockScanInfo {
uint64_t numOfExec; // execution times uint64_t numOfExec; // execution times
void* readerHandle; // stream block reader handle void* readerHandle; // stream block reader handle
SArray* pColMatchInfo; // SArray* pColMatchInfo; //
SNode* pCondition;
} SStreamBlockScanInfo; } SStreamBlockScanInfo;
typedef struct SSysTableScanInfo { typedef struct SSysTableScanInfo {
@ -672,7 +673,7 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx
const STableGroupInfo* pTableGroupInfo); const STableGroupInfo* pTableGroupInfo);
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo); SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo);
SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList,
SArray* pTableIdList, SExecTaskInfo* pTaskInfo); SArray* pTableIdList, SExecTaskInfo* pTaskInfo, SNode* pConditions);
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal, SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal,

View File

@ -6538,7 +6538,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
int32_t numOfCols = 0; int32_t numOfCols = 0;
SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols); SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
SOperatorInfo* pOperator = SOperatorInfo* pOperator =
createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo); createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo, pScanPhyNode->node.pConditions);
taosArrayDestroy(tableIdList); taosArrayDestroy(tableIdList);
return pOperator; return pOperator;
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {

View File

@ -514,6 +514,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
// NOTE: this operator does never check if current status is done or not // NOTE: this operator does never check if current status is done or not
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStreamBlockScanInfo* pInfo = pOperator->info; SStreamBlockScanInfo* pInfo = pOperator->info;
int32_t rows = 0;
pTaskInfo->code = pOperator->fpSet._openFn(pOperator); pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
if (pTaskInfo->code != TSDB_CODE_SUCCESS || pOperator->status == OP_EXEC_DONE) { if (pTaskInfo->code != TSDB_CODE_SUCCESS || pOperator->status == OP_EXEC_DONE) {
@ -580,6 +581,8 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
pTaskInfo->code = terrno; pTaskInfo->code = terrno;
return NULL; return NULL;
} }
rows = pBlockInfo->rows;
doFilter(pInfo->pCondition, pInfo->pRes);
break; break;
} }
@ -588,16 +591,16 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
pInfo->numOfExec++; pInfo->numOfExec++;
pInfo->numOfRows += pBlockInfo->rows; pInfo->numOfRows += pBlockInfo->rows;
if (pBlockInfo->rows == 0) { if (rows == 0) {
pOperator->status = OP_EXEC_DONE; pOperator->status = OP_EXEC_DONE;
} }
return (pBlockInfo->rows == 0) ? NULL : pInfo->pRes; return (rows == 0) ? NULL : pInfo->pRes;
} }
} }
SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList,
SArray* pTableIdList, SExecTaskInfo* pTaskInfo) { SArray* pTableIdList, SExecTaskInfo* pTaskInfo, SNode* pCondition) {
SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo)); SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) { if (pInfo == NULL || pOperator == NULL) {
@ -635,6 +638,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
pInfo->readerHandle = streamReadHandle; pInfo->readerHandle = streamReadHandle;
pInfo->pRes = pResBlock; pInfo->pRes = pResBlock;
pInfo->pCondition = pCondition;
pOperator->name = "StreamBlockScanOperator"; pOperator->name = "StreamBlockScanOperator";
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;

View File

@ -588,6 +588,259 @@ static int32_t jsonToLogicSortNode(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkPartitionLogicPlanPartitionKeys = "PartitionKeys";
static int32_t logicPartitionNodeToJson(const void* pObj, SJson* pJson) {
const SPartitionLogicNode* pNode = (const SPartitionLogicNode*)pObj;
int32_t code = logicPlanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkPartitionLogicPlanPartitionKeys, pNode->pPartitionKeys);
}
return code;
}
static int32_t jsonToLogicPartitionNode(const SJson* pJson, void* pObj) {
SPartitionLogicNode* pNode = (SPartitionLogicNode*)pObj;
int32_t code = jsonToLogicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkPartitionLogicPlanPartitionKeys, &pNode->pPartitionKeys);
}
return code;
}
static const char* jkSubplanIdQueryId = "QueryId";
static const char* jkSubplanIdGroupId = "GroupId";
static const char* jkSubplanIdSubplanId = "SubplanId";
static int32_t subplanIdToJson(const void* pObj, SJson* pJson) {
const SSubplanId* pNode = (const SSubplanId*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkSubplanIdQueryId, pNode->queryId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkSubplanIdGroupId, pNode->groupId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkSubplanIdSubplanId, pNode->subplanId);
}
return code;
}
static int32_t jsonToSubplanId(const SJson* pJson, void* pObj) {
SSubplanId* pNode = (SSubplanId*)pObj;
int32_t code = tjsonGetUBigIntValue(pJson, jkSubplanIdQueryId, &pNode->queryId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkSubplanIdGroupId, &pNode->groupId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkSubplanIdSubplanId, &pNode->subplanId);
}
return code;
}
static const char* jkEndPointFqdn = "Fqdn";
static const char* jkEndPointPort = "Port";
static int32_t epToJson(const void* pObj, SJson* pJson) {
const SEp* pNode = (const SEp*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkEndPointFqdn, pNode->fqdn);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkEndPointPort, pNode->port);
}
return code;
}
static int32_t jsonToEp(const SJson* pJson, void* pObj) {
SEp* pNode = (SEp*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkEndPointFqdn, pNode->fqdn);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetSmallIntValue(pJson, jkEndPointPort, &pNode->port);
}
return code;
}
static const char* jkEpSetInUse = "InUse";
static const char* jkEpSetNumOfEps = "NumOfEps";
static const char* jkEpSetEps = "Eps";
static int32_t epSetToJson(const void* pObj, SJson* pJson) {
const SEpSet* pNode = (const SEpSet*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkEpSetInUse, pNode->inUse);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkEpSetNumOfEps, pNode->numOfEps);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddArray(pJson, jkEpSetEps, epToJson, pNode->eps, sizeof(SEp), pNode->numOfEps);
}
return code;
}
static int32_t jsonToEpSet(const SJson* pJson, void* pObj) {
SEpSet* pNode = (SEpSet*)pObj;
int32_t code = tjsonGetTinyIntValue(pJson, jkEpSetInUse, &pNode->inUse);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetTinyIntValue(pJson, jkEpSetNumOfEps, &pNode->numOfEps);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToArray(pJson, jkEpSetEps, jsonToEp, pNode->eps, sizeof(SEp));
}
return code;
}
static const char* jkVgroupInfoVgId = "VgId";
static const char* jkVgroupInfoHashBegin = "HashBegin";
static const char* jkVgroupInfoHashEnd = "HashEnd";
static const char* jkVgroupInfoEpSet = "EpSet";
static const char* jkVgroupInfoNumOfTable = "NumOfTable";
static int32_t vgroupInfoToJson(const void* pObj, SJson* pJson) {
const SVgroupInfo* pNode = (const SVgroupInfo*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkVgroupInfoVgId, pNode->vgId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoHashBegin, pNode->hashBegin);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoHashEnd, pNode->hashEnd);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVgroupInfoEpSet, epSetToJson, &pNode->epSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoNumOfTable, pNode->numOfTable);
}
return code;
}
static int32_t jsonToVgroupInfo(const SJson* pJson, void* pObj) {
SVgroupInfo* pNode = (SVgroupInfo*)pObj;
int32_t code = tjsonGetIntValue(pJson, jkVgroupInfoVgId, &pNode->vgId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUIntValue(pJson, jkVgroupInfoHashBegin, &pNode->hashBegin);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUIntValue(pJson, jkVgroupInfoHashEnd, &pNode->hashEnd);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToObject(pJson, jkVgroupInfoEpSet, jsonToEpSet, &pNode->epSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVgroupInfoNumOfTable, &pNode->numOfTable);
}
return code;
}
static const char* jkVgroupsInfoNum = "Num";
static const char* jkVgroupsInfoVgroups = "Vgroups";
static int32_t vgroupsInfoToJson(const void* pObj, SJson* pJson) {
const SVgroupsInfo* pNode = (const SVgroupsInfo*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkVgroupsInfoNum, pNode->numOfVgroups);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddArray(pJson, jkVgroupsInfoVgroups, vgroupInfoToJson, pNode->vgroups, sizeof(SVgroupInfo),
pNode->numOfVgroups);
}
return code;
}
static int32_t jsonToVgroupsInfo(const SJson* pJson, void* pObj) {
SVgroupsInfo* pNode = (SVgroupsInfo*)pObj;
int32_t code = tjsonGetIntValue(pJson, jkVgroupsInfoNum, &pNode->numOfVgroups);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToArray(pJson, jkVgroupsInfoVgroups, jsonToVgroupInfo, pNode->vgroups, sizeof(SVgroupInfo));
}
return code;
}
static const char* jkLogicSubplanId = "Id";
static const char* jkLogicSubplanChildren = "Children";
static const char* jkLogicSubplanRootNode = "RootNode";
static const char* jkLogicSubplanType = "SubplanType";
static const char* jkLogicSubplanVgroupsSize = "VgroupsSize";
static const char* jkLogicSubplanVgroups = "Vgroups";
static const char* jkLogicSubplanLevel = "Level";
static const char* jkLogicSubplanSplitFlag = "SplitFlag";
static int32_t logicSubplanToJson(const void* pObj, SJson* pJson) {
const SLogicSubplan* pNode = (const SLogicSubplan*)pObj;
int32_t code = tjsonAddObject(pJson, jkLogicSubplanId, subplanIdToJson, &pNode->id);
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkLogicSubplanChildren, pNode->pChildren);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkLogicSubplanRootNode, nodeToJson, pNode->pNode);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkLogicSubplanType, pNode->subplanType);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkLogicSubplanVgroupsSize, VGROUPS_INFO_SIZE(pNode->pVgroupList));
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkLogicSubplanVgroups, vgroupsInfoToJson, pNode->pVgroupList);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkLogicSubplanLevel, pNode->level);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkLogicSubplanSplitFlag, pNode->splitFlag);
}
return code;
}
static int32_t jsonToLogicSubplan(const SJson* pJson, void* pObj) {
SLogicSubplan* pNode = (SLogicSubplan*)pObj;
int32_t code = tjsonToObject(pJson, jkLogicSubplanId, jsonToSubplanId, &pNode->id);
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkLogicSubplanChildren, &pNode->pChildren);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkLogicSubplanRootNode, (SNode**)&pNode->pNode);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkLogicSubplanType, pNode->subplanType);
}
int32_t objSize = 0;
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkLogicSubplanVgroupsSize, &objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonMakeObject(pJson, jkLogicSubplanVgroups, jsonToVgroupsInfo, (void**)&pNode->pVgroupList, objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkLogicSubplanLevel, &pNode->level);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkLogicSubplanSplitFlag, &pNode->splitFlag);
}
return code;
}
static const char* jkJoinLogicPlanJoinType = "JoinType"; static const char* jkJoinLogicPlanJoinType = "JoinType";
static const char* jkJoinLogicPlanOnConditions = "OnConditions"; static const char* jkJoinLogicPlanOnConditions = "OnConditions";
@ -837,63 +1090,6 @@ static int32_t physiStreamScanNodeToJson(const void* pObj, SJson* pJson) { retur
static int32_t jsonToPhysiStreamScanNode(const SJson* pJson, void* pObj) { return jsonToPhysiScanNode(pJson, pObj); } static int32_t jsonToPhysiStreamScanNode(const SJson* pJson, void* pObj) { return jsonToPhysiScanNode(pJson, pObj); }
static const char* jkEndPointFqdn = "Fqdn";
static const char* jkEndPointPort = "Port";
static int32_t epToJson(const void* pObj, SJson* pJson) {
const SEp* pNode = (const SEp*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkEndPointFqdn, pNode->fqdn);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkEndPointPort, pNode->port);
}
return code;
}
static int32_t jsonToEp(const SJson* pJson, void* pObj) {
SEp* pNode = (SEp*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkEndPointFqdn, pNode->fqdn);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetSmallIntValue(pJson, jkEndPointPort, &pNode->port);
}
return code;
}
static const char* jkEpSetInUse = "InUse";
static const char* jkEpSetNumOfEps = "NumOfEps";
static const char* jkEpSetEps = "Eps";
static int32_t epSetToJson(const void* pObj, SJson* pJson) {
const SEpSet* pNode = (const SEpSet*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkEpSetInUse, pNode->inUse);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkEpSetNumOfEps, pNode->numOfEps);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddArray(pJson, jkEpSetEps, epToJson, pNode->eps, sizeof(SEp), pNode->numOfEps);
}
return code;
}
static int32_t jsonToEpSet(const SJson* pJson, void* pObj) {
SEpSet* pNode = (SEpSet*)pObj;
int32_t code = tjsonGetTinyIntValue(pJson, jkEpSetInUse, &pNode->inUse);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetTinyIntValue(pJson, jkEpSetNumOfEps, &pNode->numOfEps);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToArray(pJson, jkEpSetEps, jsonToEp, pNode->eps, sizeof(SEp));
}
return code;
}
static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet"; static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet";
static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite"; static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite";
static const char* jkSysTableScanPhysiPlanAccountId = "AccountId"; static const char* jkSysTableScanPhysiPlanAccountId = "AccountId";
@ -1342,38 +1538,6 @@ static int32_t physiDispatchNodeToJson(const void* pObj, SJson* pJson) { return
static int32_t jsonToPhysiDispatchNode(const SJson* pJson, void* pObj) { return jsonToPhysicDataSinkNode(pJson, pObj); } static int32_t jsonToPhysiDispatchNode(const SJson* pJson, void* pObj) { return jsonToPhysicDataSinkNode(pJson, pObj); }
static const char* jkSubplanIdQueryId = "QueryId";
static const char* jkSubplanIdGroupId = "GroupId";
static const char* jkSubplanIdSubplanId = "SubplanId";
static int32_t subplanIdToJson(const void* pObj, SJson* pJson) {
const SSubplanId* pNode = (const SSubplanId*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkSubplanIdQueryId, pNode->queryId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkSubplanIdGroupId, pNode->groupId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkSubplanIdSubplanId, pNode->subplanId);
}
return code;
}
static int32_t jsonToSubplanId(const SJson* pJson, void* pObj) {
SSubplanId* pNode = (SSubplanId*)pObj;
int32_t code = tjsonGetUBigIntValue(pJson, jkSubplanIdQueryId, &pNode->queryId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkSubplanIdGroupId, &pNode->groupId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkSubplanIdSubplanId, &pNode->subplanId);
}
return code;
}
static const char* jkQueryNodeAddrId = "Id"; static const char* jkQueryNodeAddrId = "Id";
static const char* jkQueryNodeAddrInUse = "InUse"; static const char* jkQueryNodeAddrInUse = "InUse";
static const char* jkQueryNodeAddrNumOfEps = "NumOfEps"; static const char* jkQueryNodeAddrNumOfEps = "NumOfEps";
@ -1747,23 +1911,51 @@ static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
break; break;
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
code = tjsonGetBoolValue(pJson, jkValueDatum, &pNode->datum.b); code = tjsonGetBoolValue(pJson, jkValueDatum, &pNode->datum.b);
*(bool*)&pNode->typeData = pNode->datum.b;
break; break;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
*(int8_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
*(int16_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
*(int32_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
*(int64_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i); code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
*(int64_t*)&pNode->typeData = pNode->datum.i;
break; break;
case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_UTINYINT:
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
*(uint8_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_USMALLINT:
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
*(uint16_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_UINT:
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
*(uint32_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_UBIGINT:
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u); code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
*(uint64_t*)&pNode->typeData = pNode->datum.u;
break; break;
case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_FLOAT:
code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
*(float*)&pNode->typeData = pNode->datum.d;
break;
case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_DOUBLE:
code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d); code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
*(double*)&pNode->typeData = pNode->datum.d;
break; break;
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARCHAR:
@ -1964,78 +2156,6 @@ static int32_t jsonToTableNode(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkVgroupInfoVgId = "VgId";
static const char* jkVgroupInfoHashBegin = "HashBegin";
static const char* jkVgroupInfoHashEnd = "HashEnd";
static const char* jkVgroupInfoEpSet = "EpSet";
static const char* jkVgroupInfoNumOfTable = "NumOfTable";
static int32_t vgroupInfoToJson(const void* pObj, SJson* pJson) {
const SVgroupInfo* pNode = (const SVgroupInfo*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkVgroupInfoVgId, pNode->vgId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoHashBegin, pNode->hashBegin);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoHashEnd, pNode->hashEnd);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVgroupInfoEpSet, epSetToJson, &pNode->epSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVgroupInfoNumOfTable, pNode->numOfTable);
}
return code;
}
static int32_t jsonToVgroupInfo(const SJson* pJson, void* pObj) {
SVgroupInfo* pNode = (SVgroupInfo*)pObj;
int32_t code = tjsonGetIntValue(pJson, jkVgroupInfoVgId, &pNode->vgId);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUIntValue(pJson, jkVgroupInfoHashBegin, &pNode->hashBegin);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUIntValue(pJson, jkVgroupInfoHashEnd, &pNode->hashEnd);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToObject(pJson, jkVgroupInfoEpSet, jsonToEpSet, &pNode->epSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVgroupInfoNumOfTable, &pNode->numOfTable);
}
return code;
}
static const char* jkVgroupsInfoNum = "Num";
static const char* jkVgroupsInfoVgroups = "Vgroups";
static int32_t vgroupsInfoToJson(const void* pObj, SJson* pJson) {
const SVgroupsInfo* pNode = (const SVgroupsInfo*)pObj;
int32_t code = tjsonAddIntegerToObject(pJson, jkVgroupsInfoNum, pNode->numOfVgroups);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddArray(pJson, jkVgroupsInfoVgroups, vgroupInfoToJson, pNode->vgroups, sizeof(SVgroupInfo),
pNode->numOfVgroups);
}
return code;
}
static int32_t jsonToVgroupsInfo(const SJson* pJson, void* pObj) {
SVgroupsInfo* pNode = (SVgroupsInfo*)pObj;
int32_t code = tjsonGetIntValue(pJson, jkVgroupsInfoNum, &pNode->numOfVgroups);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonToArray(pJson, jkVgroupsInfoVgroups, jsonToVgroupInfo, pNode->vgroups, sizeof(SVgroupInfo));
}
return code;
}
static const char* jkRealTableMetaSize = "MetaSize"; static const char* jkRealTableMetaSize = "MetaSize";
static const char* jkRealTableMeta = "Meta"; static const char* jkRealTableMeta = "Meta";
static const char* jkRealTableVgroupsInfoSize = "VgroupsInfoSize"; static const char* jkRealTableVgroupsInfoSize = "VgroupsInfoSize";
@ -2582,7 +2702,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
break; break;
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return logicSortNodeToJson(pObj, pJson); return logicSortNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_PARTITION:
return logicPartitionNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_SUBPLAN: case QUERY_NODE_LOGIC_SUBPLAN:
return logicSubplanToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN: case QUERY_NODE_LOGIC_PLAN:
break; break;
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
@ -2667,6 +2790,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicProjectNode(pJson, pObj); return jsonToLogicProjectNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return jsonToLogicSortNode(pJson, pObj); return jsonToLogicSortNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_PARTITION:
return jsonToLogicPartitionNode(pJson, pObj);
case QUERY_NODE_LOGIC_SUBPLAN:
return jsonToLogicSubplan(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
return jsonToPhysiTagScanNode(pJson, pObj); return jsonToPhysiTagScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:

View File

@ -871,21 +871,18 @@ void nodesClearList(SNodeList* pList) {
void* nodesGetValueFromNode(SValueNode* pNode) { void* nodesGetValueFromNode(SValueNode* pNode) {
switch (pNode->node.resType.type) { switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
return (void*)&pNode->datum.b;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
return (void*)&pNode->datum.i;
case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_UBIGINT:
return (void*)&pNode->datum.u;
case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_DOUBLE:
return (void*)&pNode->datum.d; return (void*)&pNode->typeData;
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY: case TSDB_DATA_TYPE_VARBINARY:
@ -897,6 +894,68 @@ void* nodesGetValueFromNode(SValueNode* pNode) {
return NULL; return NULL;
} }
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value) {
switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_BOOL:
pNode->datum.b = *(bool*)value;
*(bool*)&pNode->typeData = pNode->datum.b;
break;
case TSDB_DATA_TYPE_TINYINT:
pNode->datum.i = *(int8_t*)value;
*(int8_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_SMALLINT:
pNode->datum.i = *(int16_t*)value;
*(int16_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_INT:
pNode->datum.i = *(int32_t*)value;
*(int32_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_BIGINT:
pNode->datum.i = *(int64_t*)value;
*(int64_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_TIMESTAMP:
pNode->datum.i = *(int64_t*)value;
*(int64_t*)&pNode->typeData = pNode->datum.i;
break;
case TSDB_DATA_TYPE_UTINYINT:
pNode->datum.u = *(int8_t*)value;
*(int8_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_USMALLINT:
pNode->datum.u = *(int16_t*)value;
*(int16_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_UINT:
pNode->datum.u = *(int32_t*)value;
*(int32_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_UBIGINT:
pNode->datum.u = *(uint64_t*)value;
*(uint64_t*)&pNode->typeData = pNode->datum.u;
break;
case TSDB_DATA_TYPE_FLOAT:
pNode->datum.d = *(float*)value;
*(float*)&pNode->typeData = pNode->datum.d;
break;
case TSDB_DATA_TYPE_DOUBLE:
pNode->datum.d = *(double*)value;
*(double*)&pNode->typeData = pNode->datum.d;
break;
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
pNode->datum.p = (char*)value;
break;
default:
return TSDB_CODE_QRY_APP_ERROR;
}
return TSDB_CODE_SUCCESS;
}
char* nodesGetStrValueFromNode(SValueNode* pNode) { char* nodesGetStrValueFromNode(SValueNode* pNode) {
switch (pNode->node.resType.type) { switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_BOOL: { case TSDB_DATA_TYPE_BOOL: {
@ -1090,30 +1149,31 @@ static EDealRes collectColumns(SNode* pNode, void* pContext) {
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type, int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
SNodeList** pCols) { SNodeList** pCols) {
if (NULL == pSelect || NULL == pCols) { if (NULL == pSelect || NULL == pCols) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_FAILED;
} }
SCollectColumnsCxt cxt = { SCollectColumnsCxt cxt = {
.errCode = TSDB_CODE_SUCCESS, .errCode = TSDB_CODE_SUCCESS,
.pTableAlias = pTableAlias, .pTableAlias = pTableAlias,
.collectType = type, .collectType = type,
.pCols = nodesMakeList(), .pCols = (NULL == *pCols ? nodesMakeList() : *pCols),
.pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)}; .pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)};
if (NULL == cxt.pCols || NULL == cxt.pColHash) { if (NULL == cxt.pCols || NULL == cxt.pColHash) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
*pCols = NULL;
nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt); nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
taosHashCleanup(cxt.pColHash); taosHashCleanup(cxt.pColHash);
if (TSDB_CODE_SUCCESS != cxt.errCode) { if (TSDB_CODE_SUCCESS != cxt.errCode) {
nodesDestroyList(cxt.pCols); nodesDestroyList(cxt.pCols);
return cxt.errCode; return cxt.errCode;
} }
if (0 == LIST_LENGTH(cxt.pCols)) { if (LIST_LENGTH(cxt.pCols) > 0) {
nodesDestroyList(cxt.pCols);
cxt.pCols = NULL;
}
*pCols = cxt.pCols; *pCols = cxt.pCols;
} else {
nodesDestroyList(cxt.pCols);
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -1134,7 +1194,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) { int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) {
if (NULL == pSelect || NULL == pFuncs) { if (NULL == pSelect || NULL == pFuncs) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_FAILED;
} }
SCollectFuncsCxt cxt = { SCollectFuncsCxt cxt = {
@ -1157,6 +1217,46 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNod
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
typedef struct SCollectSpecialNodesCxt {
int32_t errCode;
ENodeType type;
SNodeList* pNodes;
} SCollectSpecialNodesCxt;
static EDealRes collectSpecialNodes(SNode* pNode, void* pContext) {
SCollectSpecialNodesCxt* pCxt = (SCollectSpecialNodesCxt*)pContext;
if (pCxt->type == nodeType(pNode)) {
pCxt->errCode = nodesListStrictAppend(pCxt->pNodes, nodesCloneNode(pNode));
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
}
return DEAL_RES_CONTINUE;
}
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes) {
if (NULL == pSelect || NULL == pNodes) {
return TSDB_CODE_FAILED;
}
SCollectSpecialNodesCxt cxt = {
.errCode = TSDB_CODE_SUCCESS, .type = type, .pNodes = (NULL == *pNodes ? nodesMakeList() : *pNodes)};
if (NULL == cxt.pNodes) {
return TSDB_CODE_OUT_OF_MEMORY;
}
*pNodes = NULL;
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_GROUP_BY, collectSpecialNodes, &cxt);
if (TSDB_CODE_SUCCESS != cxt.errCode) {
nodesDestroyList(cxt.pNodes);
return cxt.errCode;
}
if (LIST_LENGTH(cxt.pNodes) > 0) {
*pNodes = cxt.pNodes;
} else {
nodesDestroyList(cxt.pNodes);
}
return TSDB_CODE_SUCCESS;
}
char* getFillModeString(EFillMode mode) { char* getFillModeString(EFillMode mode) {
switch (mode) { switch (mode) {
case FILL_MODE_NONE: case FILL_MODE_NONE:

View File

@ -30,9 +30,9 @@ typedef struct SAstCreateContext {
SParseContext* pQueryCxt; SParseContext* pQueryCxt;
SMsgBuf msgBuf; SMsgBuf msgBuf;
bool notSupport; bool notSupport;
bool valid;
SNode* pRootNode; SNode* pRootNode;
int16_t placeholderNo; int16_t placeholderNo;
int32_t errCode;
} SAstCreateContext; } SAstCreateContext;
typedef enum EDatabaseOptionType { typedef enum EDatabaseOptionType {

View File

@ -23,13 +23,12 @@
} }
%syntax_error { %syntax_error {
if (pCxt->valid) { if (TSDB_CODE_SUCCESS == pCxt->errCode) {
if(TOKEN.z) { if(TOKEN.z) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z);
} else { } else {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INCOMPLETE_SQL); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INCOMPLETE_SQL);
} }
pCxt->valid = false;
} }
} }
@ -42,8 +41,8 @@
%left NK_CONCAT. %left NK_CONCAT.
/************************************************ create/alter account *****************************************/ /************************************************ create/alter account *****************************************/
cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options. { pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options. { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
cmd ::= ALTER ACCOUNT NK_ID alter_account_options. { pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } cmd ::= ALTER ACCOUNT NK_ID alter_account_options. { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
%type account_options { int32_t } %type account_options { int32_t }
%destructor account_options { } %destructor account_options { }
@ -323,7 +322,7 @@ cmd ::= SHOW QNODES.
cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT, NULL, NULL); } cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT, NULL, NULL); }
cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, A, B); } cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, A, B); }
cmd ::= SHOW STREAMS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); } cmd ::= SHOW STREAMS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); }
cmd ::= SHOW ACCOUNTS. { pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } cmd ::= SHOW ACCOUNTS. { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
cmd ::= SHOW APPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT, NULL, NULL); } cmd ::= SHOW APPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT, NULL, NULL); }
cmd ::= SHOW CONNECTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT, NULL, NULL); } cmd ::= SHOW CONNECTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT, NULL, NULL); }
cmd ::= SHOW LICENCE. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCE_STMT, NULL, NULL); } cmd ::= SHOW LICENCE. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCE_STMT, NULL, NULL); }
@ -491,7 +490,7 @@ signed_literal(A) ::= NK_STRING(B).
signed_literal(A) ::= NK_BOOL(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &B); } signed_literal(A) ::= NK_BOOL(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &B); }
signed_literal(A) ::= TIMESTAMP NK_STRING(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &B); } signed_literal(A) ::= TIMESTAMP NK_STRING(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &B); }
signed_literal(A) ::= duration_literal(B). { A = releaseRawExprNode(pCxt, B); } signed_literal(A) ::= duration_literal(B). { A = releaseRawExprNode(pCxt, B); }
signed_literal(A) ::= NULL. { A = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, NULL); } signed_literal(A) ::= NULL(B). { A = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &B); }
signed_literal(A) ::= literal_func(B). { A = releaseRawExprNode(pCxt, B); } signed_literal(A) ::= literal_func(B). { A = releaseRawExprNode(pCxt, B); }
%type literal_list { SNodeList* } %type literal_list { SNodeList* }

View File

@ -21,7 +21,7 @@
#define CHECK_OUT_OF_MEM(p) \ #define CHECK_OUT_OF_MEM(p) \
do { \ do { \
if (NULL == (p)) { \ if (NULL == (p)) { \
pCxt->valid = false; \ pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "Out of memory"); \ snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "Out of memory"); \
return NULL; \ return NULL; \
} \ } \
@ -30,7 +30,7 @@
#define CHECK_RAW_EXPR_NODE(node) \ #define CHECK_RAW_EXPR_NODE(node) \
do { \ do { \
if (NULL == (node) || QUERY_NODE_RAW_EXPR != nodeType(node)) { \ if (NULL == (node) || QUERY_NODE_RAW_EXPR != nodeType(node)) { \
pCxt->valid = false; \ pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR; \
return NULL; \ return NULL; \
} \ } \
} while (0) } while (0)
@ -42,9 +42,9 @@ void initAstCreateContext(SParseContext* pParseCxt, SAstCreateContext* pCxt) {
pCxt->msgBuf.buf = pParseCxt->pMsg; pCxt->msgBuf.buf = pParseCxt->pMsg;
pCxt->msgBuf.len = pParseCxt->msgLen; pCxt->msgBuf.len = pParseCxt->msgLen;
pCxt->notSupport = false; pCxt->notSupport = false;
pCxt->valid = true;
pCxt->pRootNode = NULL; pCxt->pRootNode = NULL;
pCxt->placeholderNo = 0; pCxt->placeholderNo = 0;
pCxt->errCode = TSDB_CODE_SUCCESS;
} }
static void copyStringFormStringToken(SToken* pToken, char* pBuf, int32_t len) { static void copyStringFormStringToken(SToken* pToken, char* pBuf, int32_t len) {
@ -63,42 +63,38 @@ static void trimEscape(SToken* pName) {
static bool checkUserName(SAstCreateContext* pCxt, SToken* pUserName) { static bool checkUserName(SAstCreateContext* pCxt, SToken* pUserName) {
if (NULL == pUserName) { if (NULL == pUserName) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
} else { } else {
if (pUserName->n >= TSDB_USER_LEN) { if (pUserName->n >= TSDB_USER_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
pCxt->valid = false;
} }
} }
if (pCxt->valid) { if (TSDB_CODE_SUCCESS == pCxt->errCode) {
trimEscape(pUserName); trimEscape(pUserName);
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) { static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) {
if (NULL == pPasswordToken) { if (NULL == pPasswordToken) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
} else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) { } else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
pCxt->valid = false;
} else { } else {
strncpy(pPassword, pPasswordToken->z, pPasswordToken->n); strncpy(pPassword, pPasswordToken->z, pPasswordToken->n);
strdequote(pPassword); strdequote(pPassword);
if (strtrim(pPassword) <= 0) { if (strtrim(pPassword) <= 0) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY);
pCxt->valid = false;
} }
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, char* pFqdn, int32_t* pPort) { static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, char* pFqdn, int32_t* pPort) {
if (NULL == pEp) { if (NULL == pEp) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
} else if (pEp->n >= TSDB_FQDN_LEN + 2 + 6) { // format 'fqdn:port' } else if (pEp->n >= TSDB_FQDN_LEN + 2 + 6) { // format 'fqdn:port'
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
pCxt->valid = false;
} else { } else {
char ep[TSDB_FQDN_LEN + 2 + 6]; char ep[TSDB_FQDN_LEN + 2 + 6];
strncpy(ep, pEp->z, pEp->n); strncpy(ep, pEp->z, pEp->n);
@ -106,66 +102,59 @@ static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, ch
strtrim(ep); strtrim(ep);
char* pColon = strchr(ep, ':'); char* pColon = strchr(ep, ':');
if (NULL == pColon) { if (NULL == pColon) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT);
pCxt->valid = false;
} else { } else {
strncpy(pFqdn, ep, pColon - ep); strncpy(pFqdn, ep, pColon - ep);
*pPort = strtol(pColon + 1, NULL, 10); *pPort = strtol(pColon + 1, NULL, 10);
if (*pPort >= UINT16_MAX || *pPort <= 0) { if (*pPort >= UINT16_MAX || *pPort <= 0) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
pCxt->valid = false;
} }
} }
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkFqdn(SAstCreateContext* pCxt, const SToken* pFqdn) { static bool checkFqdn(SAstCreateContext* pCxt, const SToken* pFqdn) {
if (NULL == pFqdn) { if (NULL == pFqdn) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
} else { } else {
if (pFqdn->n >= TSDB_FQDN_LEN) { if (pFqdn->n >= TSDB_FQDN_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
pCxt->valid = false;
} }
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkPort(SAstCreateContext* pCxt, const SToken* pPortToken, int32_t* pPort) { static bool checkPort(SAstCreateContext* pCxt, const SToken* pPortToken, int32_t* pPort) {
if (NULL == pPortToken) { if (NULL == pPortToken) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
} else { } else {
*pPort = strtol(pPortToken->z, NULL, 10); *pPort = strtol(pPortToken->z, NULL, 10);
if (*pPort >= UINT16_MAX || *pPort <= 0) { if (*pPort >= UINT16_MAX || *pPort <= 0) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
pCxt->valid = false;
} }
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkDbName(SAstCreateContext* pCxt, SToken* pDbName, bool query) { static bool checkDbName(SAstCreateContext* pCxt, SToken* pDbName, bool query) {
if (NULL == pDbName) { if (NULL == pDbName) {
if (query && NULL == pCxt->pQueryCxt->db) { if (query && NULL == pCxt->pQueryCxt->db) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DB_NOT_SPECIFIED); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DB_NOT_SPECIFIED);
pCxt->valid = false;
} }
} else { } else {
trimEscape(pDbName); trimEscape(pDbName);
if (pDbName->n >= TSDB_DB_NAME_LEN) { if (pDbName->n >= TSDB_DB_NAME_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pDbName->z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pDbName->z);
pCxt->valid = false;
} }
} }
return pCxt->valid; return TSDB_CODE_SUCCESS == pCxt->errCode;
} }
static bool checkTableName(SAstCreateContext* pCxt, SToken* pTableName) { static bool checkTableName(SAstCreateContext* pCxt, SToken* pTableName) {
trimEscape(pTableName); trimEscape(pTableName);
if (NULL != pTableName && pTableName->n >= TSDB_TABLE_NAME_LEN) { if (NULL != pTableName && pTableName->n >= TSDB_TABLE_NAME_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pTableName->z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pTableName->z);
pCxt->valid = false;
return false; return false;
} }
return true; return true;
@ -174,8 +163,7 @@ static bool checkTableName(SAstCreateContext* pCxt, SToken* pTableName) {
static bool checkColumnName(SAstCreateContext* pCxt, SToken* pColumnName) { static bool checkColumnName(SAstCreateContext* pCxt, SToken* pColumnName) {
trimEscape(pColumnName); trimEscape(pColumnName);
if (NULL != pColumnName && pColumnName->n >= TSDB_COL_NAME_LEN) { if (NULL != pColumnName && pColumnName->n >= TSDB_COL_NAME_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pColumnName->z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pColumnName->z);
pCxt->valid = false;
return false; return false;
} }
return true; return true;
@ -184,8 +172,7 @@ static bool checkColumnName(SAstCreateContext* pCxt, SToken* pColumnName) {
static bool checkIndexName(SAstCreateContext* pCxt, SToken* pIndexName) { static bool checkIndexName(SAstCreateContext* pCxt, SToken* pIndexName) {
trimEscape(pIndexName); trimEscape(pIndexName);
if (NULL != pIndexName && pIndexName->n >= TSDB_INDEX_NAME_LEN) { if (NULL != pIndexName && pIndexName->n >= TSDB_INDEX_NAME_LEN) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pIndexName->z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pIndexName->z);
pCxt->valid = false;
return false; return false;
} }
return true; return true;
@ -224,7 +211,7 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) { if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return nil_token; return nil_token;
} }
SRawExprNode* target = (SRawExprNode*)pNode; SRawExprNode* target = (SRawExprNode*)pNode;
@ -235,16 +222,12 @@ SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode) { SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode) {
SNodeList* list = nodesMakeList(); SNodeList* list = nodesMakeList();
CHECK_OUT_OF_MEM(list); CHECK_OUT_OF_MEM(list);
if (TSDB_CODE_SUCCESS != nodesListAppend(list, pNode)) { pCxt->errCode = nodesListAppend(list, pNode);
pCxt->valid = false;
}
return list; return list;
} }
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode) { SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode) {
if (TSDB_CODE_SUCCESS != nodesListAppend(pList, pNode)) { pCxt->errCode = nodesListAppend(pList, pNode);
pCxt->valid = false;
}
return pList; return pList;
} }
@ -531,7 +514,7 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) {
} }
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) { SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
if (NULL == pNode || !pCxt->valid) { if (NULL == pNode || TSDB_CODE_SUCCESS != pCxt->errCode) {
return pNode; return pNode;
} }
int32_t len = TMIN(sizeof(((SExprNode*)pNode)->aliasName) - 1, pAlias->n); int32_t len = TMIN(sizeof(((SExprNode*)pNode)->aliasName) - 1, pAlias->n);
@ -995,7 +978,7 @@ static bool needDbShowStmt(ENodeType type) {
SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pDbName, SNode* pTbNamePattern) { SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pDbName, SNode* pTbNamePattern) {
if (needDbShowStmt(type) && NULL == pDbName && NULL == pCxt->pQueryCxt->db) { if (needDbShowStmt(type) && NULL == pDbName && NULL == pCxt->pQueryCxt->db) {
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "db not specified"); snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "db not specified");
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL; return NULL;
} }
SShowStmt* pStmt = nodesMakeNode(type); SShowStmt* pStmt = nodesMakeNode(type);
@ -1256,7 +1239,7 @@ SNode* createCompactStmt(SAstCreateContext* pCxt, SNodeList* pVgroups) {
SNode* createCreateFunctionStmt(SAstCreateContext* pCxt, bool ignoreExists, bool aggFunc, const SToken* pFuncName, SNode* createCreateFunctionStmt(SAstCreateContext* pCxt, bool ignoreExists, bool aggFunc, const SToken* pFuncName,
const SToken* pLibPath, SDataType dataType, int32_t bufSize) { const SToken* pLibPath, SDataType dataType, int32_t bufSize) {
if (pLibPath->n <= 2) { if (pLibPath->n <= 2) {
pCxt->valid = false; pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL; return NULL;
} }
SCreateFunctionStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_FUNCTION_STMT); SCreateFunctionStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_FUNCTION_STMT);

View File

@ -53,20 +53,20 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
} }
case TK_NK_ILLEGAL: { case TK_NK_ILLEGAL: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z); snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
cxt.valid = false; cxt.errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto abort_parse; goto abort_parse;
} }
case TK_NK_HEX: case TK_NK_HEX:
case TK_NK_OCT: case TK_NK_OCT:
case TK_NK_BIN: { case TK_NK_BIN: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z); snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
cxt.valid = false; cxt.errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto abort_parse; goto abort_parse;
} }
default: default:
Parse(pParser, t0.type, t0, &cxt); Parse(pParser, t0.type, t0, &cxt);
// ParseTrace(stdout, ""); // ParseTrace(stdout, "");
if (!cxt.valid) { if (TSDB_CODE_SUCCESS != cxt.errCode) {
goto abort_parse; goto abort_parse;
} }
} }
@ -74,7 +74,7 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
abort_parse: abort_parse:
ParseFree(pParser, (FFree)taosMemoryFree); ParseFree(pParser, (FFree)taosMemoryFree);
if (cxt.valid) { if (TSDB_CODE_SUCCESS == cxt.errCode) {
*pQuery = taosMemoryCalloc(1, sizeof(SQuery)); *pQuery = taosMemoryCalloc(1, sizeof(SQuery));
if (NULL == *pQuery) { if (NULL == *pQuery) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
@ -82,5 +82,5 @@ abort_parse:
(*pQuery)->pRoot = cxt.pRootNode; (*pQuery)->pRoot = cxt.pRootNode;
(*pQuery)->placeholderNum = cxt.placeholderNo; (*pQuery)->placeholderNum = cxt.placeholderNo;
} }
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED; return cxt.errCode;
} }

View File

@ -208,6 +208,23 @@ static int32_t calcConstProjections(SCalcConstContext* pCxt, SNodeList* pProject
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
int32_t code = calcConstList(pSelect->pGroupByList);
if (TSDB_CODE_SUCCESS == code) {
SNode* pNode = NULL;
FOREACH(pNode, pSelect->pGroupByList) {
SNode* pGroupPara = NULL;
FOREACH(pGroupPara, ((SGroupingSetNode*)pNode)->pParameterList) {
if (QUERY_NODE_VALUE != nodeType(pGroupPara)) {
return code;
}
}
}
DESTORY_LIST(pSelect->pGroupByList);
}
return code;
}
static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
int32_t code = calcConstProjections(pCxt, pSelect->pProjectionList, subquery); int32_t code = calcConstProjections(pCxt, pSelect->pProjectionList, subquery);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {

View File

@ -20,12 +20,12 @@
#include "functionMgt.h" #include "functionMgt.h"
#include "parUtil.h" #include "parUtil.h"
#include "scalar.h" #include "scalar.h"
#include "systable.h"
#include "tglobal.h" #include "tglobal.h"
#include "ttime.h" #include "ttime.h"
#include "systable.h"
#define generateDealNodeErrMsg(pCxt, code, ...) \ #define generateDealNodeErrMsg(pCxt, code, ...) \
(pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, code, ##__VA_ARGS__) ? DEAL_RES_ERROR : DEAL_RES_ERROR) (pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, code, ##__VA_ARGS__), DEAL_RES_ERROR)
typedef struct STranslateContext { typedef struct STranslateContext {
SParseContext* pParseCxt; SParseContext* pParseCxt;
@ -466,27 +466,66 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
break; break;
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
pVal->datum.b = (0 == strcasecmp(pVal->literal, "true")); pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
*(bool*)&pVal->typeData = pVal->datum.b;
break; break;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:{
case TSDB_DATA_TYPE_SMALLINT: char* endPtr = NULL;
case TSDB_DATA_TYPE_INT: pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
*(int8_t*)&pVal->typeData = pVal->datum.i;
break;
}
case TSDB_DATA_TYPE_SMALLINT:{
char* endPtr = NULL;
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
*(int16_t*)&pVal->typeData = pVal->datum.i;
break;
}
case TSDB_DATA_TYPE_INT:{
char* endPtr = NULL;
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
*(int32_t*)&pVal->typeData = pVal->datum.i;
break;
}
case TSDB_DATA_TYPE_BIGINT: { case TSDB_DATA_TYPE_BIGINT: {
char* endPtr = NULL; char* endPtr = NULL;
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10); pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
*(int64_t*)&pVal->typeData = pVal->datum.i;
break;
}
case TSDB_DATA_TYPE_UTINYINT:{
char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
*(uint8_t*)&pVal->typeData = pVal->datum.u;
break;
}
case TSDB_DATA_TYPE_USMALLINT:{
char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
*(uint16_t*)&pVal->typeData = pVal->datum.u;
break;
}
case TSDB_DATA_TYPE_UINT:{
char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
*(uint32_t*)&pVal->typeData = pVal->datum.u;
break; break;
} }
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT: { case TSDB_DATA_TYPE_UBIGINT: {
char* endPtr = NULL; char* endPtr = NULL;
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10); pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
*(uint64_t*)&pVal->typeData = pVal->datum.u;
break;
}
case TSDB_DATA_TYPE_FLOAT:{
char* endPtr = NULL;
pVal->datum.d = strtold(pVal->literal, &endPtr);
*(float*)&pVal->typeData = pVal->datum.d;
break; break;
} }
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
char* endPtr = NULL; char* endPtr = NULL;
pVal->datum.d = strtold(pVal->literal, &endPtr); pVal->datum.d = strtold(pVal->literal, &endPtr);
*(double*)&pVal->typeData = pVal->datum.d;
break; break;
} }
case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARCHAR:
@ -504,6 +543,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
} }
*(int64_t*)&pVal->typeData = pVal->datum.i;
break; break;
} }
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
@ -1676,11 +1716,12 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions, static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
bool alter) {
int32_t daysPerFile = pOptions->daysPerFile; int32_t daysPerFile = pOptions->daysPerFile;
int32_t daysToKeep0 = pOptions->keep[0]; int32_t daysToKeep0 = pOptions->keep[0];
if (alter && (-1 == daysPerFile || -1 == daysToKeep0)) { if (-1 == daysPerFile && -1 == daysToKeep0) {
return TSDB_CODE_SUCCESS;
} else if (-1 == daysPerFile || -1 == daysToKeep0) {
SDbCfgInfo dbCfg; SDbCfgInfo dbCfg;
int32_t code = getDBCfg(pCxt, pDbName, &dbCfg); int32_t code = getDBCfg(pCxt, pDbName, &dbCfg);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
@ -1695,8 +1736,7 @@ static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbNa
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions, static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
bool alter) {
int32_t code = int32_t code =
checkRangeOption(pCxt, "buffer", pOptions->buffer, TSDB_MIN_BUFFER_PER_VNODE, TSDB_MAX_BUFFER_PER_VNODE); checkRangeOption(pCxt, "buffer", pOptions->buffer, TSDB_MIN_BUFFER_PER_VNODE, TSDB_MAX_BUFFER_PER_VNODE);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
@ -1753,13 +1793,13 @@ static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName
code = checkDbRetentionsOption(pCxt, pOptions->pRetentions); code = checkDbRetentionsOption(pCxt, pOptions->pRetentions);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = checkOptionsDependency(pCxt, pDbName, pOptions, alter); code = checkOptionsDependency(pCxt, pDbName, pOptions);
} }
return code; return code;
} }
static int32_t checkCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt) { static int32_t checkCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt) {
return checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions, false); return checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions);
} }
typedef int32_t (*FSerializeFunc)(void* pBuf, int32_t bufLen, void* pReq); typedef int32_t (*FSerializeFunc)(void* pBuf, int32_t bufLen, void* pReq);
@ -1826,7 +1866,7 @@ static void buildAlterDbReq(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt,
} }
static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt) { static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt) {
int32_t code = checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions, true); int32_t code = checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
return code; return code;
} }
@ -3136,11 +3176,11 @@ static int32_t rewriteShow(STranslateContext* pCxt, SQuery* pQuery) {
return code; return code;
} }
typedef struct SVgroupTablesBatch { typedef struct SVgroupCreateTableBatch {
SVCreateTbBatchReq req; SVCreateTbBatchReq req;
SVgroupInfo info; SVgroupInfo info;
char dbName[TSDB_DB_NAME_LEN]; char dbName[TSDB_DB_NAME_LEN];
} SVgroupTablesBatch; } SVgroupCreateTableBatch;
static void destroyCreateTbReq(SVCreateTbReq* pReq) { static void destroyCreateTbReq(SVCreateTbReq* pReq) {
taosMemoryFreeClear(pReq->name); taosMemoryFreeClear(pReq->name);
@ -3148,7 +3188,7 @@ static void destroyCreateTbReq(SVCreateTbReq* pReq) {
} }
static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt* pStmt, const SVgroupInfo* pVgroupInfo, static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt* pStmt, const SVgroupInfo* pVgroupInfo,
SVgroupTablesBatch* pBatch) { SVgroupCreateTableBatch* pBatch) {
char dbFName[TSDB_DB_FNAME_LEN] = {0}; char dbFName[TSDB_DB_FNAME_LEN] = {0};
SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId}; SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
strcpy(name.dbname, pStmt->dbName); strcpy(name.dbname, pStmt->dbName);
@ -3182,13 +3222,13 @@ static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt*
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t serializeVgroupTablesBatch(SVgroupTablesBatch* pTbBatch, SArray* pBufArray) { static int32_t serializeVgroupCreateTableBatch(SVgroupCreateTableBatch* pTbBatch, SArray* pBufArray) {
int tlen; int tlen;
SCoder coder = {0}; SCoder coder = {0};
int32_t ret = 0; int32_t ret = 0;
tEncodeSize(tEncodeSVCreateTbBatchReq, &pTbBatch->req, tlen, ret); tEncodeSize(tEncodeSVCreateTbBatchReq, &pTbBatch->req, tlen, ret);
tlen += sizeof(SMsgHead); //+ tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req)); tlen += sizeof(SMsgHead);
void* buf = taosMemoryMalloc(tlen); void* buf = taosMemoryMalloc(tlen);
if (NULL == buf) { if (NULL == buf) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
@ -3214,7 +3254,7 @@ static int32_t serializeVgroupTablesBatch(SVgroupTablesBatch* pTbBatch, SArray*
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) { static void destroyCreateTbReqBatch(SVgroupCreateTableBatch* pTbBatch) {
size_t size = taosArrayGetSize(pTbBatch->req.pArray); size_t size = taosArrayGetSize(pTbBatch->req.pArray);
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i); SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i);
@ -3259,10 +3299,10 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt*
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
SVgroupTablesBatch tbatch = {0}; SVgroupCreateTableBatch tbatch = {0};
int32_t code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch); int32_t code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = serializeVgroupTablesBatch(&tbatch, *pBufArray); code = serializeVgroupCreateTableBatch(&tbatch, *pBufArray);
} }
destroyCreateTbReqBatch(&tbatch); destroyCreateTbReqBatch(&tbatch);
@ -3307,9 +3347,9 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, c
req.ctb.suid = suid; req.ctb.suid = suid;
req.ctb.pTag = row; req.ctb.pTag = row;
SVgroupTablesBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId)); SVgroupCreateTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
if (pTableBatch == NULL) { if (pTableBatch == NULL) {
SVgroupTablesBatch tBatch = {0}; SVgroupCreateTableBatch tBatch = {0};
tBatch.info = *pVgInfo; tBatch.info = *pVgInfo;
strcpy(tBatch.dbName, pDbName); strcpy(tBatch.dbName, pDbName);
@ -3482,21 +3522,21 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla
return code; return code;
} }
static SArray* serializeVgroupsTablesBatch(int32_t acctId, SHashObj* pVgroupHashmap) { static SArray* serializeVgroupsCreateTableBatch(int32_t acctId, SHashObj* pVgroupHashmap) {
SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*)); SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*));
if (NULL == pBufArray) { if (NULL == pBufArray) {
return NULL; return NULL;
} }
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SVgroupTablesBatch* pTbBatch = NULL; SVgroupCreateTableBatch* pTbBatch = NULL;
do { do {
pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch); pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
if (pTbBatch == NULL) { if (pTbBatch == NULL) {
break; break;
} }
serializeVgroupTablesBatch(pTbBatch, pBufArray); serializeVgroupCreateTableBatch(pTbBatch, pBufArray);
destroyCreateTbReqBatch(pTbBatch); destroyCreateTbReqBatch(pTbBatch);
} while (true); } while (true);
@ -3521,7 +3561,143 @@ static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery)
} }
} }
SArray* pBufArray = serializeVgroupsTablesBatch(pCxt->pParseCxt->acctId, pVgroupHashmap); SArray* pBufArray = serializeVgroupsCreateTableBatch(pCxt->pParseCxt->acctId, pVgroupHashmap);
taosHashCleanup(pVgroupHashmap);
if (NULL == pBufArray) {
return TSDB_CODE_OUT_OF_MEMORY;
}
return rewriteToVnodeModifOpStmt(pQuery, pBufArray);
}
typedef struct SVgroupDropTableBatch {
SVDropTbBatchReq req;
SVgroupInfo info;
char dbName[TSDB_DB_NAME_LEN];
} SVgroupDropTableBatch;
static void addDropTbReqIntoVgroup(SHashObj* pVgroupHashmap, SDropTableClause* pClause, SVgroupInfo* pVgInfo) {
SVDropTbReq req = {.name = pClause->tableName, .igNotExists = pClause->ignoreNotExists};
SVgroupDropTableBatch* pTableBatch = taosHashGet(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId));
if (NULL == pTableBatch) {
SVgroupDropTableBatch tBatch = {0};
tBatch.info = *pVgInfo;
tBatch.req.pArray = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVDropTbReq));
taosArrayPush(tBatch.req.pArray, &req);
taosHashPut(pVgroupHashmap, &pVgInfo->vgId, sizeof(pVgInfo->vgId), &tBatch, sizeof(tBatch));
} else { // add to the correct vgroup
taosArrayPush(pTableBatch->req.pArray, &req);
}
}
static int32_t buildDropTableVgroupHashmap(STranslateContext* pCxt, SDropTableClause* pClause, bool* pIsSuperTable,
SHashObj* pVgroupHashmap) {
STableMeta* pTableMeta = NULL;
int32_t code = getTableMeta(pCxt, pClause->dbName, pClause->tableName, &pTableMeta);
if (TSDB_CODE_SUCCESS == code && TSDB_SUPER_TABLE == pTableMeta->tableType) {
*pIsSuperTable = true;
goto over;
}
*pIsSuperTable = false;
SVgroupInfo info = {0};
if (TSDB_CODE_SUCCESS == code) {
code = getTableHashVgroup(pCxt, pClause->dbName, pClause->tableName, &info);
}
if (TSDB_CODE_SUCCESS == code) {
addDropTbReqIntoVgroup(pVgroupHashmap, pClause, &info);
}
over:
taosMemoryFreeClear(pTableMeta);
return code;
}
static void destroyDropTbReqBatch(SVgroupDropTableBatch* pTbBatch) { taosArrayDestroy(pTbBatch->req.pArray); }
static int32_t serializeVgroupDropTableBatch(SVgroupDropTableBatch* pTbBatch, SArray* pBufArray) {
int tlen;
SCoder coder = {0};
int32_t ret = 0;
tEncodeSize(tEncodeSVDropTbBatchReq, &pTbBatch->req, tlen, ret);
tlen += sizeof(SMsgHead);
void* buf = taosMemoryMalloc(tlen);
if (NULL == buf) {
return TSDB_CODE_OUT_OF_MEMORY;
}
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
((SMsgHead*)buf)->contLen = htonl(tlen);
void* pBuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
tCoderInit(&coder, TD_LITTLE_ENDIAN, pBuf, tlen - sizeof(SMsgHead), TD_ENCODER);
tEncodeSVDropTbBatchReq(&coder, &pTbBatch->req);
tCoderClear(&coder);
SVgDataBlocks* pVgData = taosMemoryCalloc(1, sizeof(SVgDataBlocks));
if (NULL == pVgData) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pVgData->vg = pTbBatch->info;
pVgData->pData = buf;
pVgData->size = tlen;
pVgData->numOfTables = (int32_t)taosArrayGetSize(pTbBatch->req.pArray);
taosArrayPush(pBufArray, &pVgData);
return TSDB_CODE_SUCCESS;
}
static SArray* serializeVgroupsDropTableBatch(int32_t acctId, SHashObj* pVgroupHashmap) {
SArray* pBufArray = taosArrayInit(taosHashGetSize(pVgroupHashmap), sizeof(void*));
if (NULL == pBufArray) {
return NULL;
}
int32_t code = TSDB_CODE_SUCCESS;
SVgroupDropTableBatch* pTbBatch = NULL;
do {
pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
if (pTbBatch == NULL) {
break;
}
serializeVgroupDropTableBatch(pTbBatch, pBufArray);
destroyDropTbReqBatch(pTbBatch);
} while (true);
return pBufArray;
}
static int32_t rewriteDropTable(STranslateContext* pCxt, SQuery* pQuery) {
SDropTableStmt* pStmt = (SDropTableStmt*)pQuery->pRoot;
SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
if (NULL == pVgroupHashmap) {
return TSDB_CODE_OUT_OF_MEMORY;
}
bool isSuperTable = false;
SNode* pNode;
FOREACH(pNode, pStmt->pTables) {
int32_t code = buildDropTableVgroupHashmap(pCxt, (SDropTableClause*)pNode, &isSuperTable, pVgroupHashmap);
if (TSDB_CODE_SUCCESS != code) {
taosHashCleanup(pVgroupHashmap);
return code;
}
if (isSuperTable && LIST_LENGTH(pStmt->pTables) > 1) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DROP_STABLE);
}
}
if (isSuperTable) {
taosHashCleanup(pVgroupHashmap);
return TSDB_CODE_SUCCESS;
}
SArray* pBufArray = serializeVgroupsDropTableBatch(pCxt->pParseCxt->acctId, pVgroupHashmap);
taosHashCleanup(pVgroupHashmap); taosHashCleanup(pVgroupHashmap);
if (NULL == pBufArray) { if (NULL == pBufArray) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
@ -3567,6 +3743,9 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
case QUERY_NODE_CREATE_MULTI_TABLE_STMT: case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
code = rewriteCreateMultiTable(pCxt, pQuery); code = rewriteCreateMultiTable(pCxt, pQuery);
break; break;
case QUERY_NODE_DROP_TABLE_STMT:
code = rewriteDropTable(pCxt, pQuery);
break;
case QUERY_NODE_ALTER_TABLE_STMT: case QUERY_NODE_ALTER_TABLE_STMT:
if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == ((SAlterTableStmt*)pQuery->pRoot)->alterType) { if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == ((SAlterTableStmt*)pQuery->pRoot)->alterType) {
code = rewriteAlterTable(pCxt, pQuery); code = rewriteAlterTable(pCxt, pQuery);

View File

@ -126,6 +126,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "slimit/soffset only available for PARTITION BY query"; return "slimit/soffset only available for PARTITION BY query";
case TSDB_CODE_PAR_INVALID_TOPIC_QUERY: case TSDB_CODE_PAR_INVALID_TOPIC_QUERY:
return "Invalid topic query"; return "Invalid topic query";
case TSDB_CODE_PAR_INVALID_DROP_STABLE:
return "Cannot drop super table in batch";
case TSDB_CODE_OUT_OF_MEMORY: case TSDB_CODE_OUT_OF_MEMORY:
return "Out of memory"; return "Out of memory";
default: default:

View File

@ -3021,11 +3021,11 @@ static YYACTIONTYPE yy_reduce(
/********** Begin reduce actions **********************************************/ /********** Begin reduce actions **********************************************/
YYMINORTYPE yylhsminor; YYMINORTYPE yylhsminor;
case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */
{ pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
yy_destructor(yypParser,232,&yymsp[0].minor); yy_destructor(yypParser,232,&yymsp[0].minor);
break; break;
case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */
{ pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
yy_destructor(yypParser,233,&yymsp[0].minor); yy_destructor(yypParser,233,&yymsp[0].minor);
break; break;
case 2: /* account_options ::= */ case 2: /* account_options ::= */
@ -3591,7 +3591,7 @@ static YYACTIONTYPE yy_reduce(
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); } { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); }
break; break;
case 178: /* cmd ::= SHOW ACCOUNTS */ case 178: /* cmd ::= SHOW ACCOUNTS */
{ pCxt->valid = false; generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
break; break;
case 179: /* cmd ::= SHOW APPS */ case 179: /* cmd ::= SHOW APPS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT, NULL, NULL); } { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT, NULL, NULL); }
@ -3902,7 +3902,8 @@ static YYACTIONTYPE yy_reduce(
yymsp[0].minor.yy662 = yylhsminor.yy662; yymsp[0].minor.yy662 = yylhsminor.yy662;
break; break;
case 272: /* signed_literal ::= NULL */ case 272: /* signed_literal ::= NULL */
{ yymsp[0].minor.yy662 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, NULL); } { yylhsminor.yy662 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); }
yymsp[0].minor.yy662 = yylhsminor.yy662;
break; break;
case 291: /* expression ::= NK_LP expression NK_RP */ case 291: /* expression ::= NK_LP expression NK_RP */
case 355: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==355); case 355: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==355);
@ -4352,13 +4353,12 @@ static void yy_syntax_error(
#define TOKEN yyminor #define TOKEN yyminor
/************ Begin %syntax_error code ****************************************/ /************ Begin %syntax_error code ****************************************/
if (pCxt->valid) { if (TSDB_CODE_SUCCESS == pCxt->errCode) {
if(TOKEN.z) { if(TOKEN.z) {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z);
} else { } else {
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INCOMPLETE_SQL); pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INCOMPLETE_SQL);
} }
pCxt->valid = false;
} }
/************ End %syntax_error code ******************************************/ /************ End %syntax_error code ******************************************/
ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */

View File

@ -25,3 +25,8 @@ if(${BUILD_WINGETOPT})
) )
target_link_libraries(parserTest PUBLIC wingetopt) target_link_libraries(parserTest PUBLIC wingetopt)
endif() endif()
add_test(
NAME parserTest
COMMAND parserTest
)

View File

@ -155,16 +155,22 @@ int32_t __catalogGetDBVgInfo(SCatalog* pCtg, void* pRpc, const SEpSet* pMgmtEps,
return 0; return 0;
} }
int32_t __catalogGetDBCfg(SCatalog* pCtg, void* pRpc, const SEpSet* pMgmtEps, const char* dbFName, SDbCfgInfo* pDbCfg) {
return 0;
}
void initMetaDataEnv() { void initMetaDataEnv() {
mockCatalogService.reset(new MockCatalogService()); mockCatalogService.reset(new MockCatalogService());
static Stub stub; static Stub stub;
stub.set(catalogGetHandle, __catalogGetHandle); stub.set(catalogGetHandle, __catalogGetHandle);
stub.set(catalogGetTableMeta, __catalogGetTableMeta); stub.set(catalogGetTableMeta, __catalogGetTableMeta);
stub.set(catalogGetSTableMeta, __catalogGetTableMeta);
stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup); stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup);
stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo); stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo);
stub.set(catalogGetDBVgVersion, __catalogGetDBVgVersion); stub.set(catalogGetDBVgVersion, __catalogGetDBVgVersion);
stub.set(catalogGetDBVgInfo, __catalogGetDBVgInfo); stub.set(catalogGetDBVgInfo, __catalogGetDBVgInfo);
stub.set(catalogGetDBCfg, __catalogGetDBCfg);
// { // {
// AddrAny any("libcatalog.so"); // AddrAny any("libcatalog.so");
// std::map<std::string,void*> result; // std::map<std::string,void*> result;

View File

@ -111,9 +111,8 @@ class MockCatalogServiceImpl {
} }
int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const { int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const {
char db[TSDB_DB_NAME_LEN] = {0}; vgInfo->vgId = 1;
tNameGetDbName(pTableName, db); return TSDB_CODE_SUCCESS;
return copyTableVgroup(db, tNameGetTableName(pTableName), vgInfo);
} }
int32_t catalogGetTableDistVgInfo(const SName* pTableName, SArray** vgList) const { int32_t catalogGetTableDistVgInfo(const SName* pTableName, SArray** vgList) const {

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserExplainToSyncdbTest : public ParserTestBase {};
TEST_F(ParserExplainToSyncdbTest, explain) {
useDb("root", "test");
run("explain SELECT * FROM t1");
run("explain analyze SELECT * FROM t1");
run("explain analyze verbose true ratio 0.01 SELECT * FROM t1");
}
// todo kill connection
// todo kill query
// todo kill stream
// todo merge vgroup
// todo redistribute vgroup
// todo reset query cache
// todo syncdb
} // namespace ParserTest

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserInitialATest : public ParserTestBase {};
TEST_F(ParserInitialATest, alterAccount) {
useDb("root", "test");
run("alter account ac_wxy pass '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT);
}
TEST_F(ParserInitialATest, alterDnode) {
useDb("root", "test");
run("alter dnode 1 'resetLog'");
run("alter dnode 1 'debugFlag' '134'");
}
TEST_F(ParserInitialATest, alterDatabase) {
useDb("root", "test");
run("alter database wxy_db cachelast 1 fsync 200 wal 1");
}
// todo alter local
// todo alter stable
// todo alter table
TEST_F(ParserInitialATest, alterUser) {
useDb("root", "test");
run("alter user wxy pass '123456'");
run("alter user wxy privilege 'write'");
}
TEST_F(ParserInitialATest, bug001) {
useDb("root", "test");
run("alter database db wal 0 # td-14436", TSDB_CODE_PAR_SYNTAX_ERROR);
}
} // namespace ParserTest

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserInitialCTest : public ParserTestBase {};
// todo compact
TEST_F(ParserInitialCTest, createAccount) {
useDb("root", "test");
run("create account ac_wxy pass '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT);
}
TEST_F(ParserInitialCTest, createBnode) {
useDb("root", "test");
run("create bnode on dnode 1");
}
TEST_F(ParserInitialCTest, createDatabase) {
useDb("root", "test");
run("create database wxy_db");
run("create database if not exists wxy_db "
"cachelast 2 "
"comp 1 "
"days 100 "
"fsync 100 "
"maxrows 1000 "
"minrows 100 "
"keep 1440 "
"precision 'ms' "
"replica 3 "
"wal 2 "
"vgroups 100 "
"single_stable 0 "
"retentions 15s:7d,1m:21d,15m:5y");
run("create database if not exists wxy_db "
"days 100m "
"keep 1440m,300h,400d ");
}
TEST_F(ParserInitialCTest, createDnode) {
useDb("root", "test");
run("create dnode abc1 port 7000");
run("create dnode 1.1.1.1 port 9000");
}
// todo create function
TEST_F(ParserInitialCTest, createIndexSma) {
useDb("root", "test");
run("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
}
TEST_F(ParserInitialCTest, createMnode) {
useDb("root", "test");
run("create mnode on dnode 1");
}
TEST_F(ParserInitialCTest, createQnode) {
useDb("root", "test");
run("create qnode on dnode 1");
}
TEST_F(ParserInitialCTest, createSnode) {
useDb("root", "test");
run("create snode on dnode 1");
}
TEST_F(ParserInitialCTest, createStable) {
useDb("root", "test");
run("create stable t1(ts timestamp, c1 int) TAGS(id int)");
run("create stable if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
"c15 VARCHAR(50)) "
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 "
"BINARY(20), a8 SMALLINT, "
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
"a15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
}
TEST_F(ParserInitialCTest, createStream) {
useDb("root", "test");
run("create stream s1 as select * from t1");
run("create stream if not exists s1 as select * from t1");
run("create stream s1 into st1 as select * from t1");
run("create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from t1");
}
TEST_F(ParserInitialCTest, createTable) {
useDb("root", "test");
run("create table t1(ts timestamp, c1 int)");
run("create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
"NCHAR(30), "
"c15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)");
run("create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
"NCHAR(30), "
"c15 VARCHAR(50)) "
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, "
"a5 FLOAT, a6 DOUBLE, a7 "
"BINARY(20), a8 SMALLINT, "
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 "
"TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
"a15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create "
"table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
run("create table if not exists t1 using st1 tags(1, 'wxy')");
run("create table "
"if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') "
"if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') "
"if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') ");
}
TEST_F(ParserInitialCTest, createTopic) {
useDb("root", "test");
run("create topic tp1 as select * from t1");
run("create topic if not exists tp1 as select * from t1");
run("create topic tp1 as test");
run("create topic if not exists tp1 as test");
}
TEST_F(ParserInitialCTest, createUser) {
useDb("root", "test");
run("create user wxy pass '123456'");
}
} // namespace ParserTest

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserInitialDTest : public ParserTestBase {};
// todo delete
// todo desc
// todo describe
// todo drop account
TEST_F(ParserInitialDTest, dropBnode) {
useDb("root", "test");
run("drop bnode on dnode 1");
}
// todo drop database
// todo drop dnode
// todo drop function
TEST_F(ParserInitialDTest, dropIndex) {
useDb("root", "test");
run("drop index index1 on t1");
}
TEST_F(ParserInitialDTest, dropMnode) {
useDb("root", "test");
run("drop mnode on dnode 1");
}
TEST_F(ParserInitialDTest, dropQnode) {
useDb("root", "test");
run("drop qnode on dnode 1");
}
TEST_F(ParserInitialDTest, dropSnode) {
useDb("root", "test");
run("drop snode on dnode 1");
}
// todo drop stable
// todo drop stream
// todo drop table
TEST_F(ParserInitialDTest, dropTopic) {
useDb("root", "test");
run("drop topic tp1");
run("drop topic if exists tp1");
}
TEST_F(ParserInitialDTest, dropUser) {
useDb("root", "test");
run("drop user wxy");
}
} // namespace ParserTest

View File

@ -111,6 +111,7 @@ class InsertTest : public Test {
cxt_.pMsg = errMagBuf_; cxt_.pMsg = errMagBuf_;
cxt_.msgLen = max_err_len; cxt_.msgLen = max_err_len;
code_ = TSDB_CODE_SUCCESS; code_ = TSDB_CODE_SUCCESS;
res_ = nullptr;
} }
SVnodeModifOpStmt* getVnodeModifStmt(SQuery* pQuery) { return (SVnodeModifOpStmt*)pQuery->pRoot; } SVnodeModifOpStmt* getVnodeModifStmt(SQuery* pQuery) { return (SVnodeModifOpStmt*)pQuery->pRoot; }

View File

@ -0,0 +1,182 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserSelectTest : public ParserTestBase {};
TEST_F(ParserSelectTest, basic) {
useDb("root", "test");
run("select * from t1");
run("select * from test.t1");
run("select ts, c1 from t1");
run("select ts, t.c1 from (select * from t1) t");
run("select * from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1");
}
TEST_F(ParserSelectTest, constant) {
useDb("root", "test");
run("select 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s from t1");
run("select 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
"timestamp '2022-02-09 17:30:20', true, false, 15s from t1");
run("select 123 + 45 from t1 where 2 - 1");
}
TEST_F(ParserSelectTest, expression) {
useDb("root", "test");
run("select ts + 10s, c1 + 10, concat(c2, 'abc') from t1");
run("select ts > 0, c1 < 20 and c2 = 'qaz' from t1");
run("select ts > 0, c1 between 10 and 20 and c2 = 'qaz' from t1");
}
TEST_F(ParserSelectTest, condition) {
useDb("root", "test");
run("select c1 from t1 where ts in (true, false)");
run("select * from t1 where c1 > 10 and c1 is not null");
}
TEST_F(ParserSelectTest, pseudoColumn) {
useDb("root", "test");
run("select _wstartts, _wendts, count(*) from t1 interval(10s)");
}
TEST_F(ParserSelectTest, multiResFunc) {
useDb("root", "test");
run("select last(*), first(*), last_row(*) from t1");
run("select last(c1, c2), first(t1.*), last_row(c3) from t1");
run("select last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
}
TEST_F(ParserSelectTest, clause) {
useDb("root", "test");
// group by clause
run("select count(*) cnt from t1 where c1 > 0");
run("select count(*), c2 cnt from t1 where c1 > 0 group by c2");
run("select count(*) cnt from t1 where c1 > 0 group by c2 having count(c1) > 10");
run("select count(*), c1, c2 + 10, c1 + c2 cnt from t1 where c1 > 0 group by c2, c1");
run("select count(*), c1 + 10, c2 cnt from t1 where c1 > 0 group by c1 + 10, c2");
// order by clause
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by cnt");
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by 1");
// distinct clause
// run("select distinct c1, c2 from t1 where c1 > 0 order by c1");
// run("select distinct c1 + 10, c2 from t1 where c1 > 0 order by c1 + 10, c2");
// run("select distinct c1 + 10 cc1, c2 cc2 from t1 where c1 > 0 order by cc1, c2");
// run("select distinct count(c2) from t1 where c1 > 0 group by c1 order by count(c2)");
}
TEST_F(ParserSelectTest, window) {
useDb("root", "test");
run("select count(*) from t1 interval(10s)");
}
TEST_F(ParserSelectTest, semanticError) {
useDb("root", "test");
// TSDB_CODE_PAR_INVALID_COLUMN
run("select c1, cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
run("select t1.c1, t1.cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_TABLE_NOT_EXIST
run("select * from t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
run("select * from test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
run("select t2.c1 from t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
run("select c2 from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
run("select timestamp '2010' from t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
run("select c2 from t1 tt1 join t1 tt2 on count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
PARSER_STAGE_TRANSLATE);
run("select c2 from t1 where count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
run("select c2 from t1 group by count(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
run("select c2 from t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
run("select c2 from t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
run("select count(*) cnt from t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
run("select count(*) cnt from t1 group by c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE);
run("select count(*), c1 cnt from t1 group by c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE);
run("select count(*) cnt from t1 group by c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
run("select count(*), c1 from t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
run("select count(*) from t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
run("select c1 from t1 order by count(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
run("select distinct c1, c2 from t1 where c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE);
run("select distinct c1 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE);
run("select distinct c2 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE);
}
} // namespace ParserTest

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "parTestUtil.h"
using namespace std;
namespace ParserTest {
class ParserShowToUseTest : public ParserTestBase {};
// todo show accounts
// todo show apps
// todo show connections
// todo show create database
// todo show create stable
// todo show create table
TEST_F(ParserShowToUseTest, showDatabases) {
useDb("root", "test");
run("show databases");
}
TEST_F(ParserShowToUseTest, showDnodes) {
useDb("root", "test");
run("show dnodes");
}
TEST_F(ParserShowToUseTest, showFunctions) {
useDb("root", "test");
run("show functions");
}
// todo show licence
TEST_F(ParserShowToUseTest, showIndexes) {
useDb("root", "test");
run("show indexes from t1");
run("show indexes from t1 from test");
}
TEST_F(ParserShowToUseTest, showMnodes) {
useDb("root", "test");
run("show mnodes");
}
TEST_F(ParserShowToUseTest, showModules) {
useDb("root", "test");
run("show modules");
}
TEST_F(ParserShowToUseTest, showQnodes) {
useDb("root", "test");
run("show qnodes");
}
// todo show queries
// todo show scores
TEST_F(ParserShowToUseTest, showStables) {
useDb("root", "test");
run("show stables");
run("show test.stables");
run("show stables like 'c%'");
run("show test.stables like 'c%'");
}
TEST_F(ParserShowToUseTest, showStreams) {
useDb("root", "test");
run("show streams");
}
TEST_F(ParserShowToUseTest, showTables) {
useDb("root", "test");
run("show tables");
run("show test.tables");
run("show tables like 'c%'");
run("show test.tables like 'c%'");
}
// todo show topics
TEST_F(ParserShowToUseTest, showUsers) {
useDb("root", "test");
run("show users");
}
// todo show variables
TEST_F(ParserShowToUseTest, showVgroups) {
useDb("root", "test");
run("show vgroups");
run("show test.vgroups");
}
// todo show vnodes
// todo split vgroup
TEST_F(ParserShowToUseTest, useDatabase) {
useDb("root", "test");
run("use wxy_db");
}
} // namespace ParserTest

View File

@ -30,6 +30,8 @@
#include "parTestUtil.h" #include "parTestUtil.h"
#include "parToken.h" #include "parToken.h"
namespace ParserTest {
class ParserEnv : public testing::Environment { class ParserEnv : public testing::Environment {
public: public:
virtual void SetUp() { virtual void SetUp() {
@ -62,9 +64,11 @@ static void parseArg(int argc, char* argv[]) {
} }
} }
} // namespace ParserTest
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
testing::AddGlobalTestEnvironment(new ParserEnv()); testing::AddGlobalTestEnvironment(new ParserTest::ParserEnv());
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
parseArg(argc, argv); ParserTest::parseArg(argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -23,17 +23,30 @@
using namespace std; using namespace std;
using namespace testing; using namespace testing;
namespace ParserTest {
#define DO_WITH_THROW(func, ...) \ #define DO_WITH_THROW(func, ...) \
do { \ do { \
int32_t code__ = func(__VA_ARGS__); \ int32_t code__ = func(__VA_ARGS__); \
if (!checkResultCode(#func, code__)) { \
if (TSDB_CODE_SUCCESS != code__) { \ if (TSDB_CODE_SUCCESS != code__) { \
throw runtime_error("sql:[" + stmtEnv_.sql_ + "] " #func " code:" + to_string(code__) + \ throw runtime_error("sql:[" + stmtEnv_.sql_ + "] " #func " code:" + to_string(code__) + \
", strerror:" + string(tstrerror(code__)) + ", msg:" + string(stmtEnv_.msgBuf_.data())); \ ", strerror:" + string(tstrerror(code__)) + ", msg:" + string(stmtEnv_.msgBuf_.data())); \
} else { \
throw runtime_error("sql:[" + stmtEnv_.sql_ + "] " #func " expect " + to_string(stmtEnv_.expect_) + \
" actual " + to_string(code__)); \
} \
} else if (TSDB_CODE_SUCCESS != code__) { \
throw TerminateFlag(); \
} \ } \
} while (0); } while (0);
bool g_isDump = false; bool g_isDump = false;
struct TerminateFlag : public exception {
const char* what() const throw() { return "success and terminate"; }
};
class ParserTestBaseImpl { class ParserTestBaseImpl {
public: public:
void useDb(const string& acctId, const string& db) { void useDb(const string& acctId, const string& db) {
@ -41,8 +54,8 @@ class ParserTestBaseImpl {
caseEnv_.db_ = db; caseEnv_.db_ = db;
} }
void run(const string& sql) { void run(const string& sql, int32_t expect, ParserStage checkStage) {
reset(); reset(expect, checkStage);
try { try {
SParseContext cxt = {0}; SParseContext cxt = {0};
setParseContext(sql, &cxt); setParseContext(sql, &cxt);
@ -57,6 +70,9 @@ class ParserTestBaseImpl {
if (g_isDump) { if (g_isDump) {
dump(); dump();
} }
} catch (const TerminateFlag& e) {
// success and terminate
return;
} catch (...) { } catch (...) {
dump(); dump();
throw; throw;
@ -72,6 +88,8 @@ class ParserTestBaseImpl {
struct stmtEnv { struct stmtEnv {
string sql_; string sql_;
array<char, 1024> msgBuf_; array<char, 1024> msgBuf_;
int32_t expect_;
string checkFunc_;
}; };
struct stmtRes { struct stmtRes {
@ -80,9 +98,34 @@ class ParserTestBaseImpl {
string calcConstAst_; string calcConstAst_;
}; };
void reset() { bool checkResultCode(const string& pFunc, int32_t resultCode) {
return !(stmtEnv_.checkFunc_.empty())
? (("*" == stmtEnv_.checkFunc_ || stmtEnv_.checkFunc_ == pFunc) ? stmtEnv_.expect_ == resultCode
: TSDB_CODE_SUCCESS == resultCode)
: true;
}
string stageFunc(ParserStage stage) {
switch (stage) {
case PARSER_STAGE_PARSE:
return "parse";
case PARSER_STAGE_TRANSLATE:
return "translate";
case PARSER_STAGE_CALC_CONST:
return "calculateConstant";
case PARSER_STAGE_ALL:
return "*";
default:
break;
}
return "unknown";
}
void reset(int32_t expect, ParserStage checkStage) {
stmtEnv_.sql_.clear(); stmtEnv_.sql_.clear();
stmtEnv_.msgBuf_.fill(0); stmtEnv_.msgBuf_.fill(0);
stmtEnv_.expect_ = expect;
stmtEnv_.checkFunc_ = stageFunc(checkStage);
res_.parsedAst_.clear(); res_.parsedAst_.clear();
res_.translatedAst_.clear(); res_.translatedAst_.clear();
@ -146,4 +189,8 @@ ParserTestBase::~ParserTestBase() {}
void ParserTestBase::useDb(const std::string& acctId, const std::string& db) { impl_->useDb(acctId, db); } void ParserTestBase::useDb(const std::string& acctId, const std::string& db) { impl_->useDb(acctId, db); }
void ParserTestBase::run(const std::string& sql) { return impl_->run(sql); } void ParserTestBase::run(const std::string& sql, int32_t expect, ParserStage checkStage) {
return impl_->run(sql, expect, checkStage);
}
} // namespace ParserTest

View File

@ -18,15 +18,21 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "taoserror.h"
namespace ParserTest {
class ParserTestBaseImpl; class ParserTestBaseImpl;
enum ParserStage { PARSER_STAGE_PARSE, PARSER_STAGE_TRANSLATE, PARSER_STAGE_CALC_CONST, PARSER_STAGE_ALL };
class ParserTestBase : public testing::Test { class ParserTestBase : public testing::Test {
public: public:
ParserTestBase(); ParserTestBase();
virtual ~ParserTestBase(); virtual ~ParserTestBase();
void useDb(const std::string& acctId, const std::string& db); void useDb(const std::string& acctId, const std::string& db);
void run(const std::string& sql); void run(const std::string& sql, int32_t expect = TSDB_CODE_SUCCESS, ParserStage checkStage = PARSER_STAGE_ALL);
private: private:
std::unique_ptr<ParserTestBaseImpl> impl_; std::unique_ptr<ParserTestBaseImpl> impl_;
@ -34,4 +40,6 @@ class ParserTestBase : public testing::Test {
extern bool g_isDump; extern bool g_isDump;
} // namespace ParserTest
#endif // PARSER_TEST_UTIL_H #endif // PARSER_TEST_UTIL_H

View File

@ -1,782 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <string>
#include <gtest/gtest.h>
#include "parInt.h"
#include "parTestUtil.h"
using namespace std;
using namespace testing;
class ParserTest : public Test {
protected:
void setDatabase(const string& acctId, const string& db) {
acctId_ = acctId;
db_ = db;
}
void bind(const char* sql) {
reset();
cxt_.acctId = atoi(acctId_.c_str());
cxt_.db = db_.c_str();
sqlBuf_ = string(sql);
transform(sqlBuf_.begin(), sqlBuf_.end(), sqlBuf_.begin(), ::tolower);
cxt_.sqlLen = strlen(sql);
cxt_.pSql = sqlBuf_.c_str();
}
bool run(int32_t parseCode = TSDB_CODE_SUCCESS, int32_t translateCode = TSDB_CODE_SUCCESS) {
query_ = nullptr;
bool res = runImpl(parseCode, translateCode);
qDestroyQuery(query_);
if (!res || g_isDump) {
dump();
}
return res;
}
private:
static const int max_err_len = 1024;
bool runImpl(int32_t parseCode, int32_t translateCode) {
int32_t code = parse(&cxt_, &query_);
if (code != TSDB_CODE_SUCCESS) {
parseErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
return (code == parseCode);
}
if (TSDB_CODE_SUCCESS != parseCode) {
return false;
}
parsedAstStr_ = toString(query_->pRoot);
code = translate(&cxt_, query_);
if (code != TSDB_CODE_SUCCESS) {
translateErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
return (code == translateCode);
}
translatedAstStr_ = toString(query_->pRoot);
code = calculateConstant(&cxt_, query_);
if (code != TSDB_CODE_SUCCESS) {
calcConstErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
return false;
}
calcConstAstStr_ = toString(query_->pRoot);
return (TSDB_CODE_SUCCESS == translateCode);
}
void dump() {
cout << "input sql : [" << cxt_.pSql << "]" << endl;
if (!parseErrStr_.empty()) {
cout << "parse error: " << parseErrStr_ << endl;
}
if (!parsedAstStr_.empty()) {
cout << "parse output: " << endl;
cout << parsedAstStr_ << endl;
}
if (!translateErrStr_.empty()) {
cout << "translate error: " << translateErrStr_ << endl;
}
if (!translatedAstStr_.empty()) {
cout << "translate output: " << endl;
cout << translatedAstStr_ << endl;
}
if (!calcConstErrStr_.empty()) {
cout << "calculateConstant error: " << calcConstErrStr_ << endl;
}
if (!calcConstAstStr_.empty()) {
cout << "calculateConstant output: " << endl;
cout << calcConstAstStr_ << endl;
}
}
string toString(const SNode* pRoot, bool format = false) {
char* pStr = NULL;
int32_t len = 0;
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
throw "nodesNodeToString failed!";
}
string str(pStr);
taosMemoryFreeClear(pStr);
return str;
}
void reset() {
memset(&cxt_, 0, sizeof(cxt_));
memset(errMagBuf_, 0, max_err_len);
cxt_.pMsg = errMagBuf_;
cxt_.msgLen = max_err_len;
parseErrStr_.clear();
parsedAstStr_.clear();
translateErrStr_.clear();
translatedAstStr_.clear();
calcConstErrStr_.clear();
calcConstAstStr_.clear();
}
string acctId_;
string db_;
char errMagBuf_[max_err_len];
string sqlBuf_;
SParseContext cxt_;
SQuery* query_;
string parseErrStr_;
string parsedAstStr_;
string translateErrStr_;
string translatedAstStr_;
string calcConstErrStr_;
string calcConstAstStr_;
};
TEST_F(ParserTest, createAccount) {
setDatabase("root", "test");
bind("create account ac_wxy pass '123456'");
ASSERT_TRUE(run(TSDB_CODE_PAR_EXPRIE_STATEMENT));
}
TEST_F(ParserTest, alterAccount) {
setDatabase("root", "test");
bind("alter account ac_wxy pass '123456'");
ASSERT_TRUE(run(TSDB_CODE_PAR_EXPRIE_STATEMENT));
}
TEST_F(ParserTest, createUser) {
setDatabase("root", "test");
bind("create user wxy pass '123456'");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, alterUser) {
setDatabase("root", "test");
bind("alter user wxy pass '123456'");
ASSERT_TRUE(run());
bind("alter user wxy privilege 'write'");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropUser) {
setDatabase("root", "test");
bind("drop user wxy");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectSimple) {
setDatabase("root", "test");
bind("SELECT * FROM t1");
ASSERT_TRUE(run());
bind("SELECT * FROM test.t1");
ASSERT_TRUE(run());
bind("SELECT ts, c1 FROM t1");
ASSERT_TRUE(run());
bind("SELECT ts, t.c1 FROM (SELECT * FROM t1) t");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectConstant) {
setDatabase("root", "test");
bind("SELECT 123, 20.4, 'abc', \"wxy\", TIMESTAMP '2022-02-09 17:30:20', true, false, 10s FROM t1");
ASSERT_TRUE(run());
bind(
"SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
"TIMESTAMP '2022-02-09 17:30:20', true, false, 15s FROM t1");
ASSERT_TRUE(run());
bind("SELECT 123 + 45 FROM t1 where 2 - 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectExpression) {
setDatabase("root", "test");
bind("SELECT ts + 10s, c1 + 10, concat(c2, 'abc') FROM t1");
ASSERT_TRUE(run());
bind("SELECT ts > 0, c1 < 20 AND c2 = 'qaz' FROM t1");
ASSERT_TRUE(run());
bind("SELECT ts > 0, c1 BETWEEN 10 AND 20 AND c2 = 'qaz' FROM t1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectCondition) {
setDatabase("root", "test");
bind("SELECT c1 FROM t1 where ts in (true, false)");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 where c1 > 10 and c1 is not null");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectPseudoColumn) {
setDatabase("root", "test");
bind("SELECT _wstartts, _wendts, count(*) FROM t1 interval(10s)");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectMultiResFunc) {
setDatabase("root", "test");
// bind("SELECT last(*), first(*), last_row(*) FROM t1");
// ASSERT_TRUE(run());
bind("SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1");
ASSERT_TRUE(run());
bind("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectClause) {
setDatabase("root", "test");
// GROUP BY clause
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0");
ASSERT_TRUE(run());
bind("SELECT count(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
ASSERT_TRUE(run());
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 HAVING count(c1) > 10");
ASSERT_TRUE(run());
bind("SELECT count(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
ASSERT_TRUE(run());
bind("SELECT count(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
ASSERT_TRUE(run());
// ORDER BY clause
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 ORDER BY cnt");
ASSERT_TRUE(run());
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 ORDER BY 1");
ASSERT_TRUE(run());
// DISTINCT clause
bind("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 0 ORDER BY c1");
ASSERT_TRUE(run());
bind("SELECT DISTINCT c1 + 10, c2 FROM t1 WHERE c1 > 0 ORDER BY c1 + 10, c2");
ASSERT_TRUE(run());
bind("SELECT DISTINCT c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 ORDER BY cc1, c2");
ASSERT_TRUE(run());
bind("SELECT DISTINCT count(c2) FROM t1 WHERE c1 > 0 GROUP BY c1 ORDER BY count(c2)");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectWindow) {
setDatabase("root", "test");
bind("SELECT count(*) FROM t1 interval(10s)");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, selectSyntaxError) {
setDatabase("root", "test");
bind("SELECTT * FROM t1");
ASSERT_TRUE(run(TSDB_CODE_FAILED));
bind("SELECT *");
ASSERT_TRUE(run(TSDB_CODE_FAILED));
bind("SELECT *, * FROM test.t1");
ASSERT_TRUE(run(TSDB_CODE_FAILED));
bind("SELECT * FROM test.t1 t WHER");
ASSERT_TRUE(run(TSDB_CODE_FAILED));
}
TEST_F(ParserTest, selectSemanticError) {
setDatabase("root", "test");
// TSDB_CODE_PAR_INVALID_COLUMN
bind("SELECT c1, cc1 FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_INVALID_COLUMN));
bind("SELECT t1.c1, t1.cc1 FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_INVALID_COLUMN));
// TSDB_CODE_PAR_TABLE_NOT_EXIST
bind("SELECT * FROM t10");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
bind("SELECT * FROM test.t10");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
bind("SELECT t2.c1 FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
bind("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_AMBIGUOUS_COLUMN));
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
bind("SELECT 10n FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_VALUE_TYPE));
bind("SELECT TIMESTAMP '2010' FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_VALUE_TYPE));
// TSDB_CODE_PAR_INVALID_FUNTION
bind("SELECT cnt(*) FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_FUNC_INVALID_FUNTION));
// TSDB_CODE_PAR_FUNTION_PARA_NUM
// TSDB_CODE_PAR_FUNTION_PARA_TYPE
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
bind("SELECT c2 FROM t1 tt1 JOIN t1 tt2 ON count(*) > 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
bind("SELECT c2 FROM t1 where count(*) > 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
bind("SELECT c2 FROM t1 GROUP BY count(*)");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
bind("SELECT c2 FROM t1 ORDER BY 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT));
bind("SELECT c2 FROM t1 ORDER BY 2");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT));
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
bind("SELECT count(*) cnt FROM t1 HAVING c1 > 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
bind("SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c1 > 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
bind("SELECT count(*), c1 cnt FROM t1 GROUP BY c2 HAVING c2 > 0");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
bind("SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c2 > 0 ORDER BY c1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
bind("SELECT count(*), c1 FROM t1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
bind("SELECT count(*) FROM t1 ORDER BY c1");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
bind("SELECT c1 FROM t1 ORDER BY count(*)");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
bind("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 0 ORDER BY ts");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
bind("SELECT DISTINCT c1 FROM t1 WHERE c1 > 0 ORDER BY count(c2)");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
bind("SELECT DISTINCT c2 FROM t1 WHERE c1 > 0 ORDER BY count(c2)");
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
}
TEST_F(ParserTest, showUsers) {
setDatabase("root", "test");
bind("show users");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createDnode) {
setDatabase("root", "test");
bind("create dnode abc1 port 7000");
ASSERT_TRUE(run());
bind("create dnode 1.1.1.1 port 9000");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showDnodes) {
setDatabase("root", "test");
bind("show dnodes");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, alterDnode) {
setDatabase("root", "test");
bind("alter dnode 1 'resetLog'");
ASSERT_TRUE(run());
bind("alter dnode 1 'debugFlag' '134'");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createDatabase) {
setDatabase("root", "test");
bind("create database wxy_db");
ASSERT_TRUE(run());
bind(
"create database if not exists wxy_db "
"BLOCKS 100 "
"CACHE 100 "
"CACHELAST 2 "
"COMP 1 "
"DAYS 100 "
"FSYNC 100 "
"MAXROWS 1000 "
"MINROWS 100 "
"KEEP 100 "
"PRECISION 'ms' "
"QUORUM 1 "
"REPLICA 3 "
"TTL 100 "
"WAL 2 "
"VGROUPS 100 "
"SINGLE_STABLE 0 "
"STREAM_MODE 1 "
"RETENTIONS '15s:7d,1m:21d,15m:5y'");
ASSERT_TRUE(run());
bind(
"create database if not exists wxy_db "
"DAYS 100m "
"KEEP 200m,300h,400d ");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, alterDatabase) {
setDatabase("root", "test");
bind("alter database wxy_db BLOCKS 200");
ASSERT_TRUE(run());
bind(
"alter database wxy_db "
"BLOCKS 200 "
"CACHELAST 1 "
"FSYNC 200 "
"KEEP 200 "
"QUORUM 2 "
"WAL 1 ");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showDatabase) {
setDatabase("root", "test");
bind("show databases");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, useDatabase) {
setDatabase("root", "test");
bind("use wxy_db");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createTable) {
setDatabase("root", "test");
bind("create table t1(ts timestamp, c1 int)");
ASSERT_TRUE(run());
bind(
"create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
"c14 JSON, c15 VARCHAR(50)) "
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)");
ASSERT_TRUE(run());
bind(
"create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
"c14 JSON, c15 VARCHAR(50)) "
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 "
"BINARY(20), a8 SMALLINT, "
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
"a14 JSON, a15 VARCHAR(50)) "
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
ASSERT_TRUE(run());
bind("create table if not exists t1 using st1 tags(1, 'wxy')");
ASSERT_TRUE(run());
bind(
"create table "
"if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') "
"if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') "
"if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') "
"if not exists test.t4 using test.st1 (tag1, tag2) tags(3, null) "
"if not exists test.t5 using test.st1 (tag1, tag2) tags(null, 'abc') "
"if not exists test.t6 using test.st1 (tag1, tag2) tags(null, null)");
ASSERT_TRUE(run());
bind("create stable t1(ts timestamp, c1 int) TAGS(id int)");
ASSERT_TRUE(run());
bind(
"create stable if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
"c14 JSON, c15 VARCHAR(50)) "
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 "
"BINARY(20), a8 SMALLINT, "
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
"a14 JSON, a15 VARCHAR(50)) "
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showTables) {
setDatabase("root", "test");
bind("show tables");
ASSERT_TRUE(run());
bind("show test.tables");
ASSERT_TRUE(run());
bind("show tables like 'c%'");
ASSERT_TRUE(run());
bind("show test.tables like 'c%'");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showStables) {
setDatabase("root", "test");
bind("show stables");
ASSERT_TRUE(run());
bind("show test.stables");
ASSERT_TRUE(run());
bind("show stables like 'c%'");
ASSERT_TRUE(run());
bind("show test.stables like 'c%'");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showVgroups) {
setDatabase("root", "test");
bind("show vgroups");
ASSERT_TRUE(run());
bind("show test.vgroups");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showMnodes) {
setDatabase("root", "test");
bind("show mnodes");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showModules) {
setDatabase("root", "test");
bind("show modules");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showQnodes) {
setDatabase("root", "test");
bind("show qnodes");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showFunctions) {
setDatabase("root", "test");
bind("show functions");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showIndexes) {
setDatabase("root", "test");
bind("show indexes from t1");
ASSERT_TRUE(run());
bind("show indexes from t1 from test");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, showStreams) {
setDatabase("root", "test");
bind("show streams");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createSmaIndex) {
setDatabase("root", "test");
bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropIndex) {
setDatabase("root", "test");
bind("drop index index1 on t1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createQnode) {
setDatabase("root", "test");
bind("create qnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropQnode) {
setDatabase("root", "test");
bind("drop qnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createBnode) {
setDatabase("root", "test");
bind("create bnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropBnode) {
setDatabase("root", "test");
bind("drop bnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createSnode) {
setDatabase("root", "test");
bind("create snode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropSnode) {
setDatabase("root", "test");
bind("drop snode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createMnode) {
setDatabase("root", "test");
bind("create mnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropMnode) {
setDatabase("root", "test");
bind("drop mnode on dnode 1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createTopic) {
setDatabase("root", "test");
bind("create topic tp1 as select * from t1");
ASSERT_TRUE(run());
bind("create topic if not exists tp1 as select * from t1");
ASSERT_TRUE(run());
bind("create topic tp1 as test");
ASSERT_TRUE(run());
bind("create topic if not exists tp1 as test");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, dropTopic) {
setDatabase("root", "test");
bind("drop topic tp1");
ASSERT_TRUE(run());
bind("drop topic if exists tp1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, createStream) {
setDatabase("root", "test");
bind("create stream s1 as select * from t1");
ASSERT_TRUE(run());
bind("create stream if not exists s1 as select * from t1");
ASSERT_TRUE(run());
bind("create stream s1 into st1 as select * from t1");
ASSERT_TRUE(run());
bind("create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from t1");
ASSERT_TRUE(run());
}
TEST_F(ParserTest, explain) {
setDatabase("root", "test");
bind("explain SELECT * FROM t1");
ASSERT_TRUE(run());
bind("explain analyze SELECT * FROM t1");
ASSERT_TRUE(run());
bind("explain analyze verbose true ratio 0.01 SELECT * FROM t1");
ASSERT_TRUE(run());
}

View File

@ -748,10 +748,10 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
SLogicNode* pRoot = NULL; SLogicNode* pRoot = NULL;
int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot); int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot); code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot); code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot); code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
@ -944,9 +944,16 @@ static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator*
} }
static int32_t getMsgType(ENodeType sqlType) { static int32_t getMsgType(ENodeType sqlType) {
return (QUERY_NODE_CREATE_TABLE_STMT == sqlType || QUERY_NODE_CREATE_MULTI_TABLE_STMT == sqlType) switch (sqlType) {
? TDMT_VND_CREATE_TABLE case QUERY_NODE_CREATE_TABLE_STMT:
: TDMT_VND_SUBMIT; case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
return TDMT_VND_CREATE_TABLE;
case QUERY_NODE_DROP_TABLE_STMT:
return TDMT_VND_DROP_TABLE;
default:
break;
}
return TDMT_VND_SUBMIT;
} }
static int32_t createVnodeModifLogicNode(SLogicPlanContext* pCxt, SVnodeModifOpStmt* pStmt, SLogicNode** pLogicNode) { static int32_t createVnodeModifLogicNode(SLogicPlanContext* pCxt, SVnodeModifOpStmt* pStmt, SLogicNode** pLogicNode) {

View File

@ -206,6 +206,8 @@ static int32_t cpdMergeCond(SNode** pDst, SNode** pSrc) {
if (NULL == pLogicCond) { if (NULL == pLogicCond) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
pLogicCond->condType = LOGIC_COND_TYPE_AND; pLogicCond->condType = LOGIC_COND_TYPE_AND;
int32_t code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc); int32_t code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
@ -520,6 +522,7 @@ static int32_t cpdPushCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SN
default: default:
break; break;
} }
planError("cpdPushCondToChild failed, invalid logic plan node %s", nodesNodeName(nodeType(pChild)));
return TSDB_CODE_PLAN_INTERNAL_ERROR; return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }

View File

@ -272,6 +272,7 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
} }
// pIndex is definitely not NULL, otherwise it is a bug // pIndex is definitely not NULL, otherwise it is a bug
if (NULL == pIndex) { if (NULL == pIndex) {
planError("doSetSlotId failed, invalid slot name %s", name);
pCxt->errCode = TSDB_CODE_PLAN_INTERNAL_ERROR; pCxt->errCode = TSDB_CODE_PLAN_INTERNAL_ERROR;
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
@ -435,12 +436,15 @@ static void vgroupInfoToNodeAddr(const SVgroupInfo* vg, SQueryNodeAddr* pNodeAdd
pNodeAddr->epSet = vg->epSet; pNodeAddr->epSet = vg->epSet;
} }
static int32_t createTagScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) { static int32_t createTagScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode,
SPhysiNode** pPhyNode) {
STagScanPhysiNode* pTagScan = (STagScanPhysiNode*)makePhysiNode( STagScanPhysiNode* pTagScan = (STagScanPhysiNode*)makePhysiNode(
pCxt, pScanLogicNode->pMeta->tableInfo.precision, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN); pCxt, pScanLogicNode->pMeta->tableInfo.precision, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN);
if (NULL == pTagScan) { if (NULL == pTagScan) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
taosArrayPush(pCxt->pExecNodeList, &pSubplan->execNode);
return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pTagScan, pPhyNode); return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pTagScan, pPhyNode);
} }
@ -514,7 +518,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
SPhysiNode** pPhyNode) { SPhysiNode** pPhyNode) {
switch (pScanLogicNode->scanType) { switch (pScanLogicNode->scanType) {
case SCAN_TYPE_TAG: case SCAN_TYPE_TAG:
return createTagScanPhysiNode(pCxt, pScanLogicNode, pPhyNode); return createTagScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode);
case SCAN_TYPE_TABLE: case SCAN_TYPE_TABLE:
return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode);
case SCAN_TYPE_SYSTEM_TABLE: case SCAN_TYPE_SYSTEM_TABLE:

View File

@ -104,8 +104,9 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes; pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t inputSize = (NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes);
pVal->node.resType.type = pParam->buffer_type; pVal->node.resType.type = pParam->buffer_type;
pVal->node.resType.bytes = NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes; pVal->node.resType.bytes = inputSize;
switch (pParam->buffer_type) { switch (pParam->buffer_type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
pVal->datum.b = *((bool*)pParam->buffer); pVal->datum.b = *((bool*)pParam->buffer);
@ -130,7 +131,6 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
break; break;
case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY: case TSDB_DATA_TYPE_VARBINARY:
case TSDB_DATA_TYPE_NCHAR:
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1); pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
if (NULL == pVal->datum.p) { if (NULL == pVal->datum.p) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
@ -138,6 +138,21 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
varDataSetLen(pVal->datum.p, pVal->node.resType.bytes); varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes); strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes);
break; break;
case TSDB_DATA_TYPE_NCHAR: {
pVal->node.resType.bytes *= TSDB_NCHAR_SIZE;
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
if (NULL == pVal->datum.p) {
return TSDB_CODE_OUT_OF_MEMORY;
}
int32_t output = 0;
if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes, &output)) {
return errno;
}
varDataSetLen(pVal->datum.p, output);
pVal->node.resType.bytes = output;
break;
}
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
pVal->datum.i = *((int64_t*)pParam->buffer); pVal->datum.i = *((int64_t*)pParam->buffer);
break; break;
@ -181,13 +196,20 @@ static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) {
int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId) { int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId) {
int32_t size = taosArrayGetSize(pPlan->pPlaceholderValues); int32_t size = taosArrayGetSize(pPlan->pPlaceholderValues);
int32_t code = 0;
if (colIdx < 0) { if (colIdx < 0) {
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, i), pParams + i); code = setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, i), pParams + i);
if (code) {
return code;
}
} }
} else { } else {
setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, colIdx), pParams); code = setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, colIdx), pParams);
if (code) {
return code;
}
} }
if (colIdx < 0 || ((colIdx + 1) == size)) { if (colIdx < 0 || ((colIdx + 1) == size)) {

View File

@ -31,3 +31,8 @@ if(${BUILD_WINGETOPT})
) )
target_link_libraries(plannerTest PUBLIC wingetopt) target_link_libraries(plannerTest PUBLIC wingetopt)
endif() endif()
add_test(
NAME plannerTest
COMMAND plannerTest
)

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanBasicTest : public PlannerTestBase {};
TEST_F(PlanBasicTest, select) {
useDb("root", "test");
// run("select * from t1");
// run("select 1 from t1");
// run("select * from st1");
run("select 1 from st1");
}
TEST_F(PlanBasicTest, where) {
useDb("root", "test");
run("select * from t1 where c1 > 10");
}
TEST_F(PlanBasicTest, join) {
useDb("root", "test");
run("select t1.c1, t2.c2 from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
run("select t1.c1, t2.c2 from st1s1 t1 join st1s2 t2 on t1.ts = t2.ts");
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanDistinctTest : public PlannerTestBase {};
TEST_F(PlanDistinctTest, basic) {
useDb("root", "test");
// distinct single col
run("select distinct c1 from t1");
// distinct col list
run("select distinct c1, c2 from t1");
}
TEST_F(PlanDistinctTest, expr) {
useDb("root", "test");
run("select distinct c1, c2 + 10 from t1");
}
TEST_F(PlanDistinctTest, withOrderBy) {
useDb("root", "test");
run("select distinct c1 + 10 a from t1 order by a");
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanGroupByTest : public PlannerTestBase {};
TEST_F(PlanGroupByTest, basic) {
useDb("root", "test");
run("select count(*) from t1");
run("select c1, max(c3), min(c3), count(*) from t1 group by c1");
run("select c1 + c3, c1 + count(*) from t1 where c2 = 'abc' group by c1, c3");
run("select c1 + c3, sum(c4 * c5) from t1 where concat(c2, 'wwww') = 'abcwww' group by c1 + c3");
run("select sum(ceil(c1)) from t1 group by ceil(c1)");
}
TEST_F(PlanGroupByTest, withOrderBy) {
useDb("root", "test");
// order by aggfunc
run("select count(*), sum(c1) from t1 order by sum(c1)");
// order by alias of aggfunc
// run("select count(*), sum(c1) a from t1 order by a");
}

View File

@ -13,25 +13,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if 0 #include "planTestUtil.h"
#include "tsdb.h" #include "planner.h"
#ifndef _TSDB_PLUGINS
int tsdbScanFGroup(STsdbScanHandle* pScanHandle, char* rootDir, int fid) { return 0; } using namespace std;
STsdbScanHandle* tsdbNewScanHandle() { return NULL; } class PlanIntervalTest : public PlannerTestBase {};
void tsdbSetScanLogStream(STsdbScanHandle* pScanHandle, FILE* fLogStream) {} TEST_F(PlanIntervalTest, basic) {
useDb("root", "test");
int tsdbSetAndOpenScanFile(STsdbScanHandle* pScanHandle, char* rootDir, int fid) { return 0; } run("select count(*) from t1 interval(10s)");
}
int tsdbScanSBlockIdx(STsdbScanHandle* pScanHandle) { return 0; } TEST_F(PlanIntervalTest, pseudoCol) {
useDb("root", "test");
int tsdbScanSBlock(STsdbScanHandle* pScanHandle, int idx) { return 0; } run("select _wstartts, _wduration, _wendts, count(*) from t1 interval(10s)");
}
int tsdbCloseScanFile(STsdbScanHandle* pScanHandle) { return 0; } TEST_F(PlanIntervalTest, fill) {
useDb("root", "test");
void tsdbFreeScanHandle(STsdbScanHandle* pScanHandle) {} run("select count(*) from t1 interval(10s) fill(linear)");
#endif run("select count(*), sum(c1) from t1 interval(10s) fill(value, 10, 20)");
#endif }

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanJoinTest : public PlannerTestBase {};
TEST_F(PlanJoinTest, basic) {
useDb("root", "test");
run("select t1.c1, t2.c2 from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
run("select t1.*, t2.* from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
// run("select t1.c1, t2.c1 from st1s1 t1 join st1s2 t2 on t1.ts = t2.ts where t1.c1 > t2.c1 and t1.c2 = 'abc' and "
// "t2.c2 = 'qwe'");
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanLimitTest : public PlannerTestBase {};
TEST_F(PlanLimitTest, limit) {
useDb("root", "test");
run("select * from t1 limit 2");
run("select * from t1 limit 5 offset 2");
run("select * from t1 limit 2, 5");
}
TEST_F(PlanLimitTest, slimit) {
useDb("root", "test");
run("select * from t1 partition by c1 slimit 2");
run("select * from t1 partition by c1 slimit 5 soffset 2");
run("select * from t1 partition by c1 slimit 2, 5");
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanOrderByTest : public PlannerTestBase {};
TEST_F(PlanOrderByTest, basic) {
useDb("root", "test");
// order by key is in the projection list
run("select c1 from t1 order by c1");
// order by key is not in the projection list
run("select c1 from t1 order by c2");
}
TEST_F(PlanOrderByTest, expr) {
useDb("root", "test");
run("select * from t1 order by c1 + 10, c2");
}
TEST_F(PlanOrderByTest, nullsOrder) {
useDb("root", "test");
run("select * from t1 order by c1 desc nulls first");
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanOtherTest : public PlannerTestBase {};
TEST_F(PlanOtherTest, createTopic) {
useDb("root", "test");
run("create topic tp as SELECT * FROM st1");
}
TEST_F(PlanOtherTest, createStream) {
useDb("root", "test");
run("create stream if not exists s1 trigger window_close watermark 10s into st1 as select count(*) from t1 "
"interval(10s)");
}
TEST_F(PlanOtherTest, createSmaIndex) {
useDb("root", "test");
run("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) interval(10s)");
}
TEST_F(PlanOtherTest, explain) {
useDb("root", "test");
run("explain SELECT * FROM t1");
run("explain analyze SELECT * FROM t1");
run("explain analyze verbose true ratio 0.01 SELECT * FROM t1");
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanPartitionByTest : public PlannerTestBase {};
TEST_F(PlanPartitionByTest, basic) {
useDb("root", "test");
run("select * from t1 partition by c1");
}
TEST_F(PlanPartitionByTest, withAggFunc) {
useDb("root", "test");
run("select count(*) from t1 partition by c1");
}
TEST_F(PlanPartitionByTest, withInterval) {
useDb("root", "test");
// normal/child table
run("select count(*) from t1 partition by c1 interval(10s)");
// super table
run("select count(*) from st1 partition by tag1, tag2 interval(10s)");
}
TEST_F(PlanPartitionByTest, withGroupBy) {
useDb("root", "test");
run("select count(*) from t1 partition by c1 group by c2");
}

View File

@ -13,14 +13,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "parTestUtil.h" #include "planTestUtil.h"
#include "planner.h"
using namespace std; using namespace std;
class ParserAlterTest : public ParserTestBase {}; class PlanSessionTest : public PlannerTestBase {};
TEST_F(ParserAlterTest, stmt) { TEST_F(PlanSessionTest, basic) {
useDb("root", "test"); useDb("root", "test");
run("create database db1"); run("select count(*) from t1 session(ts, 10s)");
} }

View File

@ -13,12 +13,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _DEFAULT_SOURCE #include "planTestUtil.h"
#include "vnd.h" #include "planner.h"
// #include "vnodeInt.h"
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; } using namespace std;
int32_t vnodeCompact(SVnode *pVnode) { return 0; } class PlanStateTest : public PlannerTestBase {};
int32_t vnodeSync(SVnode *pVnode) { return 0; } TEST_F(PlanStateTest, basic) {
useDb("root", "test");
run("select count(*) from t1 state_window(c1)");
}
TEST_F(PlanStateTest, stateExpr) {
useDb("root", "test");
run("select count(*) from t1 state_window(c1 + 10)");
}

View File

@ -42,7 +42,7 @@ class PlanStmtTest : public PlannerTestBase {
// todo // todo
} }
private: private:
TAOS_MULTI_BIND* pBindParams_; TAOS_MULTI_BIND* pBindParams_;
int32_t paramNo_; int32_t paramNo_;
}; };
@ -50,5 +50,5 @@ private:
TEST_F(PlanStmtTest, stmt) { TEST_F(PlanStmtTest, stmt) {
useDb("root", "test"); useDb("root", "test");
run("SELECT * FROM t1 where c1 = ?"); run("select * from t1 where c1 = ?");
} }

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planTestUtil.h"
#include "planner.h"
using namespace std;
class PlanSubqeuryTest : public PlannerTestBase {};
TEST_F(PlanSubqeuryTest, basic) {
useDb("root", "test");
run("select * from (select * from t1)");
}
TEST_F(PlanSubqeuryTest, doubleGroupBy) {
useDb("root", "test");
run("select count(*) from (select c1 + c3 a, c1 + count(*) b from t1 where c2 = 'abc' group by c1, c3) where a > 100 "
"group by b");
}

View File

@ -13,19 +13,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TDB_TXN_H_ #include "planTestUtil.h"
#define _TDB_TXN_H_ #include "planner.h"
#ifdef __cplusplus using namespace std;
extern "C" {
#endif
int tdbTxnOpen(TXN *pTxn, int64_t txnid, void *(*xMalloc)(void *, size_t), void (*xFree)(void *, void *), void *xArg, class PlanSysTableTest : public PlannerTestBase {};
int flags);
int tdbTxnClose(TXN *pTxn);
#ifdef __cplusplus TEST_F(PlanSysTableTest, show) {
useDb("root", "test");
run("show tables");
run("show stables");
} }
#endif
#endif /*_TDB_TXN_H_*/ TEST_F(PlanSysTableTest, information) {
useDb("root", "information_schema");
run("show tables");
}

View File

@ -106,6 +106,7 @@ class PlannerTestBaseImpl {
res_.splitLogicPlan_.clear(); res_.splitLogicPlan_.clear();
res_.scaledLogicPlan_.clear(); res_.scaledLogicPlan_.clear();
res_.physiPlan_.clear(); res_.physiPlan_.clear();
res_.physiSubplans_.clear();
} }
void dump() { void dump() {

View File

@ -1,398 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <gtest/gtest.h>
#include "cmdnodes.h"
#include "parser.h"
#include "planInt.h"
using namespace std;
using namespace testing;
class PlannerTest : public Test {
protected:
void setDatabase(const string& acctId, const string& db) {
acctId_ = acctId;
db_ = db;
}
void bind(const char* sql) {
reset();
cxt_.acctId = atoi(acctId_.c_str());
cxt_.db = db_.c_str();
sqlBuf_ = string(sql);
transform(sqlBuf_.begin(), sqlBuf_.end(), sqlBuf_.begin(), ::tolower);
cxt_.sqlLen = strlen(sql);
cxt_.pSql = sqlBuf_.c_str();
}
bool run(bool streamQuery = false) {
int32_t code = qParseQuerySql(&cxt_, &query_);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] qParseQuerySql code:" << code << ", strerror:" << tstrerror(code)
<< ", msg:" << errMagBuf_ << endl;
return false;
}
const string syntaxTreeStr = toString(query_->pRoot, false);
SLogicNode* pLogicNode = nullptr;
SPlanContext cxt = {0};
cxt.queryId = 1;
cxt.acctId = 0;
cxt.streamQuery = streamQuery;
setPlanContext(query_, &cxt);
code = createLogicPlan(&cxt, &pLogicNode);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] createLogicPlan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
}
cout << "====================sql : [" << cxt_.pSql << "]" << endl;
cout << "syntax tree : " << endl;
cout << syntaxTreeStr << endl;
cout << "unformatted logic plan : " << endl;
cout << toString((const SNode*)pLogicNode, false) << endl;
code = optimizeLogicPlan(&cxt, pLogicNode);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] optimizeLogicPlan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
}
SLogicSubplan* pLogicSubplan = nullptr;
code = splitLogicPlan(&cxt, pLogicNode, &pLogicSubplan);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] splitLogicPlan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
}
SQueryLogicPlan* pLogicPlan = NULL;
code = scaleOutLogicPlan(&cxt, pLogicSubplan, &pLogicPlan);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] createPhysiPlan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
}
SArray* pExecNodeList = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SQueryNodeAddr));
code = createPhysiPlan(&cxt, pLogicPlan, &plan_, pExecNodeList);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] createPhysiPlan code:" << code << ", strerror:" << tstrerror(code) << endl;
return false;
}
cout << "unformatted physical plan : " << endl;
cout << toString((const SNode*)plan_, false) << endl;
SNode* pNode;
FOREACH(pNode, plan_->pSubplans) {
SNode* pSubplan;
FOREACH(pSubplan, ((SNodeListNode*)pNode)->pNodeList) {
cout << "unformatted physical subplan : " << endl;
cout << toString(pSubplan, false) << endl;
}
}
return true;
}
private:
static const int max_err_len = 1024;
void setPlanContext(SQuery* pQuery, SPlanContext* pCxt) {
if (QUERY_NODE_CREATE_TOPIC_STMT == nodeType(pQuery->pRoot)) {
pCxt->pAstRoot = ((SCreateTopicStmt*)pQuery->pRoot)->pQuery;
pCxt->topicQuery = true;
} else if (QUERY_NODE_CREATE_INDEX_STMT == nodeType(pQuery->pRoot)) {
SMCreateSmaReq req = {0};
tDeserializeSMCreateSmaReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req);
nodesStringToNode(req.ast, &pCxt->pAstRoot);
pCxt->streamQuery = true;
} else if (QUERY_NODE_CREATE_STREAM_STMT == nodeType(pQuery->pRoot)) {
SCreateStreamStmt* pStmt = (SCreateStreamStmt*)pQuery->pRoot;
pCxt->pAstRoot = pStmt->pQuery;
pCxt->streamQuery = true;
pCxt->triggerType = pStmt->pOptions->triggerType;
pCxt->watermark = (NULL != pStmt->pOptions->pWatermark ? ((SValueNode*)pStmt->pOptions->pWatermark)->datum.i : 0);
} else {
pCxt->pAstRoot = pQuery->pRoot;
}
}
void reset() {
memset(&cxt_, 0, sizeof(cxt_));
memset(errMagBuf_, 0, max_err_len);
cxt_.pMsg = errMagBuf_;
cxt_.msgLen = max_err_len;
}
string toString(const SNode* pRoot, bool format = true) {
char* pStr = NULL;
int32_t len = 0;
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
if (code != TSDB_CODE_SUCCESS) {
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
return string();
}
string str(pStr);
taosMemoryFreeClear(pStr);
return str;
}
string acctId_;
string db_;
char errMagBuf_[max_err_len];
string sqlBuf_;
SParseContext cxt_;
SQuery* query_;
SQueryPlan* plan_;
};
TEST_F(PlannerTest, selectBasic) {
setDatabase("root", "test");
bind("SELECT * FROM t1");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectConstant) {
setDatabase("root", "test");
bind("SELECT 2-1 FROM t1");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectStableBasic) {
setDatabase("root", "test");
bind("SELECT * FROM st1");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectJoin) {
setDatabase("root", "test");
bind("SELECT t1.c1, t2.c2 FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
ASSERT_TRUE(run());
bind("SELECT t1.*, t2.* FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
ASSERT_TRUE(run());
bind(
"SELECT t1.c1, t2.c1 FROM st1s1 t1 join st1s2 t2 on t1.ts = t2.ts where t1.c1 > t2.c1 and t1.c2 = 'abc' and "
"t2.c2 = 'qwe'");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectGroupBy) {
setDatabase("root", "test");
bind("SELECT count(*) FROM t1");
ASSERT_TRUE(run());
bind("SELECT c1, max(c3), min(c3), count(*) FROM t1 GROUP BY c1");
ASSERT_TRUE(run());
bind("SELECT c1 + c3, c1 + count(*) FROM t1 where c2 = 'abc' GROUP BY c1, c3");
ASSERT_TRUE(run());
bind("SELECT c1 + c3, sum(c4 * c5) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
ASSERT_TRUE(run());
bind("SELECT sum(ceil(c1)) FROM t1 GROUP BY ceil(c1)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectSubquery) {
setDatabase("root", "test");
bind(
"SELECT count(*) FROM (SELECT c1 + c3 a, c1 + count(*) b FROM t1 where c2 = 'abc' GROUP BY c1, c3) where a > 100 "
"group by b");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectInterval) {
setDatabase("root", "test");
bind("SELECT count(*) FROM t1 interval(10s)");
ASSERT_TRUE(run());
bind("SELECT _wstartts, _wduration, _wendts, count(*) FROM t1 interval(10s)");
ASSERT_TRUE(run());
bind("SELECT count(*) FROM t1 interval(10s) fill(linear)");
ASSERT_TRUE(run());
bind("SELECT count(*), sum(c1) FROM t1 interval(10s) fill(value, 10, 20)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectSessionWindow) {
setDatabase("root", "test");
bind("SELECT count(*) FROM t1 session(ts, 10s)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectStateWindow) {
setDatabase("root", "test");
bind("SELECT count(*) FROM t1 state_window(c1)");
ASSERT_TRUE(run());
bind("SELECT count(*) FROM t1 state_window(c1 + 10)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectPartitionBy) {
setDatabase("root", "test");
bind("SELECT * FROM t1 partition by c1");
ASSERT_TRUE(run());
bind("SELECT count(*) FROM t1 partition by c1");
ASSERT_TRUE(run());
bind("SELECT count(*) FROM t1 partition by c1 group by c2");
ASSERT_TRUE(run());
bind("SELECT count(*) FROM st1 partition by tag1, tag2 interval(10s)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectOrderBy) {
setDatabase("root", "test");
bind("SELECT c1 FROM t1 order by c1");
ASSERT_TRUE(run());
bind("SELECT c1 FROM t1 order by c2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 order by c1 + 10, c2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 order by c1 desc nulls first");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectGroupByOrderBy) {
setDatabase("root", "test");
bind("select count(*), sum(c1) from t1 order by sum(c1)");
ASSERT_TRUE(run());
bind("select count(*), sum(c1) a from t1 order by a");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectDistinct) {
setDatabase("root", "test");
bind("SELECT distinct c1 FROM t1");
ASSERT_TRUE(run());
bind("SELECT distinct c1, c2 + 10 FROM t1");
ASSERT_TRUE(run());
bind("SELECT distinct c1 + 10 a FROM t1 order by a");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectLimit) {
setDatabase("root", "test");
bind("SELECT * FROM t1 limit 2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 limit 5 offset 2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 limit 2, 5");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, selectSlimit) {
setDatabase("root", "test");
bind("SELECT * FROM t1 partition by c1 slimit 2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 partition by c1 slimit 5 soffset 2");
ASSERT_TRUE(run());
bind("SELECT * FROM t1 partition by c1 slimit 2, 5");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, showTables) {
setDatabase("root", "test");
bind("show tables");
ASSERT_TRUE(run());
setDatabase("root", "information_schema");
bind("show tables");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, showStables) {
setDatabase("root", "test");
bind("show stables");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, createTopic) {
setDatabase("root", "test");
bind("create topic tp as SELECT * FROM st1");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, createStream) {
setDatabase("root", "test");
bind(
"create stream if not exists s1 trigger window_close watermark 10s into st1 as select count(*) from t1 "
"interval(10s)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, createSmaIndex) {
setDatabase("root", "test");
bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
ASSERT_TRUE(run());
}
TEST_F(PlannerTest, explain) {
setDatabase("root", "test");
bind("explain SELECT * FROM t1");
ASSERT_TRUE(run());
bind("explain analyze SELECT * FROM t1");
ASSERT_TRUE(run());
bind("explain analyze verbose true ratio 0.01 SELECT * FROM t1");
ASSERT_TRUE(run());
}

View File

@ -23,6 +23,7 @@ extern "C" {
#include "qworker.h" #include "qworker.h"
#include "tlockfree.h" #include "tlockfree.h"
#include "ttimer.h" #include "ttimer.h"
#include "tref.h"
#define QW_DEFAULT_SCHEDULER_NUMBER 10000 #define QW_DEFAULT_SCHEDULER_NUMBER 10000
#define QW_DEFAULT_TASK_NUMBER 10000 #define QW_DEFAULT_TASK_NUMBER 10000
@ -85,6 +86,12 @@ typedef struct SQWMsg {
SQWConnInfo connInfo; SQWConnInfo connInfo;
} SQWMsg; } SQWMsg;
typedef struct SQWHbParam {
bool inUse;
int32_t qwrId;
int64_t refId;
} SQWHbParam;
typedef struct SQWHbInfo { typedef struct SQWHbInfo {
SSchedulerHbRsp rsp; SSchedulerHbRsp rsp;
SQWConnInfo connInfo; SQWConnInfo connInfo;
@ -137,7 +144,8 @@ typedef struct SQWSchStatus {
} SQWSchStatus; } SQWSchStatus;
// Qnode/Vnode level task management // Qnode/Vnode level task management
typedef struct SQWorkerMgmt { typedef struct SQWorker {
int64_t refId;
SQWorkerCfg cfg; SQWorkerCfg cfg;
int8_t nodeType; int8_t nodeType;
int32_t nodeId; int32_t nodeId;
@ -148,9 +156,17 @@ typedef struct SQWorkerMgmt {
SHashObj *schHash; // key: schedulerId, value: SQWSchStatus SHashObj *schHash; // key: schedulerId, value: SQWSchStatus
SHashObj *ctxHash; // key: queryId+taskId, value: SQWTaskCtx SHashObj *ctxHash; // key: queryId+taskId, value: SQWTaskCtx
SMsgCb msgCb; SMsgCb msgCb;
} SQWorker;
typedef struct SQWorkerMgmt {
SRWLatch lock;
int32_t qwRef;
int32_t qwNum;
SQWHbParam param[1024];
int32_t paramIdx;
} SQWorkerMgmt; } SQWorkerMgmt;
#define QW_FPARAMS_DEF SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, int64_t rId #define QW_FPARAMS_DEF SQWorker *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, int64_t rId
#define QW_IDS() sId, qId, tId, rId #define QW_IDS() sId, qId, tId, rId
#define QW_FPARAMS() mgmt, QW_IDS() #define QW_FPARAMS() mgmt, QW_IDS()
@ -209,13 +225,13 @@ typedef struct SQWorkerMgmt {
} \ } \
} while (0) } while (0)
#define QW_ELOG(param, ...) qError("QW:%p " param, mgmt, __VA_ARGS__) #define QW_ELOG(_param, ...) qError("QW:%p " _param, mgmt, __VA_ARGS__)
#define QW_DLOG(param, ...) qDebug("QW:%p " param, mgmt, __VA_ARGS__) #define QW_DLOG(_param, ...) qDebug("QW:%p " _param, mgmt, __VA_ARGS__)
#define QW_DUMP(param, ...) \ #define QW_DUMP(_param, ...) \
do { \ do { \
if (gQWDebug.dumpEnable) { \ if (gQWDebug.dumpEnable) { \
qDebug("QW:%p " param, mgmt, __VA_ARGS__); \ qDebug("QW:%p " _param, mgmt, __VA_ARGS__); \
} \ } \
} while (0) } while (0)
@ -282,6 +298,14 @@ typedef struct SQWorkerMgmt {
} \ } \
} while (0) } while (0)
extern SQWorkerMgmt gQwMgmt;
FORCE_INLINE SQWorker *qwAcquire(int64_t refId) { return (SQWorker *)taosAcquireRef(atomic_load_32(&gQwMgmt.qwRef), refId); }
FORCE_INLINE int32_t qwRelease(int64_t refId) { return taosReleaseRef(gQwMgmt.qwRef, refId); }
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -28,7 +28,7 @@ int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg);
int32_t qwProcessReady(QW_FPARAMS_DEF, SQWMsg *qwMsg); int32_t qwProcessReady(QW_FPARAMS_DEF, SQWMsg *qwMsg);
int32_t qwProcessFetch(QW_FPARAMS_DEF, SQWMsg *qwMsg); int32_t qwProcessFetch(QW_FPARAMS_DEF, SQWMsg *qwMsg);
int32_t qwProcessDrop(QW_FPARAMS_DEF, SQWMsg *qwMsg); int32_t qwProcessDrop(QW_FPARAMS_DEF, SQWMsg *qwMsg);
int32_t qwProcessHb(SQWorkerMgmt *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req); int32_t qwProcessHb(SQWorker *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req);
int32_t qwBuildAndSendDropRsp(SQWConnInfo *pConn, int32_t code); int32_t qwBuildAndSendDropRsp(SQWConnInfo *pConn, int32_t code);
int32_t qwBuildAndSendCancelRsp(SQWConnInfo *pConn, int32_t code); int32_t qwBuildAndSendCancelRsp(SQWConnInfo *pConn, int32_t code);
@ -41,10 +41,10 @@ int32_t qwBuildAndSendQueryRsp(SQWConnInfo *pConn, int32_t code);
int32_t qwBuildAndSendExplainRsp(SQWConnInfo *pConn, SExplainExecInfo *execInfo, int32_t num); int32_t qwBuildAndSendExplainRsp(SQWConnInfo *pConn, SExplainExecInfo *execInfo, int32_t num);
void qwFreeFetchRsp(void *msg); void qwFreeFetchRsp(void *msg);
int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp); int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp);
int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp); int32_t qwGetSchTasksStatus(SQWorker *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp);
int32_t qwBuildAndSendHbRsp(SQWConnInfo *pConn, SSchedulerHbRsp *rsp, int32_t code); int32_t qwBuildAndSendHbRsp(SQWConnInfo *pConn, SSchedulerHbRsp *rsp, int32_t code);
int32_t qwRegisterQueryBrokenLinkArg(QW_FPARAMS_DEF, SQWConnInfo *pConn); int32_t qwRegisterQueryBrokenLinkArg(QW_FPARAMS_DEF, SQWConnInfo *pConn);
int32_t qwRegisterHbBrokenLinkArg(SQWorkerMgmt *mgmt, uint64_t sId, SQWConnInfo *pConn); int32_t qwRegisterHbBrokenLinkArg(SQWorker *mgmt, uint64_t sId, SQWConnInfo *pConn);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -10,6 +10,11 @@
#include "tname.h" #include "tname.h"
SQWDebug gQWDebug = {.statusEnable = true, .dumpEnable = true}; SQWDebug gQWDebug = {.statusEnable = true, .dumpEnable = true};
SQWorkerMgmt gQwMgmt = {
.lock = 0,
.qwRef = -1,
.qwNum = 0,
};
int32_t qwDbgValidateStatus(QW_FPARAMS_DEF, int8_t oriStatus, int8_t newStatus, bool *ignore) { int32_t qwDbgValidateStatus(QW_FPARAMS_DEF, int8_t oriStatus, int8_t newStatus, bool *ignore) {
if (!gQWDebug.statusEnable) { if (!gQWDebug.statusEnable) {
@ -98,7 +103,7 @@ _return:
void qwDbgDumpSchInfo(SQWSchStatus *sch, int32_t i) {} void qwDbgDumpSchInfo(SQWSchStatus *sch, int32_t i) {}
void qwDbgDumpMgmtInfo(SQWorkerMgmt *mgmt) { void qwDbgDumpMgmtInfo(SQWorker *mgmt) {
if (!gQWDebug.dumpEnable) { if (!gQWDebug.dumpEnable) {
return; return;
} }
@ -186,7 +191,7 @@ int32_t qwSetTaskStatus(QW_FPARAMS_DEF, SQWTaskStatus *task, int8_t status) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwAddSchedulerImpl(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType) { int32_t qwAddSchedulerImpl(SQWorker *mgmt, uint64_t sId, int32_t rwType) {
SQWSchStatus newSch = {0}; SQWSchStatus newSch = {0};
newSch.tasksHash = newSch.tasksHash =
taosHashInit(mgmt->cfg.maxSchTaskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); taosHashInit(mgmt->cfg.maxSchTaskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
@ -213,7 +218,7 @@ int32_t qwAddSchedulerImpl(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwAcquireSchedulerImpl(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch, int32_t nOpt) { int32_t qwAcquireSchedulerImpl(SQWorker *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch, int32_t nOpt) {
while (true) { while (true) {
QW_LOCK(rwType, &mgmt->schLock); QW_LOCK(rwType, &mgmt->schLock);
*sch = taosHashGet(mgmt->schHash, &sId, sizeof(sId)); *sch = taosHashGet(mgmt->schHash, &sId, sizeof(sId));
@ -240,15 +245,15 @@ int32_t qwAcquireSchedulerImpl(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType,
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwAcquireAddScheduler(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch) { int32_t qwAcquireAddScheduler(SQWorker *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch) {
return qwAcquireSchedulerImpl(mgmt, sId, rwType, sch, QW_NOT_EXIST_ADD); return qwAcquireSchedulerImpl(mgmt, sId, rwType, sch, QW_NOT_EXIST_ADD);
} }
int32_t qwAcquireScheduler(SQWorkerMgmt *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch) { int32_t qwAcquireScheduler(SQWorker *mgmt, uint64_t sId, int32_t rwType, SQWSchStatus **sch) {
return qwAcquireSchedulerImpl(mgmt, sId, rwType, sch, QW_NOT_EXIST_RET_ERR); return qwAcquireSchedulerImpl(mgmt, sId, rwType, sch, QW_NOT_EXIST_RET_ERR);
} }
void qwReleaseScheduler(int32_t rwType, SQWorkerMgmt *mgmt) { QW_UNLOCK(rwType, &mgmt->schLock); } void qwReleaseScheduler(int32_t rwType, SQWorker *mgmt) { QW_UNLOCK(rwType, &mgmt->schLock); }
int32_t qwAcquireTaskStatus(QW_FPARAMS_DEF, int32_t rwType, SQWSchStatus *sch, SQWTaskStatus **task) { int32_t qwAcquireTaskStatus(QW_FPARAMS_DEF, int32_t rwType, SQWSchStatus *sch, SQWTaskStatus **task) {
char id[sizeof(qId) + sizeof(tId)] = {0}; char id[sizeof(qId) + sizeof(tId)] = {0};
@ -384,7 +389,7 @@ int32_t qwAddTaskCtx(QW_FPARAMS_DEF) { QW_RET(qwAddTaskCtxImpl(QW_FPARAMS(), fal
int32_t qwAddAcquireTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx) { return qwAddTaskCtxImpl(QW_FPARAMS(), true, ctx); } int32_t qwAddAcquireTaskCtx(QW_FPARAMS_DEF, SQWTaskCtx **ctx) { return qwAddTaskCtxImpl(QW_FPARAMS(), true, ctx); }
void qwReleaseTaskCtx(SQWorkerMgmt *mgmt, void *ctx) { taosHashRelease(mgmt->ctxHash, ctx); } void qwReleaseTaskCtx(SQWorker *mgmt, void *ctx) { taosHashRelease(mgmt->ctxHash, ctx); }
void qwFreeTaskHandle(QW_FPARAMS_DEF, qTaskInfo_t *taskHandle) { void qwFreeTaskHandle(QW_FPARAMS_DEF, qTaskInfo_t *taskHandle) {
// Note: free/kill may in RC // Note: free/kill may in RC
@ -606,7 +611,7 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryEnd) {
QW_RET(code); QW_RET(code);
} }
int32_t qwGenerateSchHbRsp(SQWorkerMgmt *mgmt, SQWSchStatus *sch, SQWHbInfo *hbInfo) { int32_t qwGenerateSchHbRsp(SQWorker *mgmt, SQWSchStatus *sch, SQWHbInfo *hbInfo) {
int32_t taskNum = 0; int32_t taskNum = 0;
hbInfo->connInfo = sch->hbConnInfo; hbInfo->connInfo = sch->hbConnInfo;
@ -1262,7 +1267,7 @@ _return:
QW_RET(TSDB_CODE_SUCCESS); QW_RET(TSDB_CODE_SUCCESS);
} }
int32_t qwProcessHbLinkBroken(SQWorkerMgmt *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req) { int32_t qwProcessHbLinkBroken(SQWorker *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req) {
int32_t code = 0; int32_t code = 0;
SSchedulerHbRsp rsp = {0}; SSchedulerHbRsp rsp = {0};
SQWSchStatus * sch = NULL; SQWSchStatus * sch = NULL;
@ -1288,7 +1293,7 @@ int32_t qwProcessHbLinkBroken(SQWorkerMgmt *mgmt, SQWMsg *qwMsg, SSchedulerHbReq
QW_RET(TSDB_CODE_SUCCESS); QW_RET(TSDB_CODE_SUCCESS);
} }
int32_t qwProcessHb(SQWorkerMgmt *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req) { int32_t qwProcessHb(SQWorker *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req) {
int32_t code = 0; int32_t code = 0;
SSchedulerHbRsp rsp = {0}; SSchedulerHbRsp rsp = {0};
SQWSchStatus * sch = NULL; SQWSchStatus * sch = NULL;
@ -1333,7 +1338,19 @@ _return:
} }
void qwProcessHbTimerEvent(void *param, void *tmrId) { void qwProcessHbTimerEvent(void *param, void *tmrId) {
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)param; SQWHbParam* hbParam = (SQWHbParam*)param;
if (hbParam->qwrId != atomic_load_32(&gQwMgmt.qwRef)) {
return;
}
int64_t refId = hbParam->refId;
SQWorker *mgmt = qwAcquire(refId);
if (NULL == mgmt) {
QW_DLOG("qwAcquire %" PRIx64 "failed", refId);
taosMemoryFree(param);
return;
}
SQWSchStatus *sch = NULL; SQWSchStatus *sch = NULL;
int32_t taskNum = 0; int32_t taskNum = 0;
SQWHbInfo * rspList = NULL; SQWHbInfo * rspList = NULL;
@ -1347,6 +1364,7 @@ void qwProcessHbTimerEvent(void *param, void *tmrId) {
if (schNum <= 0) { if (schNum <= 0) {
QW_UNLOCK(QW_READ, &mgmt->schLock); QW_UNLOCK(QW_READ, &mgmt->schLock);
taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer); taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer);
qwRelease(refId);
return; return;
} }
@ -1355,6 +1373,7 @@ void qwProcessHbTimerEvent(void *param, void *tmrId) {
QW_UNLOCK(QW_READ, &mgmt->schLock); QW_UNLOCK(QW_READ, &mgmt->schLock);
QW_ELOG("calloc %d SQWHbInfo failed", schNum); QW_ELOG("calloc %d SQWHbInfo failed", schNum);
taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer); taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer);
qwRelease(refId);
return; return;
} }
@ -1396,6 +1415,74 @@ _return:
taosMemoryFreeClear(rspList); taosMemoryFreeClear(rspList);
taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer); taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer);
qwRelease(refId);
}
void qwCloseRef(void) {
taosWLockLatch(&gQwMgmt.lock);
if (atomic_load_32(&gQwMgmt.qwNum) <= 0 && gQwMgmt.qwRef >= 0) {
taosCloseRef(gQwMgmt.qwRef);
gQwMgmt.qwRef= -1;
}
taosWUnLockLatch(&gQwMgmt.lock);
}
void qwDestroyImpl(void *pMgmt) {
SQWorker *mgmt = (SQWorker *)pMgmt;
taosTmrStopA(&mgmt->hbTimer);
taosTmrCleanUp(mgmt->timer);
// TODO STOP ALL QUERY
// TODO FREE ALL
taosHashCleanup(mgmt->ctxHash);
taosHashCleanup(mgmt->schHash);
taosMemoryFree(mgmt);
atomic_sub_fetch_32(&gQwMgmt.qwNum, 1);
qwCloseRef();
}
int32_t qwOpenRef(void) {
taosWLockLatch(&gQwMgmt.lock);
if (gQwMgmt.qwRef < 0) {
gQwMgmt.qwRef= taosOpenRef(100, qwDestroyImpl);
if (gQwMgmt.qwRef < 0) {
taosWUnLockLatch(&gQwMgmt.lock);
qError("init qworker ref failed");
QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
}
}
taosWUnLockLatch(&gQwMgmt.lock);
return TSDB_CODE_SUCCESS;
}
void qwSetHbParam(int64_t refId, SQWHbParam **pParam) {
int32_t paramIdx = 0;
int32_t newParamIdx = 0;
while (true) {
paramIdx = atomic_load_32(&gQwMgmt.paramIdx);
if (paramIdx == tListLen(gQwMgmt.param)) {
newParamIdx = 0;
} else {
newParamIdx = paramIdx + 1;
}
if (paramIdx == atomic_val_compare_exchange_32(&gQwMgmt.paramIdx, paramIdx, newParamIdx)) {
break;
}
}
gQwMgmt.param[paramIdx].qwrId = gQwMgmt.qwRef;
gQwMgmt.param[paramIdx].refId = refId;
*pParam = &gQwMgmt.param[paramIdx];
} }
int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qWorkerMgmt, const SMsgCb *pMsgCb) { int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qWorkerMgmt, const SMsgCb *pMsgCb) {
@ -1404,10 +1491,21 @@ int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qW
QW_RET(TSDB_CODE_QRY_INVALID_INPUT); QW_RET(TSDB_CODE_QRY_INVALID_INPUT);
} }
int32_t code = 0; int32_t qwNum = atomic_add_fetch_32(&gQwMgmt.qwNum, 1);
SQWorkerMgmt *mgmt = taosMemoryCalloc(1, sizeof(SQWorkerMgmt)); if (1 == qwNum) {
memset(gQwMgmt.param, 0, sizeof(gQwMgmt.param));
}
int32_t code = qwOpenRef();
if (code) {
atomic_sub_fetch_32(&gQwMgmt.qwNum, 1);
QW_RET(code);
}
SQWorker *mgmt = taosMemoryCalloc(1, sizeof(SQWorker));
if (NULL == mgmt) { if (NULL == mgmt) {
qError("calloc %d failed", (int32_t)sizeof(SQWorkerMgmt)); qError("calloc %d failed", (int32_t)sizeof(SQWorker));
atomic_sub_fetch_32(&gQwMgmt.qwNum, 1);
QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
@ -1449,16 +1547,25 @@ int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qW
QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
mgmt->hbTimer = taosTmrStart(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, mgmt, mgmt->timer); mgmt->nodeType = nodeType;
mgmt->nodeId = nodeId;
mgmt->msgCb = *pMsgCb;
mgmt->refId = taosAddRef(gQwMgmt.qwRef, mgmt);
if (mgmt->refId < 0) {
qError("taosAddRef qw failed, error:%s", tstrerror(terrno));
QW_ERR_JRET(terrno);
}
SQWHbParam *param = NULL;
qwSetHbParam(mgmt->refId, &param);
mgmt->hbTimer = taosTmrStart(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, (void*)param, mgmt->timer);
if (NULL == mgmt->hbTimer) { if (NULL == mgmt->hbTimer) {
qError("start hb timer failed"); qError("start hb timer failed");
QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
mgmt->nodeType = nodeType;
mgmt->nodeId = nodeId;
mgmt->msgCb = *pMsgCb;
*qWorkerMgmt = mgmt; *qWorkerMgmt = mgmt;
qDebug("qworker initialized for node, type:%d, id:%d, handle:%p", mgmt->nodeType, mgmt->nodeId, mgmt); qDebug("qworker initialized for node, type:%d, id:%d, handle:%p", mgmt->nodeType, mgmt->nodeId, mgmt);
@ -1467,13 +1574,17 @@ int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qW
_return: _return:
if (mgmt->refId >= 0) {
qwRelease(mgmt->refId);
} else {
taosHashCleanup(mgmt->schHash); taosHashCleanup(mgmt->schHash);
taosHashCleanup(mgmt->ctxHash); taosHashCleanup(mgmt->ctxHash);
taosTmrCleanUp(mgmt->timer); taosTmrCleanUp(mgmt->timer);
taosMemoryFreeClear(mgmt); taosMemoryFreeClear(mgmt);
atomic_sub_fetch_32(&gQwMgmt.qwNum, 1);
}
QW_RET(code); QW_RET(code);
} }
@ -1482,22 +1593,14 @@ void qWorkerDestroy(void **qWorkerMgmt) {
return; return;
} }
SQWorkerMgmt *mgmt = *qWorkerMgmt; SQWorker *mgmt = *qWorkerMgmt;
taosTmrStopA(&mgmt->hbTimer); if (taosRemoveRef(gQwMgmt.qwRef, mgmt->refId)) {
taosTmrCleanUp(mgmt->timer); qError("remove qw from ref list failed, refId:%" PRIx64, mgmt->refId);
}
// TODO STOP ALL QUERY
// TODO FREE ALL
taosHashCleanup(mgmt->ctxHash);
taosHashCleanup(mgmt->schHash);
taosMemoryFreeClear(*qWorkerMgmt);
} }
int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp) { int32_t qwGetSchTasksStatus(SQWorker *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp) {
/* /*
SQWSchStatus *sch = NULL; SQWSchStatus *sch = NULL;
int32_t taskNum = 0; int32_t taskNum = 0;
@ -1544,7 +1647,7 @@ int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRs
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwUpdateSchLastAccess(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId) { int32_t qwUpdateSchLastAccess(SQWorker *mgmt, uint64_t sId, uint64_t qId, uint64_t tId) {
SQWSchStatus *sch = NULL; SQWSchStatus *sch = NULL;
/* /*
@ -1557,7 +1660,7 @@ int32_t qwUpdateSchLastAccess(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, ui
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwGetTaskStatus(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, int8_t *taskStatus) { int32_t qwGetTaskStatus(SQWorker *mgmt, uint64_t sId, uint64_t qId, uint64_t tId, int8_t *taskStatus) {
SQWSchStatus * sch = NULL; SQWSchStatus * sch = NULL;
SQWTaskStatus *task = NULL; SQWTaskStatus *task = NULL;
int32_t code = 0; int32_t code = 0;
@ -1584,7 +1687,7 @@ int32_t qwGetTaskStatus(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t
QW_RET(code); QW_RET(code);
} }
int32_t qwCancelTask(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t tId) { int32_t qwCancelTask(SQWorker *mgmt, uint64_t sId, uint64_t qId, uint64_t tId) {
SQWSchStatus * sch = NULL; SQWSchStatus * sch = NULL;
SQWTaskStatus *task = NULL; SQWTaskStatus *task = NULL;
int32_t code = 0; int32_t code = 0;

View File

@ -320,7 +320,7 @@ int32_t qwRegisterQueryBrokenLinkArg(QW_FPARAMS_DEF, SQWConnInfo *pConn) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qwRegisterHbBrokenLinkArg(SQWorkerMgmt *mgmt, uint64_t sId, SQWConnInfo *pConn) { int32_t qwRegisterHbBrokenLinkArg(SQWorker *mgmt, uint64_t sId, SQWConnInfo *pConn) {
SSchedulerHbReq req = {0}; SSchedulerHbReq req = {0};
req.header.vgId = mgmt->nodeId; req.header.vgId = mgmt->nodeId;
req.sId = sId; req.sId = sId;
@ -363,7 +363,7 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
int32_t code = 0; int32_t code = 0;
SSubQueryMsg *msg = pMsg->pCont; SSubQueryMsg *msg = pMsg->pCont;
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { if (NULL == msg || pMsg->contLen <= sizeof(*msg)) {
QW_ELOG("invalid query msg, msg:%p, msgLen:%d", msg, pMsg->contLen); QW_ELOG("invalid query msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
@ -405,7 +405,7 @@ int32_t qWorkerProcessCQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
SQueryContinueReq *msg = (SQueryContinueReq *)pMsg->pCont; SQueryContinueReq *msg = (SQueryContinueReq *)pMsg->pCont;
bool needStop = false; bool needStop = false;
SQWTaskCtx *handles = NULL; SQWTaskCtx *handles = NULL;
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
if (NULL == msg || pMsg->contLen < sizeof(*msg)) { if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
QW_ELOG("invalid cquery msg, msg:%p, msgLen:%d", msg, pMsg->contLen); QW_ELOG("invalid cquery msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
@ -436,7 +436,7 @@ int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
return TSDB_CODE_QRY_INVALID_INPUT; return TSDB_CODE_QRY_INVALID_INPUT;
} }
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
SResReadyReq *msg = pMsg->pCont; SResReadyReq *msg = pMsg->pCont;
if (NULL == msg || pMsg->contLen < sizeof(*msg)) { if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
QW_ELOG("invalid task ready msg, msg:%p, msgLen:%d", msg, pMsg->contLen); QW_ELOG("invalid task ready msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
@ -478,7 +478,7 @@ int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
} }
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
msg->sId = htobe64(msg->sId); msg->sId = htobe64(msg->sId);
uint64_t sId = msg->sId; uint64_t sId = msg->sId;
@ -499,7 +499,7 @@ int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
} }
SResFetchReq *msg = pMsg->pCont; SResFetchReq *msg = pMsg->pCont;
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
if (NULL == msg || pMsg->contLen < sizeof(*msg)) { if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
QW_ELOG("invalid fetch msg, msg:%p, msgLen:%d", msg, pMsg->contLen); QW_ELOG("invalid fetch msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
@ -539,7 +539,7 @@ int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
return TSDB_CODE_QRY_INVALID_INPUT; return TSDB_CODE_QRY_INVALID_INPUT;
} }
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
int32_t code = 0; int32_t code = 0;
STaskCancelReq *msg = pMsg->pCont; STaskCancelReq *msg = pMsg->pCont;
if (NULL == msg || pMsg->contLen < sizeof(*msg)) { if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
@ -579,7 +579,7 @@ int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
int32_t code = 0; int32_t code = 0;
STaskDropReq *msg = pMsg->pCont; STaskDropReq *msg = pMsg->pCont;
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
if (NULL == msg || pMsg->contLen < sizeof(*msg)) { if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
QW_ELOG("invalid task drop msg, msg:%p, msgLen:%d", msg, pMsg->contLen); QW_ELOG("invalid task drop msg, msg:%p, msgLen:%d", msg, pMsg->contLen);
@ -621,7 +621,7 @@ int32_t qWorkerProcessHbMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
int32_t code = 0; int32_t code = 0;
SSchedulerHbReq req = {0}; SSchedulerHbReq req = {0};
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt; SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
if (NULL == pMsg->pCont) { if (NULL == pMsg->pCont) {
QW_ELOG("invalid hb msg, msg:%p, msgLen:%d", pMsg->pCont, pMsg->contLen); QW_ELOG("invalid hb msg, msg:%p, msgLen:%d", pMsg->pCont, pMsg->contLen);

View File

@ -3765,6 +3765,7 @@ int32_t filterInitFromNode(SNode* pNode, SFilterInfo **pInfo, uint32_t options)
FLT_ERR_JRET(fltReviseNodes(info, &pNode, &stat)); FLT_ERR_JRET(fltReviseNodes(info, &pNode, &stat));
info->scalarMode = stat.scalarMode; info->scalarMode = stat.scalarMode;
fltDebug("scalar mode: %d", info->scalarMode);
if (!info->scalarMode) { if (!info->scalarMode) {
FLT_ERR_JRET(fltInitFromNode(pNode, info, options)); FLT_ERR_JRET(fltInitFromNode(pNode, info, options));

View File

@ -75,7 +75,15 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
if (valueNode->node.resType.type != type) { if (valueNode->node.resType.type != type) {
out.columnData->info.type = type; out.columnData->info.type = type;
if (IS_VAR_DATA_TYPE(type)) {
if (IS_VAR_DATA_TYPE(valueNode->node.resType.type)) {
out.columnData->info.bytes = valueNode->node.resType.bytes * TSDB_NCHAR_SIZE;
} else {
out.columnData->info.bytes = 64 * TSDB_NCHAR_SIZE;
}
} else {
out.columnData->info.bytes = tDataTypes[type].bytes; out.columnData->info.bytes = tDataTypes[type].bytes;
}
code = doConvertDataType(valueNode, &out); code = doConvertDataType(valueNode, &out);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
@ -598,7 +606,7 @@ EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) {
res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1); res->datum.p = taosMemoryCalloc(res->node.resType.bytes + VARSTR_HEADER_SIZE + 1, 1);
memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData)); memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
} else { } else {
memcpy(nodesGetValueFromNode(res), output.columnData->pData, tDataTypes[type].bytes); nodesSetValueNodeValue(res, output.columnData->pData);
} }
} }
@ -638,7 +646,7 @@ EDealRes sclRewriteLogic(SNode** pNode, SScalarCtx *ctx) {
res->datum.p = output.columnData->pData; res->datum.p = output.columnData->pData;
output.columnData->pData = NULL; output.columnData->pData = NULL;
} else { } else {
memcpy(nodesGetValueFromNode(res), output.columnData->pData, tDataTypes[type].bytes); nodesSetValueNodeValue(res, output.columnData->pData);
} }
nodesDestroyNode(*pNode); nodesDestroyNode(*pNode);
@ -680,7 +688,7 @@ EDealRes sclRewriteOperator(SNode** pNode, SScalarCtx *ctx) {
res->datum.p = output.columnData->pData; res->datum.p = output.columnData->pData;
output.columnData->pData = NULL; output.columnData->pData = NULL;
} else { } else {
memcpy(nodesGetValueFromNode(res), output.columnData->pData, tDataTypes[type].bytes); nodesSetValueNodeValue(res, output.columnData->pData);
} }
} }

View File

@ -85,7 +85,10 @@ typedef struct SSchedulerMgmt {
uint64_t taskId; // sequential taksId uint64_t taskId; // sequential taksId
uint64_t sId; // schedulerId uint64_t sId; // schedulerId
SSchedulerCfg cfg; SSchedulerCfg cfg;
SRWLatch lock;
bool exit;
int32_t jobRef; int32_t jobRef;
int32_t jobNum;
SSchedulerStat stat; SSchedulerStat stat;
SHashObj *hbConnections; SHashObj *hbConnections;
} SSchedulerMgmt; } SSchedulerMgmt;

View File

@ -21,7 +21,9 @@
#include "tref.h" #include "tref.h"
#include "trpc.h" #include "trpc.h"
SSchedulerMgmt schMgmt = {0}; SSchedulerMgmt schMgmt = {
.jobRef = -1,
};
FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); } FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); }
@ -70,6 +72,7 @@ int32_t schInitTask(SSchJob *pJob, SSchTask *pTask, SSubplan *pPlan, SSchLevel *
int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray *pNodeList, const char *sql, int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray *pNodeList, const char *sql,
int64_t startTs, bool syncSchedule) { int64_t startTs, bool syncSchedule) {
int32_t code = 0; int32_t code = 0;
int64_t refId = -1;
SSchJob *pJob = taosMemoryCalloc(1, sizeof(SSchJob)); SSchJob *pJob = taosMemoryCalloc(1, sizeof(SSchJob));
if (NULL == pJob) { if (NULL == pJob) {
qError("QID:%" PRIx64 " calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob)); qError("QID:%" PRIx64 " calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob));
@ -114,15 +117,17 @@ int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray
tsem_init(&pJob->rspSem, 0, 0); tsem_init(&pJob->rspSem, 0, 0);
int64_t refId = taosAddRef(schMgmt.jobRef, pJob); refId = taosAddRef(schMgmt.jobRef, pJob);
if (refId < 0) { if (refId < 0) {
SCH_JOB_ELOG("taosAddRef job failed, error:%s", tstrerror(terrno)); SCH_JOB_ELOG("taosAddRef job failed, error:%s", tstrerror(terrno));
SCH_ERR_JRET(terrno); SCH_ERR_JRET(terrno);
} }
atomic_add_fetch_32(&schMgmt.jobNum, 1);
if (NULL == schAcquireJob(refId)) { if (NULL == schAcquireJob(refId)) {
SCH_JOB_ELOG("schAcquireJob job failed, refId:%" PRIx64, refId); SCH_JOB_ELOG("schAcquireJob job failed, refId:%" PRIx64, refId);
SCH_RET(TSDB_CODE_SCH_STATUS_ERROR); SCH_ERR_JRET(TSDB_CODE_SCH_STATUS_ERROR);
} }
pJob->refId = refId; pJob->refId = refId;
@ -137,7 +142,11 @@ int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray
_return: _return:
if (refId < 0) {
schFreeJobImpl(pJob); schFreeJobImpl(pJob);
} else {
taosRemoveRef(schMgmt.jobRef, refId);
}
SCH_RET(code); SCH_RET(code);
} }
@ -245,6 +254,7 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1); SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
case TDMT_VND_CREATE_TABLE_RSP: case TDMT_VND_CREATE_TABLE_RSP:
case TDMT_VND_DROP_TABLE_RSP:
case TDMT_VND_SUBMIT_RSP: case TDMT_VND_SUBMIT_RSP:
break; break;
default: default:
@ -369,7 +379,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
} }
for (int32_t n = 0; n < childNum; ++n) { for (int32_t n = 0; n < childNum; ++n) {
SSubplan * child = (SSubplan *)nodesListGetNode(pPlan->pChildren, n); SSubplan *child = (SSubplan *)nodesListGetNode(pPlan->pChildren, n);
SSchTask **childTask = taosHashGet(planToTask, &child, POINTER_BYTES); SSchTask **childTask = taosHashGet(planToTask, &child, POINTER_BYTES);
if (NULL == childTask || NULL == *childTask) { if (NULL == childTask || NULL == *childTask) {
SCH_TASK_ELOG("subplan children relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); SCH_TASK_ELOG("subplan children relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n);
@ -401,7 +411,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
} }
for (int32_t n = 0; n < parentNum; ++n) { for (int32_t n = 0; n < parentNum; ++n) {
SSubplan * parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n); SSubplan *parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n);
SSchTask **parentTask = taosHashGet(planToTask, &parent, POINTER_BYTES); SSchTask **parentTask = taosHashGet(planToTask, &parent, POINTER_BYTES);
if (NULL == parentTask || NULL == *parentTask) { if (NULL == parentTask || NULL == *parentTask) {
SCH_TASK_ELOG("subplan parent relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n); SCH_TASK_ELOG("subplan parent relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n);
@ -491,7 +501,7 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
SSchLevel level = {0}; SSchLevel level = {0};
SNodeListNode *plans = NULL; SNodeListNode *plans = NULL;
int32_t taskNum = 0; int32_t taskNum = 0;
SSchLevel * pLevel = NULL; SSchLevel *pLevel = NULL;
level.status = JOB_TASK_STATUS_NOT_START; level.status = JOB_TASK_STATUS_NOT_START;
@ -1094,6 +1104,30 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask)); SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask));
break; break;
} }
case TDMT_VND_DROP_TABLE_RSP: {
SVDropTbBatchRsp batchRsp = {0};
if (msg) {
SCoder coder = {0};
tCoderInit(&coder, TD_LITTLE_ENDIAN, msg, msgSize, TD_DECODER);
code = tDecodeSVDropTbBatchRsp(&coder, &batchRsp);
if (TSDB_CODE_SUCCESS == code && batchRsp.pArray) {
int32_t num = taosArrayGetSize(batchRsp.pArray);
for (int32_t i = 0; i < num; ++i) {
SVDropTbRsp *rsp = taosArrayGet(batchRsp.pArray, i);
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
tCoderClear(&coder);
SCH_ERR_JRET(rsp->code);
}
}
}
tCoderClear(&coder);
SCH_ERR_JRET(code);
}
SCH_ERR_JRET(rspCode);
SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask));
break;
}
case TDMT_VND_SUBMIT_RSP: { case TDMT_VND_SUBMIT_RSP: {
if (msg) { if (msg) {
SSubmitRsp *rsp = (SSubmitRsp *)msg; SSubmitRsp *rsp = (SSubmitRsp *)msg;
@ -1267,7 +1301,7 @@ int32_t schUpdateTaskExecNodeHandle(SSchTask *pTask, void *handle, int32_t rspCo
int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t msgType, int32_t rspCode) { int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t msgType, int32_t rspCode) {
int32_t code = 0; int32_t code = 0;
SSchTaskCallbackParam *pParam = (SSchTaskCallbackParam *)param; SSchTaskCallbackParam *pParam = (SSchTaskCallbackParam *)param;
SSchTask * pTask = NULL; SSchTask *pTask = NULL;
SSchJob *pJob = schAcquireJob(pParam->refId); SSchJob *pJob = schAcquireJob(pParam->refId);
if (NULL == pJob) { if (NULL == pJob) {
@ -1316,6 +1350,10 @@ int32_t schHandleCreateTableCallback(void *param, const SDataBuf *pMsg, int32_t
return schHandleCallback(param, pMsg, TDMT_VND_CREATE_TABLE_RSP, code); return schHandleCallback(param, pMsg, TDMT_VND_CREATE_TABLE_RSP, code);
} }
int32_t schHandleDropTableCallback(void *param, const SDataBuf *pMsg, int32_t code) {
return schHandleCallback(param, pMsg, TDMT_VND_DROP_TABLE_RSP, code);
}
int32_t schHandleQueryCallback(void *param, const SDataBuf *pMsg, int32_t code) { int32_t schHandleQueryCallback(void *param, const SDataBuf *pMsg, int32_t code) {
return schHandleCallback(param, pMsg, TDMT_VND_QUERY_RSP, code); return schHandleCallback(param, pMsg, TDMT_VND_QUERY_RSP, code);
} }
@ -1412,6 +1450,9 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) {
case TDMT_VND_CREATE_TABLE: case TDMT_VND_CREATE_TABLE:
*fp = schHandleCreateTableCallback; *fp = schHandleCreateTableCallback;
break; break;
case TDMT_VND_DROP_TABLE:
*fp = schHandleDropTableCallback;
break;
case TDMT_VND_SUBMIT: case TDMT_VND_SUBMIT:
*fp = schHandleSubmitCallback; *fp = schHandleSubmitCallback;
break; break;
@ -1617,8 +1658,8 @@ _return:
int32_t schMakeHbRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) { int32_t schMakeHbRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) {
int32_t code = 0; int32_t code = 0;
SSchHbCallbackParam *param = NULL; SSchHbCallbackParam *param = NULL;
SMsgSendInfo * pMsgSendInfo = NULL; SMsgSendInfo *pMsgSendInfo = NULL;
SQueryNodeAddr * addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
SQueryNodeEpId epId = {0}; SQueryNodeEpId epId = {0};
epId.nodeId = addr->nodeId; epId.nodeId = addr->nodeId;
@ -1759,10 +1800,10 @@ int32_t schCloneHbRpcCtx(SRpcCtx *pSrc, SRpcCtx *pDst) {
} }
SRpcCtxVal dst = {0}; SRpcCtxVal dst = {0};
void * pIter = taosHashIterate(pSrc->args, NULL); void *pIter = taosHashIterate(pSrc->args, NULL);
while (pIter) { while (pIter) {
SRpcCtxVal *pVal = (SRpcCtxVal *)pIter; SRpcCtxVal *pVal = (SRpcCtxVal *)pIter;
int32_t * msgType = taosHashGetKey(pIter, NULL); int32_t *msgType = taosHashGetKey(pIter, NULL);
dst = *pVal; dst = *pVal;
dst.val = NULL; dst.val = NULL;
@ -1916,7 +1957,7 @@ _return:
int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType) { int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType) {
uint32_t msgSize = 0; uint32_t msgSize = 0;
void * msg = NULL; void *msg = NULL;
int32_t code = 0; int32_t code = 0;
bool isCandidateAddr = false; bool isCandidateAddr = false;
bool persistHandle = false; bool persistHandle = false;
@ -1931,6 +1972,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
switch (msgType) { switch (msgType) {
case TDMT_VND_CREATE_TABLE: case TDMT_VND_CREATE_TABLE:
case TDMT_VND_DROP_TABLE:
case TDMT_VND_SUBMIT: { case TDMT_VND_SUBMIT: {
msgSize = pTask->msgLen; msgSize = pTask->msgLen;
msg = taosMemoryCalloc(1, msgSize); msg = taosMemoryCalloc(1, msgSize);
@ -2239,6 +2281,19 @@ int32_t schCancelJob(SSchJob *pJob) {
// TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST // TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST
} }
void schCloseJobRef(void) {
if (!atomic_load_8((int8_t*)&schMgmt.exit)) {
return;
}
SCH_LOCK(SCH_WRITE, &schMgmt.lock);
if (atomic_load_32(&schMgmt.jobNum) <= 0 && schMgmt.jobRef >= 0) {
taosCloseRef(schMgmt.jobRef);
schMgmt.jobRef = -1;
}
SCH_UNLOCK(SCH_WRITE, &schMgmt.lock);
}
void schFreeJobImpl(void *job) { void schFreeJobImpl(void *job) {
if (NULL == job) { if (NULL == job) {
return; return;
@ -2284,6 +2339,10 @@ void schFreeJobImpl(void *job) {
taosMemoryFreeClear(pJob); taosMemoryFreeClear(pJob);
qDebug("QID:0x%" PRIx64 " job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob); qDebug("QID:0x%" PRIx64 " job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob);
atomic_sub_fetch_32(&schMgmt.jobNum, 1);
schCloseJobRef();
} }
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pDag, int64_t *job, const char *sql, static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pDag, int64_t *job, const char *sql,
@ -2368,7 +2427,7 @@ _return:
} }
int32_t schedulerInit(SSchedulerCfg *cfg) { int32_t schedulerInit(SSchedulerCfg *cfg) {
if (schMgmt.jobRef) { if (schMgmt.jobRef >= 0) {
qError("scheduler already initialized"); qError("scheduler already initialized");
return TSDB_CODE_QRY_INVALID_INPUT; return TSDB_CODE_QRY_INVALID_INPUT;
} }
@ -2673,7 +2732,7 @@ int32_t schedulerGetTasksStatus(int64_t job, SArray *pSub) {
SSchLevel *pLevel = taosArrayGet(pJob->levels, i); SSchLevel *pLevel = taosArrayGet(pJob->levels, i);
for (int32_t m = 0; m < pLevel->taskNum; ++m) { for (int32_t m = 0; m < pLevel->taskNum; ++m) {
SSchTask * pTask = taosArrayGet(pLevel->subTasks, m); SSchTask *pTask = taosArrayGet(pLevel->subTasks, m);
SQuerySubDesc subDesc = {.tid = pTask->taskId, .status = pTask->status}; SQuerySubDesc subDesc = {.tid = pTask->taskId, .status = pTask->status};
taosArrayPush(pSub, &subDesc); taosArrayPush(pSub, &subDesc);
@ -2732,7 +2791,9 @@ void schedulerFreeTaskList(SArray *taskList) {
} }
void schedulerDestroy(void) { void schedulerDestroy(void) {
if (schMgmt.jobRef) { atomic_store_8((int8_t*)&schMgmt.exit, 1);
if (schMgmt.jobRef >= 0) {
SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0); SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0);
int64_t refId = 0; int64_t refId = 0;
@ -2745,9 +2806,6 @@ void schedulerDestroy(void) {
pJob = taosIterateRef(schMgmt.jobRef, refId); pJob = taosIterateRef(schMgmt.jobRef, refId);
} }
taosCloseRef(schMgmt.jobRef);
schMgmt.jobRef = 0;
} }
if (schMgmt.hbConnections) { if (schMgmt.hbConnections) {

View File

@ -22,6 +22,65 @@
extern "C" { extern "C" {
#endif #endif
typedef int (*tdb_cmpr_fn_t)(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
// exposed types
typedef struct STEnv TENV;
typedef struct STDB TDB;
typedef struct STDBC TDBC;
typedef struct STxn TXN;
// TENV
int tdbEnvOpen(const char *rootDir, int szPage, int pages, TENV **ppEnv);
int tdbEnvClose(TENV *pEnv);
int tdbBegin(TENV *pEnv, TXN *pTxn);
int tdbCommit(TENV *pEnv, TXN *pTxn);
// TDB
int tdbDbOpen(const char *fname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprFn, TENV *pEnv, TDB **ppDb);
int tdbDbClose(TDB *pDb);
int tdbDbDrop(TDB *pDb);
int tdbDbPut(TDB *pDb, const void *pKey, int keyLen, const void *pVal, int valLen, TXN *pTxn);
int tdbDbGet(TDB *pDb, const void *pKey, int kLen, void **ppVal, int *vLen);
int tdbDbPGet(TDB *pDb, const void *pKey, int kLen, void **ppKey, int *pkLen, void **ppVal, int *vLen);
// TDBC
int tdbDbcOpen(TDB *pDb, TDBC **ppDbc, TXN *pTxn);
int tdbDbcClose(TDBC *pDbc);
int tdbDbcMoveTo(TDBC *pDbc, const void *pKey, int kLen, int *c);
int tdbDbcMoveToFirst(TDBC *pDbc);
int tdbDbcMoveToLast(TDBC *pDbc);
int tdbDbcMoveToNext(TDBC *pDbc);
int tdbDbcMoveToPrev(TDBC *pDbc);
int tdbDbcGet(TDBC *pDbc, const void **ppKey, int *pkLen, const void **ppVal, int *pvLen);
int tdbDbcPut(TDBC *pDbc, const void *pKey, int keyLen, const void *pVal, int valLen);
int tdbDbcUpdate(TDBC *pDbc, const void *pKey, int kLen, const void *pVal, int vLen);
int tdbDbcDrop(TDBC *pDbc);
int tdbDbcNext(TDBC *pDbc, void **ppKey, int *kLen, void **ppVal, int *vLen);
// TXN
#define TDB_TXN_WRITE 0x1
#define TDB_TXN_READ_UNCOMMITTED 0x2
int tdbTxnOpen(TXN *pTxn, int64_t txnid, void *(*xMalloc)(void *, size_t), void (*xFree)(void *, void *), void *xArg,
int flags);
int tdbTxnClose(TXN *pTxn);
// other
void tdbFree(void *);
struct STxn {
int flags;
int64_t txnId;
void *(*xMalloc)(void *, size_t);
void (*xFree)(void *, void *);
void *xArg;
};
// error code
enum { TDB_CODE_SUCCESS = 0, TDB_CODE_MAX };
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,7 +23,7 @@ struct SBTree {
int keyLen; int keyLen;
int valLen; int valLen;
SPager *pPager; SPager *pPager;
FKeyComparator kcmpr; tdb_cmpr_fn_t kcmpr;
int pageSize; int pageSize;
int maxLocal; int maxLocal;
int minLocal; int minLocal;
@ -58,16 +58,6 @@ typedef struct {
SBTree *pBt; SBTree *pBt;
} SBtreeInitPageArg; } SBtreeInitPageArg;
typedef struct {
int kLen;
const u8 *pKey;
int vLen;
const u8 *pVal;
SPgno pgno;
u8 *pBuf;
} SCellDecoder;
static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst);
static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2); static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2);
static int tdbBtreeOpenImpl(SBTree *pBt); static int tdbBtreeOpenImpl(SBTree *pBt);
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init); static int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
@ -76,11 +66,10 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder); static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder);
static int tdbBtreeBalance(SBTC *pBtc); static int tdbBtreeBalance(SBTC *pBtc);
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell); static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell);
static int tdbBtcMoveToNext(SBTC *pBtc);
static int tdbBtcMoveDownward(SBTC *pBtc); static int tdbBtcMoveDownward(SBTC *pBtc);
static int tdbBtcMoveUpward(SBTC *pBtc); static int tdbBtcMoveUpward(SBTC *pBtc);
int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, FKeyComparator kcmpr, SBTree **ppBt) { int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, tdb_cmpr_fn_t kcmpr, SBTree **ppBt) {
SBTree *pBt; SBTree *pBt;
int ret; int ret;
@ -165,7 +154,7 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in
// make sure enough space to hold the cell // make sure enough space to hold the cell
szBuf = kLen + vLen + 14; szBuf = kLen + vLen + 14;
pBuf = TDB_REALLOC(pBt->pBuf, pBt->pageSize > szBuf ? szBuf : pBt->pageSize); pBuf = tdbRealloc(pBt->pBuf, pBt->pageSize > szBuf ? szBuf : pBt->pageSize);
if (pBuf == NULL) { if (pBuf == NULL) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); ASSERT(0);
@ -243,7 +232,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
tdbBtreeDecodeCell(btc.pPage, pCell, &cd); tdbBtreeDecodeCell(btc.pPage, pCell, &cd);
if (ppKey) { if (ppKey) {
pTKey = TDB_REALLOC(*ppKey, cd.kLen); pTKey = tdbRealloc(*ppKey, cd.kLen);
if (pTKey == NULL) { if (pTKey == NULL) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); ASSERT(0);
@ -255,7 +244,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
} }
if (ppVal) { if (ppVal) {
pTVal = TDB_REALLOC(*ppVal, cd.vLen); pTVal = tdbRealloc(*ppVal, cd.vLen);
if (pTVal == NULL) { if (pTVal == NULL) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); ASSERT(0);
@ -1018,6 +1007,7 @@ int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn) {
pBtc->iPage = -1; pBtc->iPage = -1;
pBtc->pPage = NULL; pBtc->pPage = NULL;
pBtc->idx = -1; pBtc->idx = -1;
memset(&pBtc->coder, 0, sizeof(SCellDecoder));
if (pTxn == NULL) { if (pTxn == NULL) {
pBtc->pTxn = &pBtc->txn; pBtc->pTxn = &pBtc->txn;
@ -1060,6 +1050,8 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
return 0; return 0;
} }
} else { } else {
ASSERT(0);
#if 0
// move from a position // move from a position
int iPage = 0; int iPage = 0;
@ -1077,6 +1069,7 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
tdbBtcMoveUpward(pBtc); tdbBtcMoveUpward(pBtc);
} }
#endif
} }
// move downward // move downward
@ -1125,6 +1118,8 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
return 0; return 0;
} }
} else { } else {
ASSERT(0);
#if 0
int iPage = 0; int iPage = 0;
// downward search // downward search
@ -1147,6 +1142,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
tdbBtcMoveUpward(pBtc); tdbBtcMoveUpward(pBtc);
} }
#endif
} }
// move downward // move downward
@ -1185,7 +1181,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd); tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd);
pKey = TDB_REALLOC(*ppKey, cd.kLen); pKey = tdbRealloc(*ppKey, cd.kLen);
if (pKey == NULL) { if (pKey == NULL) {
return -1; return -1;
} }
@ -1196,9 +1192,9 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
if (ppVal) { if (ppVal) {
// TODO: vLen may be zero // TODO: vLen may be zero
pVal = TDB_REALLOC(*ppVal, cd.vLen); pVal = tdbRealloc(*ppVal, cd.vLen);
if (pVal == NULL) { if (pVal == NULL) {
TDB_FREE(pKey); tdbFree(pKey);
return -1; return -1;
} }
@ -1216,7 +1212,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
return 0; return 0;
} }
static int tdbBtcMoveToNext(SBTC *pBtc) { int tdbBtcMoveToNext(SBTC *pBtc) {
int nCells; int nCells;
int ret; int ret;
SCell *pCell; SCell *pCell;
@ -1262,6 +1258,43 @@ static int tdbBtcMoveToNext(SBTC *pBtc) {
return 0; return 0;
} }
int tdbBtcMoveToPrev(SBTC *pBtc) {
if (pBtc->idx < 0) return -1;
pBtc->idx--;
if (pBtc->idx >= 0) {
return 0;
}
// move upward
for (;;) {
if (pBtc->iPage == 0) {
pBtc->idx = -1;
return 0;
}
tdbBtcMoveUpward(pBtc);
pBtc->idx--;
if (pBtc->idx >= 0) {
break;
}
}
// move downward
for (;;) {
if (TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) break;
tdbBtcMoveDownward(pBtc);
if (TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
pBtc->idx = TDB_PAGE_TOTAL_CELLS(pBtc->pPage) - 1;
} else {
pBtc->idx = TDB_PAGE_TOTAL_CELLS(pBtc->pPage);
}
}
return 0;
}
static int tdbBtcMoveDownward(SBTC *pBtc) { static int tdbBtcMoveDownward(SBTC *pBtc) {
int ret; int ret;
SPgno pgno; SPgno pgno;
@ -1307,17 +1340,38 @@ static int tdbBtcMoveUpward(SBTC *pBtc) {
return 0; return 0;
} }
static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) { int tdbBtcGet(SBTC *pBtc, const void **ppKey, int *kLen, const void **ppVal, int *vLen) {
SCell *pCell;
if (pBtc->idx < 0 || pBtc->idx >= TDB_PAGE_TOTAL_CELLS(pBtc->pPage)) {
return -1;
}
pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx);
tdbBtreeDecodeCell(pBtc->pPage, pCell, &pBtc->coder);
if (ppKey) {
*ppKey = (void *)pBtc->coder.pKey;
*kLen = pBtc->coder.kLen;
}
if (ppVal) {
*ppVal = (void *)pBtc->coder.pVal;
*kLen = pBtc->coder.vLen;
}
return 0;
}
int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
int ret; int ret;
int nCells; int nCells;
int c; int c;
SBTree *pBt;
SCell *pCell; SCell *pCell;
SPager *pPager; SBTree *pBt = pBtc->pBt;
SCellDecoder cd = {0}; SPager *pPager = pBt->pPager;
const void *pTKey;
pBt = pBtc->pBt; int tkLen;
pPager = pBt->pPager;
if (pBtc->iPage < 0) { if (pBtc->iPage < 0) {
// move from a clear cursor // move from a clear cursor
@ -1334,6 +1388,8 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
// for empty tree, just return with an invalid position // for empty tree, just return with an invalid position
if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0) return 0; if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0) return 0;
} else { } else {
ASSERT(0);
#if 0
SPage *pPage; SPage *pPage;
int idx; int idx;
int iPage = 0; int iPage = 0;
@ -1368,11 +1424,12 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
if (pBtc->iPage == iPage) break; if (pBtc->iPage == iPage) break;
tdbBtcMoveUpward(pBtc); tdbBtcMoveUpward(pBtc);
} }
#endif
} }
// search downward to the leaf // search downward to the leaf
for (;;) { for (;;) {
int lidx, ridx, midx; int lidx, ridx;
SPage *pPage; SPage *pPage;
pPage = pBtc->pPage; pPage = pBtc->pPage;
@ -1381,13 +1438,11 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
ridx = nCells - 1; ridx = nCells - 1;
ASSERT(nCells > 0); ASSERT(nCells > 0);
ASSERT(pBtc->idx == -1);
// compare first cell // compare first cell
midx = lidx; pBtc->idx = lidx;
pCell = tdbPageGetCell(pPage, midx); tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
tdbBtreeDecodeCell(pPage, pCell, &cd); c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
if (c <= 0) { if (c <= 0) {
ridx = lidx - 1; ridx = lidx - 1;
} else { } else {
@ -1396,10 +1451,9 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
// compare last cell // compare last cell
if (lidx <= ridx) { if (lidx <= ridx) {
midx = ridx; pBtc->idx = ridx;
pCell = tdbPageGetCell(pPage, midx); tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
tdbBtreeDecodeCell(pPage, pCell, &cd); c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
if (c >= 0) { if (c >= 0) {
lidx = ridx + 1; lidx = ridx + 1;
} else { } else {
@ -1411,24 +1465,15 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
for (;;) { for (;;) {
if (lidx > ridx) break; if (lidx > ridx) break;
midx = (lidx + ridx) >> 1; pBtc->idx = (lidx + ridx) >> 1;
tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
pCell = tdbPageGetCell(pPage, midx); c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
ret = tdbBtreeDecodeCell(pPage, pCell, &cd);
if (ret < 0) {
// TODO: handle error
ASSERT(0);
return -1;
}
// Compare the key values
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
if (c < 0) { if (c < 0) {
// pKey < cd.pKey // pKey < cd.pKey
ridx = midx - 1; ridx = pBtc->idx - 1;
} else if (c > 0) { } else if (c > 0) {
// pKey > cd.pKey // pKey > cd.pKey
lidx = midx + 1; lidx = pBtc->idx + 1;
} else { } else {
// pKey == cd.pKey // pKey == cd.pKey
break; break;
@ -1437,14 +1482,11 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
// keep search downward or break // keep search downward or break
if (TDB_BTREE_PAGE_IS_LEAF(pPage)) { if (TDB_BTREE_PAGE_IS_LEAF(pPage)) {
pBtc->idx = midx;
*pCRst = c; *pCRst = c;
break; break;
} else { } else {
if (c <= 0) { if (c > 0) {
pBtc->idx = midx; pBtc->idx += 1;
} else {
pBtc->idx = midx + 1;
} }
tdbBtcMoveDownward(pBtc); tdbBtcMoveDownward(pBtc);
} }

View File

@ -24,7 +24,7 @@ struct STDBC {
SBTC btc; SBTC btc;
}; };
int tdbDbOpen(const char *fname, int keyLen, int valLen, FKeyComparator keyCmprFn, TENV *pEnv, TDB **ppDb) { int tdbDbOpen(const char *fname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprFn, TENV *pEnv, TDB **ppDb) {
TDB *pDb; TDB *pDb;
SPager *pPager; SPager *pPager;
int ret; int ret;
@ -75,7 +75,7 @@ int tdbDbDrop(TDB *pDb) {
return 0; return 0;
} }
int tdbDbInsert(TDB *pDb, const void *pKey, int keyLen, const void *pVal, int valLen, TXN *pTxn) { int tdbDbPut(TDB *pDb, const void *pKey, int keyLen, const void *pVal, int valLen, TXN *pTxn) {
return tdbBtreeInsert(pDb->pBt, pKey, keyLen, pVal, valLen, pTxn); return tdbBtreeInsert(pDb->pBt, pKey, keyLen, pVal, valLen, pTxn);
} }
@ -87,7 +87,7 @@ int tdbDbPGet(TDB *pDb, const void *pKey, int kLen, void **ppKey, int *pkLen, vo
return tdbBtreePGet(pDb->pBt, pKey, kLen, ppKey, pkLen, ppVal, vLen); return tdbBtreePGet(pDb->pBt, pKey, kLen, ppKey, pkLen, ppVal, vLen);
} }
int tdbDbcOpen(TDB *pDb, TDBC **ppDbc) { int tdbDbcOpen(TDB *pDb, TDBC **ppDbc, TXN *pTxn) {
int ret; int ret;
TDBC *pDbc = NULL; TDBC *pDbc = NULL;
@ -97,34 +97,53 @@ int tdbDbcOpen(TDB *pDb, TDBC **ppDbc) {
return -1; return -1;
} }
tdbBtcOpen(&pDbc->btc, pDb->pBt, NULL); tdbBtcOpen(&pDbc->btc, pDb->pBt, pTxn);
// TODO: move to first now, we can move to any key-value
// and in any direction, design new APIs.
ret = tdbBtcMoveToFirst(&pDbc->btc);
if (ret < 0) {
ASSERT(0);
return -1;
}
*ppDbc = pDbc; *ppDbc = pDbc;
return 0; return 0;
} }
int tdbDbNext(TDBC *pDbc, void **ppKey, int *kLen, void **ppVal, int *vLen) { int tdbDbcMoveTo(TDBC *pDbc, const void *pKey, int kLen, int *c) { return tdbBtcMoveTo(&pDbc->btc, pKey, kLen, c); }
int tdbDbcMoveToFirst(TDBC *pDbc) { return tdbBtcMoveToFirst(&pDbc->btc); }
int tdbDbcMoveToLast(TDBC *pDbc) { return tdbBtcMoveToLast(&pDbc->btc); }
int tdbDbcMoveToNext(TDBC *pDbc) { return tdbBtcMoveToNext(&pDbc->btc); }
int tdbDbcMoveToPrev(TDBC *pDbc) { return tdbBtcMoveToPrev(&pDbc->btc); }
int tdbDbcGet(TDBC *pDbc, const void **ppKey, int *pkLen, const void **ppVal, int *pvLen) {
return tdbBtcGet(&pDbc->btc, ppKey, pkLen, ppVal, pvLen);
}
int tdbDbcPut(TDBC *pDbc, const void *pKey, int keyLen, const void *pVal, int valLen) {
// TODO
ASSERT(0);
return 0;
}
int tdbDbcUpdate(TDBC *pDbc, const void *pKey, int kLen, const void *pVal, int vLen) {
// TODO
ASSERT(0);
return 0;
}
int tdbDbcDrop(TDBC *pDbc) {
// TODO
ASSERT(0);
return 0;
}
int tdbDbcNext(TDBC *pDbc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
return tdbBtreeNext(&pDbc->btc, ppKey, kLen, ppVal, vLen); return tdbBtreeNext(&pDbc->btc, ppKey, kLen, ppVal, vLen);
} }
int tdbDbcClose(TDBC *pDbc) { int tdbDbcClose(TDBC *pDbc) {
if (pDbc) { if (pDbc) {
tdbBtcClose(&pDbc->btc);
tdbOsFree(pDbc); tdbOsFree(pDbc);
} }
return 0; return 0;
} }
int tdbDbcInsert(TDBC *pDbc, const void *pKey, int keyLen, const void *pVal, int valLen) {
// TODO
ASSERT(0);
return 0;
}

View File

@ -15,7 +15,7 @@
#include "tdbInt.h" #include "tdbInt.h"
int tdbEnvOpen(const char *rootDir, int pageSize, int cacheSize, TENV **ppEnv) { int tdbEnvOpen(const char *rootDir, int szPage, int pages, TENV **ppEnv) {
TENV *pEnv; TENV *pEnv;
int dsize; int dsize;
int zsize; int zsize;
@ -49,14 +49,14 @@ int tdbEnvOpen(const char *rootDir, int pageSize, int cacheSize, TENV **ppEnv) {
pEnv->jfd = -1; pEnv->jfd = -1;
ret = tdbPCacheOpen(pageSize, cacheSize, &(pEnv->pCache)); ret = tdbPCacheOpen(szPage, pages, &(pEnv->pCache));
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
pEnv->nPgrHash = 8; pEnv->nPgrHash = 8;
tsize = sizeof(SPager *) * pEnv->nPgrHash; tsize = sizeof(SPager *) * pEnv->nPgrHash;
pEnv->pgrHash = TDB_REALLOC(pEnv->pgrHash, tsize); pEnv->pgrHash = tdbRealloc(pEnv->pgrHash, tsize);
if (pEnv->pgrHash == NULL) { if (pEnv->pgrHash == NULL) {
return -1; return -1;
} }
@ -103,11 +103,6 @@ int tdbCommit(TENV *pEnv, TXN *pTxn) {
return 0; return 0;
} }
int tdbRollback(TENV *pEnv, TXN *pTxn) {
ASSERT(0);
return 0;
}
SPager *tdbEnvGetPager(TENV *pEnv, const char *fname) { SPager *tdbEnvGetPager(TENV *pEnv, const char *fname) {
u32 hash; u32 hash;
SPager **ppPager; SPager **ppPager;

View File

@ -13,7 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "tdbInt.h" #include "tdbOs.h"
#ifndef TDB_FOR_TDENGINE #ifndef TDB_FOR_TDENGINE

Some files were not shown because too many files have changed in this diff Show More