Merge branch '3.0' into feature/TD-14481-3.0
This commit is contained in:
commit
da4f86f368
|
@ -14,7 +14,9 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "taos.h"
|
||||
|
@ -24,7 +26,7 @@ static void msg_process(TAOS_RES* msg) {
|
|||
char buf[1024];
|
||||
memset(buf, 0, 1024);
|
||||
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) {
|
||||
TAOS_ROW row = taos_fetch_row(msg);
|
||||
if (row == NULL) break;
|
||||
|
@ -140,8 +142,8 @@ int32_t create_topic() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets) {
|
||||
printf("commit %d\n", resp);
|
||||
void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets, void* param) {
|
||||
printf("commit %d tmq %p offsets %p param %p\n", resp, tmq, offsets, param);
|
||||
}
|
||||
|
||||
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.pass", "taosdata");
|
||||
/*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);
|
||||
assert(tmq);
|
||||
return tmq;
|
||||
|
@ -215,12 +217,24 @@ void sync_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
|
|||
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) {
|
||||
TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 1000);
|
||||
if (tmqmessage) {
|
||||
msg_process(tmqmessage);
|
||||
taos_free_result(tmqmessage);
|
||||
|
||||
tmq_commit(tmq, NULL, 1);
|
||||
/*if ((++msg_count % MIN_COMMIT_COUNT) == 0) tmq_commit(tmq, NULL, 0);*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_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 int32_t tmq_list_append(tmq_list_t *, const char *);
|
||||
|
@ -253,12 +253,12 @@ typedef enum tmq_conf_res_t tmq_conf_res_t;
|
|||
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 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---------------------- */
|
||||
|
||||
DLL_EXPORT char *tmq_get_topic_name(TAOS_RES *res);
|
||||
DLL_EXPORT int32_t tmq_get_vgroup_id(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);
|
||||
// TODO
|
||||
#if 0
|
||||
DLL_EXPORT char *tmq_get_table_name(TAOS_RES *res);
|
||||
|
|
|
@ -1524,6 +1524,7 @@ typedef struct {
|
|||
int32_t tEncodeSRSmaParam(SCoder* pCoder, const SRSmaParam* pRSmaParam);
|
||||
int32_t tDecodeSRSmaParam(SCoder* pCoder, SRSmaParam* pRSmaParam);
|
||||
|
||||
// TDMT_VND_CREATE_STB ==============
|
||||
typedef struct SVCreateStbReq {
|
||||
const char* name;
|
||||
tb_uid_t suid;
|
||||
|
@ -1536,17 +1537,14 @@ typedef struct SVCreateStbReq {
|
|||
int tEncodeSVCreateStbReq(SCoder* pCoder, const SVCreateStbReq* pReq);
|
||||
int tDecodeSVCreateStbReq(SCoder* pCoder, SVCreateStbReq* pReq);
|
||||
|
||||
// TDMT_VND_DROP_STB ==============
|
||||
typedef struct SVDropStbReq {
|
||||
// data
|
||||
#ifdef WINDOWS
|
||||
size_t avoidCompilationErrors;
|
||||
#endif
|
||||
|
||||
const char* name;
|
||||
tb_uid_t suid;
|
||||
} SVDropStbReq;
|
||||
|
||||
typedef struct SVCreateStbRsp {
|
||||
int code;
|
||||
} SVCreateStbRsp;
|
||||
int32_t tEncodeSVDropStbReq(SCoder* pCoder, const SVDropStbReq* pReq);
|
||||
int32_t tDecodeSVDropStbReq(SCoder* pCoder, SVDropStbReq* pReq);
|
||||
|
||||
typedef struct SVCreateTbReq {
|
||||
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 tDeserializeSVCreateTbBatchRsp(void* buf, int32_t bufLen, SVCreateTbBatchRsp* pRsp);
|
||||
|
||||
// TDMT_VND_DROP_TABLE =================
|
||||
typedef struct {
|
||||
int64_t ver;
|
||||
char* name;
|
||||
uint8_t type;
|
||||
tb_uid_t suid;
|
||||
const char* name;
|
||||
int8_t igNotExists;
|
||||
} SVDropTbReq;
|
||||
|
||||
typedef struct {
|
||||
int tmp; // TODO: to avoid compile error
|
||||
int32_t code;
|
||||
} SVDropTbRsp;
|
||||
|
||||
int32_t tSerializeSVDropTbReq(void** buf, SVDropTbReq* pReq);
|
||||
void* tDeserializeSVDropTbReq(void* buf, SVDropTbReq* pReq);
|
||||
typedef struct {
|
||||
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 {
|
||||
SMsgHead head;
|
||||
|
|
|
@ -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_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_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_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_QUERY, "vnode-mq-query", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_MQ_CONNECT, "vnode-mq-connect", NULL, NULL)
|
||||
|
|
|
@ -22,19 +22,20 @@ extern "C" {
|
|||
|
||||
#include "tdef.h"
|
||||
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type))
|
||||
|
||||
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
|
||||
|
||||
#define FOREACH(node, list) \
|
||||
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
|
||||
#define FOREACH(node, list) \
|
||||
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 INSERT_LIST(target, src) nodesListInsertList((target), cell, src)
|
||||
|
||||
#define WHERE_EACH(node, list) \
|
||||
#define WHERE_EACH(node, list) \
|
||||
SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
|
||||
while (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false))
|
||||
|
||||
|
@ -43,16 +44,26 @@ extern "C" {
|
|||
// only be use in WHERE_EACH
|
||||
#define ERASE_NODE(list) cell = nodesListErase((list), cell)
|
||||
|
||||
#define FORBOTH(node1, list1, node2, list2) \
|
||||
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : 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)
|
||||
#define FORBOTH(node1, list1, node2, list2) \
|
||||
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : 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)
|
||||
|
||||
#define REPLACE_LIST1_NODE(newNode) cell1->pNode = (SNode*)(newNode)
|
||||
#define REPLACE_LIST2_NODE(newNode) cell2->pNode = (SNode*)(newNode)
|
||||
|
||||
#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)
|
||||
#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)
|
||||
|
||||
#define DESTORY_LIST(list) \
|
||||
do { \
|
||||
nodesDestroyList(list); \
|
||||
list = NULL; \
|
||||
} while (0)
|
||||
|
||||
typedef enum ENodeType {
|
||||
// Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN,
|
||||
|
@ -202,7 +213,7 @@ typedef enum ENodeType {
|
|||
|
||||
/**
|
||||
* The first field of a node of any type is guaranteed to be the ENodeType.
|
||||
* Hence the type of any node can be gotten by casting it to SNode.
|
||||
* Hence the type of any node can be gotten by casting it to SNode.
|
||||
*/
|
||||
typedef struct SNode {
|
||||
ENodeType type;
|
||||
|
@ -211,41 +222,36 @@ typedef struct SNode {
|
|||
typedef struct SListCell {
|
||||
struct SListCell* pPrev;
|
||||
struct SListCell* pNext;
|
||||
SNode* pNode;
|
||||
SNode* pNode;
|
||||
} SListCell;
|
||||
|
||||
typedef struct SNodeList {
|
||||
int32_t length;
|
||||
int32_t length;
|
||||
SListCell* pHead;
|
||||
SListCell* pTail;
|
||||
} SNodeList;
|
||||
|
||||
#define SNodeptr void*
|
||||
#define SNodeptr void*
|
||||
|
||||
SNodeptr nodesMakeNode(ENodeType type);
|
||||
void nodesDestroyNode(SNodeptr pNode);
|
||||
void nodesDestroyNode(SNodeptr pNode);
|
||||
|
||||
SNodeList* nodesMakeList();
|
||||
int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode);
|
||||
int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode);
|
||||
int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode);
|
||||
int32_t nodesListMakeStrictAppend(SNodeList** pList, SNodeptr pNode);
|
||||
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListPushFront(SNodeList* pList, SNodeptr pNode);
|
||||
int32_t nodesListAppend(SNodeList* pList, SNodeptr pNode);
|
||||
int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode);
|
||||
int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode);
|
||||
int32_t nodesListMakeStrictAppend(SNodeList** pList, SNodeptr pNode);
|
||||
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc);
|
||||
int32_t nodesListPushFront(SNodeList* pList, SNodeptr pNode);
|
||||
SListCell* nodesListErase(SNodeList* pList, SListCell* pCell);
|
||||
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc);
|
||||
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index);
|
||||
void nodesDestroyList(SNodeList* pList);
|
||||
void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc);
|
||||
SNodeptr nodesListGetNode(SNodeList* pList, int32_t index);
|
||||
void nodesDestroyList(SNodeList* pList);
|
||||
// Only clear the linked list structure, without releasing the elements inside
|
||||
void nodesClearList(SNodeList* pList);
|
||||
|
||||
typedef enum EDealRes {
|
||||
DEAL_RES_CONTINUE = 1,
|
||||
DEAL_RES_IGNORE_CHILD,
|
||||
DEAL_RES_ERROR,
|
||||
DEAL_RES_END
|
||||
} EDealRes;
|
||||
typedef enum EDealRes { DEAL_RES_CONTINUE = 1, DEAL_RES_IGNORE_CHILD, DEAL_RES_ERROR, DEAL_RES_END } EDealRes;
|
||||
|
||||
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
|
||||
void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||
|
@ -261,18 +267,18 @@ void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void*
|
|||
|
||||
bool nodesEqualNode(const SNodeptr a, const SNodeptr b);
|
||||
|
||||
SNodeptr nodesCloneNode(const SNodeptr pNode);
|
||||
SNodeptr nodesCloneNode(const SNodeptr pNode);
|
||||
SNodeList* nodesCloneList(const SNodeList* pList);
|
||||
|
||||
const char* nodesNodeName(ENodeType type);
|
||||
int32_t nodesNodeToString(const SNodeptr pNode, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
||||
int32_t nodesNodeToString(const SNodeptr pNode, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
||||
|
||||
int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
||||
|
||||
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len);
|
||||
char *nodesGetNameFromColumnNode(SNode *pNode);
|
||||
int32_t nodesNodeToSQL(SNode* pNode, char* buf, int32_t bufSize, int32_t* len);
|
||||
char* nodesGetNameFromColumnNode(SNode* pNode);
|
||||
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -88,6 +88,7 @@ typedef struct SValueNode {
|
|||
double d;
|
||||
char* p;
|
||||
} datum;
|
||||
int64_t typeData;
|
||||
char unit;
|
||||
} SValueNode;
|
||||
|
||||
|
@ -294,13 +295,14 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
|
|||
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;
|
||||
|
||||
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
|
||||
SNodeList** pCols);
|
||||
|
||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||
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 nodesIsUnaryOp(const SOperatorNode* pOp);
|
||||
|
@ -312,6 +314,7 @@ bool nodesIsTimeorderQuery(const SNode* pQuery);
|
|||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||
|
||||
void* nodesGetValueFromNode(SValueNode* pNode);
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value);
|
||||
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
||||
char* getFillModeString(EFillMode mode);
|
||||
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||
|
|
|
@ -318,6 +318,7 @@ int32_t* taosGetErrno();
|
|||
#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_HASH_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x0517)
|
||||
#define TSDB_CODE_VND_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0518)
|
||||
|
||||
// tsdb
|
||||
#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_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_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
|
|
@ -79,17 +79,6 @@ typedef struct {
|
|||
#define TD_CODER_CURRENT(CODER) ((CODER)->data + (CODER)->pos)
|
||||
#define TD_CODER_MOVE_POS(CODER, MOVE) ((CODER)->pos += (MOVE))
|
||||
#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) {
|
||||
void* ptr = NULL;
|
||||
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) \
|
||||
do{ \
|
||||
do { \
|
||||
SCoder coder = {0}; \
|
||||
RET = 0; \
|
||||
tCoderInit(&coder, TD_LITTLE_ENDIAN, NULL, 0, TD_ENCODER); \
|
||||
if ((E)(&coder, S) == 0) { \
|
||||
SIZE = coder.pos; \
|
||||
|
@ -111,7 +101,7 @@ static FORCE_INLINE void* tCoderMalloc(SCoder* pCoder, int32_t size) {
|
|||
RET = -1; \
|
||||
} \
|
||||
tCoderClear(&coder); \
|
||||
}while(0)
|
||||
} while (0)
|
||||
// #define tEncodeSize(E, S, SIZE) \
|
||||
// ({ \
|
||||
// SCoder coder = {0}; \
|
||||
|
|
|
@ -52,72 +52,21 @@ typedef struct SSkipListNode {
|
|||
#define SL_NODE_GET_FORWARD_POINTER(n, l) (n)->forwards[(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 struct SSkipList {
|
||||
uint32_t seed;
|
||||
__compar_fn_t comparFn;
|
||||
__sl_key_fn_t keyFn;
|
||||
TdThreadRwlock *lock;
|
||||
uint16_t len;
|
||||
uint8_t maxLevel;
|
||||
uint8_t flags;
|
||||
uint8_t type; // static info above
|
||||
uint8_t level;
|
||||
uint32_t size;
|
||||
SSkipListNode *pHead; // point to the first element
|
||||
SSkipListNode *pTail; // point to the last element
|
||||
#if SKIP_LIST_RECORD_PERFORMANCE
|
||||
tSkipListState state; // skiplist state
|
||||
#endif
|
||||
uint32_t seed;
|
||||
__compar_fn_t comparFn;
|
||||
__sl_key_fn_t keyFn;
|
||||
TdThreadRwlock *lock;
|
||||
uint16_t len;
|
||||
uint8_t maxLevel;
|
||||
uint8_t flags;
|
||||
uint8_t type; // static info above
|
||||
uint8_t level;
|
||||
uint32_t size;
|
||||
SSkipListNode *pHead; // point to the first element
|
||||
SSkipListNode *pTail; // point to the last element
|
||||
tGenericSavedFunc *insertHandleFn;
|
||||
} SSkipList;
|
||||
|
||||
|
|
|
@ -46,11 +46,12 @@ typedef struct SStmtTableCache {
|
|||
void* boundTags;
|
||||
} SStmtTableCache;
|
||||
|
||||
typedef struct SQueryFields {
|
||||
typedef struct SStmtQueryResInfo {
|
||||
TAOS_FIELD* fields;
|
||||
TAOS_FIELD* userFields;
|
||||
uint32_t numOfCols;
|
||||
} SQueryFields;
|
||||
int32_t precision;
|
||||
} SStmtQueryResInfo;
|
||||
|
||||
typedef struct SStmtBindInfo {
|
||||
bool needParse;
|
||||
|
@ -72,17 +73,17 @@ typedef struct SStmtExecInfo {
|
|||
} SStmtExecInfo;
|
||||
|
||||
typedef struct SStmtSQLInfo {
|
||||
STMT_TYPE type;
|
||||
STMT_STATUS status;
|
||||
bool autoCreate;
|
||||
uint64_t runTimes;
|
||||
SHashObj* pTableCache; //SHash<SStmtTableCache>
|
||||
SQuery* pQuery;
|
||||
char* sqlStr;
|
||||
int32_t sqlLen;
|
||||
SArray* nodeList;
|
||||
SQueryPlan* pQueryPlan;
|
||||
SQueryFields fields;
|
||||
STMT_TYPE type;
|
||||
STMT_STATUS status;
|
||||
bool autoCreate;
|
||||
uint64_t runTimes;
|
||||
SHashObj* pTableCache; //SHash<SStmtTableCache>
|
||||
SQuery* pQuery;
|
||||
char* sqlStr;
|
||||
int32_t sqlLen;
|
||||
SArray* nodeList;
|
||||
SQueryPlan* pQueryPlan;
|
||||
SStmtQueryResInfo queryRes;
|
||||
} SStmtSQLInfo;
|
||||
|
||||
typedef struct STscStmt {
|
||||
|
|
|
@ -74,17 +74,44 @@ int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) {
|
|||
}
|
||||
|
||||
int32_t stmtBackupQueryFields(STscStmt* pStmt) {
|
||||
SQueryFields *pFields = &pStmt->sql.fields;
|
||||
int32_t size = pFields->numOfCols * sizeof(TAOS_FIELD);
|
||||
SStmtQueryResInfo *pRes = &pStmt->sql.queryRes;
|
||||
pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols;
|
||||
pRes->precision = pStmt->exec.pRequest->body.resInfo.precision;
|
||||
|
||||
pFields->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols;
|
||||
pFields->fields = taosMemoryMalloc(size);
|
||||
pFields->userFields = taosMemoryMalloc(size);
|
||||
if (NULL == pFields->fields || NULL == pFields->userFields) {
|
||||
int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD);
|
||||
pRes->fields = taosMemoryMalloc(size);
|
||||
pRes->userFields = taosMemoryMalloc(size);
|
||||
if (NULL == pRes->fields || NULL == pRes->userFields) {
|
||||
STMT_ERR_RET(TSDB_CODE_TSC_OUT_OF_MEMORY);
|
||||
}
|
||||
memcpy(pFields->fields, pStmt->exec.pRequest->body.resInfo.fields, size);
|
||||
memcpy(pFields->userFields, pStmt->exec.pRequest->body.resInfo.userFields, size);
|
||||
memcpy(pRes->fields, pStmt->exec.pRequest->body.resInfo.fields, 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;
|
||||
}
|
||||
|
@ -235,6 +262,8 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) {
|
|||
}
|
||||
|
||||
int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
|
||||
taosMemoryFree(pStmt->sql.queryRes.fields);
|
||||
taosMemoryFree(pStmt->sql.queryRes.userFields);
|
||||
taosMemoryFree(pStmt->sql.sqlStr);
|
||||
qDestroyQuery(pStmt->sql.pQuery);
|
||||
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->exec.pRequest->body.pDag = NULL;
|
||||
STMT_ERR_RET(stmtBackupQueryFields(pStmt));
|
||||
} else {
|
||||
STMT_ERR_RET(stmtRestoreQueryFields(pStmt));
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
if (colIdx != (pStmt->bInfo.sBindLastIdx + 1) && colIdx != 0) {
|
||||
tscError("bind column index not in sequence");
|
||||
|
|
|
@ -68,6 +68,7 @@ struct tmq_conf_t {
|
|||
char* pass;
|
||||
char* db;
|
||||
tmq_commit_cb* commitCb;
|
||||
void* commitCbUserParam;
|
||||
};
|
||||
|
||||
struct tmq_t {
|
||||
|
@ -78,7 +79,8 @@ struct tmq_t {
|
|||
int32_t autoCommitInterval;
|
||||
int32_t resetOffsetCfg;
|
||||
int64_t consumerId;
|
||||
tmq_commit_cb* commit_cb;
|
||||
tmq_commit_cb* commitCb;
|
||||
void* commitCbUserParam;
|
||||
|
||||
// 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) {
|
||||
SMqCommitCbParam* pParam = (SMqCommitCbParam*)param;
|
||||
pParam->rspErr = code == 0 ? TMQ_RESP_ERR__SUCCESS : TMQ_RESP_ERR__FAIL;
|
||||
if (pParam->tmq->commit_cb) {
|
||||
pParam->tmq->commit_cb(pParam->tmq, pParam->rspErr, NULL);
|
||||
if (pParam->tmq->commitCb) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -384,7 +394,7 @@ tmq_resp_err_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
|
|||
*topics = tmq_list_new();
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
pTmq->autoCommit = conf->autoCommit;
|
||||
pTmq->autoCommitInterval = conf->autoCommitInterval;
|
||||
pTmq->commit_cb = conf->commitCb;
|
||||
pTmq->commitCb = conf->commitCb;
|
||||
pTmq->commitCbUserParam = conf->commitCbUserParam;
|
||||
pTmq->resetOffsetCfg = conf->resetOffset;
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
SMqCommitCbParam* pParam = taosMemoryMalloc(sizeof(SMqCommitCbParam));
|
||||
SMqCommitCbParam* pParam = taosMemoryCalloc(1, sizeof(SMqCommitCbParam));
|
||||
if (pParam == NULL) {
|
||||
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);
|
||||
sendInfo->requestObjRefId = 0;
|
||||
sendInfo->param = pParam;
|
||||
sendInfo->fp = tmqCommitCb;
|
||||
SEpSet epSet = getEpSet_s(&tmq->pTscObj->pAppInfo->mgmtEp);
|
||||
|
@ -582,13 +594,12 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in
|
|||
if (!async) {
|
||||
tsem_wait(&pParam->rspSem);
|
||||
resp = pParam->rspErr;
|
||||
}
|
||||
tsem_destroy(&pParam->rspSem);
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
tsem_destroy(&pParam->rspSem);
|
||||
taosMemoryFree(pParam);
|
||||
|
||||
if (pArray) {
|
||||
taosArrayDestroy(pArray);
|
||||
if (pArray) {
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
}
|
||||
|
||||
return resp;
|
||||
|
@ -688,9 +699,10 @@ FAIL:
|
|||
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->commitCbUserParam = param;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -1306,10 +1318,10 @@ const char* tmq_err2str(tmq_resp_err_t err) {
|
|||
return "fail";
|
||||
}
|
||||
|
||||
char* tmq_get_topic_name(TAOS_RES* res) {
|
||||
const char* tmq_get_topic_name(TAOS_RES* res) {
|
||||
if (TD_RES_TMQ(res)) {
|
||||
SMqRspObj* pRspObj = (SMqRspObj*)res;
|
||||
return pRspObj->topic;
|
||||
return strchr(pRspObj->topic, '.') + 1;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -490,21 +490,6 @@ int32_t tDeserializeSClientHbBatchRsp(void *buf, int32_t bufLen, SClientHbBatchR
|
|||
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) {
|
||||
SCoder encoder = {0};
|
||||
tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_ENCODER);
|
||||
|
@ -3811,3 +3796,119 @@ int tDecodeSVCreateTbRsp(SCoder *pCoder, SVCreateTbRsp *pRsp) {
|
|||
tEndDecode(pCoder);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -254,8 +254,17 @@ static void dmSendRpcRedirectRsp(SDnode *pDnode, const SRpcMsg *pReq) {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef int32_t (*MndInitFp)(SMnode *pMnode);
|
|||
typedef void (*MndCleanupFp)(SMnode *pMnode);
|
||||
typedef int32_t (*ShowRetrieveFp)(SNodeMsg *pMsg, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
typedef void (*ShowFreeIterFp)(SMnode *pMnode, void *pIter);
|
||||
typedef struct SQWorkerMgmt SQHandle;
|
||||
typedef struct SQWorker SQHandle;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
|
|
@ -428,17 +428,23 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
SVDropTbReq req = {0};
|
||||
req.ver = 0;
|
||||
req.name = (char *)tNameGetTableName(&name);
|
||||
req.type = TD_SUPER_TABLE;
|
||||
req.suid = pStb->uid;
|
||||
|
||||
int32_t contLen = tSerializeSVDropTbReq(NULL, &req) + sizeof(SMsgHead);
|
||||
SMsgHead *pHead = taosMemoryMalloc(contLen);
|
||||
tEncodeSize(tEncodeSVDropStbReq, &req, contLen, ret);
|
||||
if (ret < 0) return NULL;
|
||||
|
||||
contLen += sizeof(SMsgHead);
|
||||
pHead = taosMemoryMalloc(contLen);
|
||||
if (pHead == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
|
@ -448,7 +454,10 @@ static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb,
|
|||
pHead->vgId = htonl(pVgroup->vgId);
|
||||
|
||||
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;
|
||||
return pHead;
|
||||
|
|
|
@ -144,6 +144,10 @@ static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SM
|
|||
|
||||
int32_t vgId = pRebVg->pVgEp->vgId;
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId);
|
||||
if (pVgObj == NULL) {
|
||||
taosMemoryFree(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STransAction action = {0};
|
||||
action.epSet = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
|
@ -509,7 +513,9 @@ static int32_t mndProcessRebalanceReq(SNodeMsg *pMsg) {
|
|||
/*ASSERT(taosArrayGetSize(rebOutput.rebVgs) != 0);*/
|
||||
|
||||
// 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) {
|
||||
SMqTopicObj *pTopic = (SMqTopicObj *)rebInput.pTopic;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SQWorkerMgmt SQHandle;
|
||||
typedef struct SQWorker SQHandle;
|
||||
|
||||
typedef struct SQnode {
|
||||
int32_t qndId;
|
||||
|
|
|
@ -8,7 +8,6 @@ target_sources(
|
|||
"src/vnd/vnodeBufPool.c"
|
||||
"src/vnd/vnodeCfg.c"
|
||||
"src/vnd/vnodeCommit.c"
|
||||
"src/vnd/vnodeInt.c"
|
||||
"src/vnd/vnodeQuery.c"
|
||||
"src/vnd/vnodeStateMgr.c"
|
||||
"src/vnd/vnodeModule.c"
|
||||
|
@ -33,7 +32,6 @@ target_sources(
|
|||
"src/tsdb/tsdbMemTable.c"
|
||||
"src/tsdb/tsdbRead.c"
|
||||
"src/tsdb/tsdbReadImpl.c"
|
||||
"src/tsdb/tsdbScan.c"
|
||||
"src/tsdb/tsdbSma.c"
|
||||
"src/tsdb/tsdbWrite.c"
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "trow.h"
|
||||
|
||||
#include "tdbInt.h"
|
||||
#include "tdb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -57,9 +57,6 @@ int vnodeProcessCMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
|||
int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
||||
int vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg);
|
||||
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);
|
||||
int vnodeValidateTableHash(SVnode *pVnode, char *tableFName);
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ int metaEncodeEntry(SCoder* pCoder, const SMetaEntry* pME);
|
|||
int metaDecodeEntry(SCoder* pCoder, SMetaEntry* pME);
|
||||
|
||||
// metaTable ==================
|
||||
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
|
||||
|
||||
// metaQuery ==================
|
||||
int metaGetTableEntryByVersion(SMetaReader* pReader, int64_t version, tb_uid_t uid);
|
||||
|
|
|
@ -73,7 +73,6 @@ struct STsdb {
|
|||
SVnode *pVnode;
|
||||
bool repoLocked;
|
||||
TdThreadMutex mutex;
|
||||
STsdbCfg config;
|
||||
STsdbMemTable *mem;
|
||||
STsdbMemTable *imem;
|
||||
SRtn rtn;
|
||||
|
@ -185,7 +184,7 @@ struct STsdbFS {
|
|||
};
|
||||
|
||||
#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_META(r) ((r)->pVnode->pMeta)
|
||||
#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
|
||||
#define TSDB_FILE_HEAD_SIZE 512
|
||||
#define TSDB_FILE_DELIMITER 0xF00AFA0F
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "tcompare.h"
|
||||
#include "tcompression.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdbInt.h"
|
||||
#include "tdb.h"
|
||||
#include "tencode.h"
|
||||
#include "tfs.h"
|
||||
#include "tglobal.h"
|
||||
|
@ -52,7 +52,7 @@ typedef struct STsdb STsdb;
|
|||
typedef struct STQ STQ;
|
||||
typedef struct SVState SVState;
|
||||
typedef struct SVBufPool SVBufPool;
|
||||
typedef struct SQWorkerMgmt SQHandle;
|
||||
typedef struct SQWorker SQHandle;
|
||||
|
||||
#define VNODE_META_DIR "meta"
|
||||
#define VNODE_TSDB_DIR "tsdb"
|
||||
|
@ -75,6 +75,7 @@ int metaClose(SMeta* pMeta);
|
|||
int metaBegin(SMeta* pMeta);
|
||||
int metaCommit(SMeta* pMeta);
|
||||
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);
|
||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
|
||||
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
|
||||
|
|
|
@ -47,66 +47,66 @@ int metaOpen(SVnode *pVnode, SMeta **ppMeta) {
|
|||
// open env
|
||||
ret = tdbEnvOpen(pMeta->path, pVnode->config.szPage, pVnode->config.szCache, &pMeta->pEnv);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pTbDb
|
||||
ret = tdbDbOpen("table.db", sizeof(STbDbKey), -1, tbDbKeyCmpr, pMeta->pEnv, &pMeta->pTbDb);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pSkmDb
|
||||
ret = tdbDbOpen("schema.db", sizeof(SSkmDbKey), -1, skmDbKeyCmpr, pMeta->pEnv, &pMeta->pSkmDb);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pUidIdx
|
||||
ret = tdbDbOpen("uid.idx", sizeof(tb_uid_t), sizeof(int64_t), uidIdxKeyCmpr, pMeta->pEnv, &pMeta->pUidIdx);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pNameIdx
|
||||
ret = tdbDbOpen("name.idx", -1, sizeof(tb_uid_t), NULL, pMeta->pEnv, &pMeta->pNameIdx);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pCtbIdx
|
||||
ret = tdbDbOpen("ctb.idx", sizeof(SCtbIdxKey), 0, ctbIdxKeyCmpr, pMeta->pEnv, &pMeta->pCtbIdx);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pTagIdx
|
||||
ret = tdbDbOpen("tag.idx", -1, 0, tagIdxKeyCmpr, pMeta->pEnv, &pMeta->pTagIdx);
|
||||
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;
|
||||
}
|
||||
|
||||
// open pTtlIdx
|
||||
ret = tdbDbOpen("ttl.idx", sizeof(STtlIdxKey), 0, ttlIdxKeyCmpr, pMeta->pEnv, &pMeta->pTtlIdx);
|
||||
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;
|
||||
}
|
||||
|
||||
// open index
|
||||
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;
|
||||
}
|
||||
|
||||
metaDebug("vgId: %d meta is opened", TD_VID(pVnode));
|
||||
metaDebug("vgId:%d meta is opened", TD_VID(pVnode));
|
||||
|
||||
*ppMeta = pMeta;
|
||||
return 0;
|
||||
|
|
|
@ -23,7 +23,7 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
|
|||
|
||||
void metaReaderClear(SMetaReader *pReader) {
|
||||
tCoderClear(&pReader->coder);
|
||||
TDB_FREE(pReader->pBuf);
|
||||
tdbFree(pReader->pBuf);
|
||||
}
|
||||
|
||||
int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) {
|
||||
|
@ -96,15 +96,17 @@ SMTbCursor *metaOpenTbCursor(SMeta *pMeta) {
|
|||
|
||||
metaReaderInit(&pTbCur->mr, pMeta, 0);
|
||||
|
||||
tdbDbcOpen(pMeta->pUidIdx, &pTbCur->pDbc);
|
||||
tdbDbcOpen(pMeta->pUidIdx, &pTbCur->pDbc, NULL);
|
||||
|
||||
tdbDbcMoveToFirst(pTbCur->pDbc);
|
||||
|
||||
return pTbCur;
|
||||
}
|
||||
|
||||
void metaCloseTbCursor(SMTbCursor *pTbCur) {
|
||||
if (pTbCur) {
|
||||
TDB_FREE(pTbCur->pKey);
|
||||
TDB_FREE(pTbCur->pVal);
|
||||
tdbFree(pTbCur->pKey);
|
||||
tdbFree(pTbCur->pVal);
|
||||
metaReaderClear(&pTbCur->mr);
|
||||
if (pTbCur->pDbc) {
|
||||
tdbDbcClose(pTbCur->pDbc);
|
||||
|
@ -119,7 +121,7 @@ int metaTbCursorNext(SMTbCursor *pTbCur) {
|
|||
STbCfg tbCfg;
|
||||
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, boo
|
|||
|
||||
pSW->pSchema = pSchema;
|
||||
|
||||
TDB_FREE(pVal);
|
||||
tdbFree(pVal);
|
||||
|
||||
return pSW;
|
||||
}
|
||||
|
@ -185,7 +187,9 @@ struct SMCtbCursor {
|
|||
|
||||
SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
|
||||
SMCtbCursor *pCtbCur = NULL;
|
||||
SCtbIdxKey ctbIdxKey;
|
||||
int ret;
|
||||
int c;
|
||||
|
||||
pCtbCur = (SMCtbCursor *)taosMemoryCalloc(1, sizeof(*pCtbCur));
|
||||
if (pCtbCur == NULL) {
|
||||
|
@ -193,12 +197,20 @@ SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid) {
|
|||
}
|
||||
|
||||
pCtbCur->suid = uid;
|
||||
ret = tdbDbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur);
|
||||
ret = tdbDbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL);
|
||||
if (ret < 0) {
|
||||
taosMemoryFree(pCtbCur);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -207,8 +219,8 @@ void metaCloseCtbCurosr(SMCtbCursor *pCtbCur) {
|
|||
if (pCtbCur->pCur) {
|
||||
tdbDbcClose(pCtbCur->pCur);
|
||||
|
||||
TDB_FREE(pCtbCur->pKey);
|
||||
TDB_FREE(pCtbCur->pVal);
|
||||
tdbFree(pCtbCur->pKey);
|
||||
tdbFree(pCtbCur->pVal);
|
||||
}
|
||||
|
||||
taosMemoryFree(pCtbCur);
|
||||
|
@ -219,12 +231,15 @@ tb_uid_t metaCtbCursorNext(SMCtbCursor *pCtbCur) {
|
|||
int ret;
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pCtbIdxKey = pCtbCur->pKey;
|
||||
if (pCtbIdxKey->suid > pCtbCur->suid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pCtbIdxKey->uid;
|
||||
}
|
||||
|
@ -283,7 +298,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
|
||||
while (true) {
|
||||
// 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;
|
||||
ASSERT(pSmaIdxKey != NULL);
|
||||
|
||||
|
@ -297,7 +312,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
++pSW->number;
|
||||
STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma));
|
||||
if (tptr == NULL) {
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
metaCloseSmaCursor(pCur);
|
||||
tdDestroyTSmaWrapper(pSW);
|
||||
taosMemoryFreeClear(pSW);
|
||||
|
@ -306,13 +321,13 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
pSW->tSma = tptr;
|
||||
pBuf = pSmaVal;
|
||||
if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) {
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
metaCloseSmaCursor(pCur);
|
||||
tdDestroyTSmaWrapper(pSW);
|
||||
taosMemoryFreeClear(pSW);
|
||||
return NULL;
|
||||
}
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -354,7 +369,7 @@ SArray *metaGetSmaTbUids(SMeta *pMeta, bool isDup) {
|
|||
tb_uid_t uid = 0;
|
||||
while (true) {
|
||||
// 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);
|
||||
pSmaIdxKey = pCur->pKey;
|
||||
|
||||
|
@ -425,11 +440,11 @@ void *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid, bool isDecode) {
|
|||
if (tDecodeTSma(pBuf, pCfg) == NULL) {
|
||||
tdDestroyTSma(pCfg);
|
||||
taosMemoryFree(pCfg);
|
||||
TDB_FREE(pVal);
|
||||
tdbFree(pVal);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TDB_FREE(pVal);
|
||||
tdbFree(pVal);
|
||||
return pCfg;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -289,7 +289,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
pVal = pBuf = buf;
|
||||
metaEncodeTbInfo(&pBuf, pTbCfg);
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
pVal = pBuf = buf;
|
||||
metaEncodeSchemaEx(&pBuf, &schemaWrapper);
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
kLen = nameLen + 1 + sizeof(uid);
|
||||
pVal = NULL;
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
kLen = sizeof(uid);
|
||||
pVal = NULL;
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
kLen = sizeof(ctbIdxKey);
|
||||
pVal = NULL;
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ int metaSaveTableToDB(SMeta *pMeta, STbCfg *pTbCfg, STbDdlH *pHandle) {
|
|||
kLen = sizeof(uid);
|
||||
pVal = NULL;
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ static SSchemaWrapper *metaGetTableSchemaImpl(SMeta *pMeta, tb_uid_t uid, int32_
|
|||
pSchemaWrapper = taosMemoryMalloc(sizeof(*pSchemaWrapper));
|
||||
metaDecodeSchemaEx(pBuf, pSchemaWrapper, isGetEx);
|
||||
|
||||
TDB_FREE(pVal);
|
||||
tdbFree(pVal);
|
||||
|
||||
return pSchemaWrapper;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
|
||||
while (true) {
|
||||
// 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;
|
||||
ASSERT(pSmaIdxKey != NULL);
|
||||
|
||||
|
@ -450,7 +450,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
}
|
||||
|
||||
if ((pSW == NULL) && ((pSW = taosMemoryCalloc(1, sizeof(*pSW))) == NULL)) {
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
metaCloseSmaCursor(pCur);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
++pSW->number;
|
||||
STSma *tptr = (STSma *)taosMemoryRealloc(pSW->tSma, pSW->number * sizeof(STSma));
|
||||
if (tptr == NULL) {
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
metaCloseSmaCursor(pCur);
|
||||
tdDestroyTSmaWrapper(pSW);
|
||||
taosMemoryFreeClear(pSW);
|
||||
|
@ -467,13 +467,13 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid) {
|
|||
pSW->tSma = tptr;
|
||||
pBuf = pSmaVal;
|
||||
if (tDecodeTSma(pBuf, pSW->tSma + pSW->number - 1) == NULL) {
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
metaCloseSmaCursor(pCur);
|
||||
tdDestroyTSmaWrapper(pSW);
|
||||
taosMemoryFreeClear(pSW);
|
||||
return NULL;
|
||||
}
|
||||
TDB_FREE(pSmaVal);
|
||||
tdbFree(pSmaVal);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -530,7 +530,7 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
|
|||
int32_t kLen = sizeof(pSmaCfg->indexUid);
|
||||
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) {
|
||||
taosMemoryFreeClear(pBuf);
|
||||
return -1;
|
||||
|
@ -545,7 +545,7 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
|
|||
val = NULL;
|
||||
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) {
|
||||
taosMemoryFreeClear(pBuf);
|
||||
return -1;
|
||||
|
@ -613,7 +613,7 @@ int64_t metaSmaCursorNext(SMSmaCursor *pCur) {
|
|||
void *pBuf;
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,19 +61,58 @@ int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
|
||||
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;
|
||||
|
||||
_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));
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
_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) {
|
||||
|
@ -179,7 +218,7 @@ static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
|
|||
tCoderClear(&coder);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -192,11 +231,11 @@ _err:
|
|||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
@ -219,12 +258,12 @@ static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME) {
|
|||
ttlKey.dtime = ctime + ttlDays * 24 * 60 * 60;
|
||||
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) {
|
||||
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) {
|
||||
|
@ -265,7 +304,7 @@ static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
|
|||
tCoderInit(&coder, TD_LITTLE_ENDIAN, pVal, vLen, TD_ENCODER);
|
||||
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;
|
||||
goto _exit;
|
||||
}
|
||||
|
|
|
@ -91,16 +91,8 @@ int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* p
|
|||
int32_t sversion = 0;
|
||||
if (pHandle->sver != sversion) {
|
||||
pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion);
|
||||
#if 0
|
||||
tb_uid_t quid;
|
||||
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
|
||||
|
||||
// this interface use suid instead of uid
|
||||
pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true);
|
||||
pHandle->sver = sversion;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef struct {
|
|||
#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_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)))
|
||||
|
||||
static void tsdbStartCommit(STsdb *pRepo);
|
||||
|
|
|
@ -56,9 +56,8 @@ int tsdbOpenImpl(SVnode *pVnode, int8_t type, STsdb **ppTsdb, const char *dir) {
|
|||
dir);
|
||||
pTsdb->pVnode = pVnode;
|
||||
pTsdb->repoLocked = false;
|
||||
tdbMutexInit(&pTsdb->mutex, NULL);
|
||||
pTsdb->config = pVnode->config.tsdbCfg;
|
||||
pTsdb->fs = tsdbNewFS(&pTsdb->config);
|
||||
taosThreadMutexInit(&pTsdb->mutex, NULL);
|
||||
pTsdb->fs = tsdbNewFS(REPO_CFG(pTsdb));
|
||||
|
||||
// create dir (TODO: use tfsMkdir)
|
||||
taosMkDir(pTsdb->path);
|
||||
|
|
|
@ -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
|
||||
// the expired data to client, even it is queried already.
|
||||
static int64_t getEarliestValidTimestamp(STsdb* pTsdb) {
|
||||
STsdbCfg* pCfg = &pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pTsdb);
|
||||
|
||||
int64_t now = taosGetTimestamp(pCfg->precision);
|
||||
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->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->config.maxRows);
|
||||
pReadHandle->pDataCols = tdNewDataCols(1000, pReadHandle->pTsdb->pVnode->config.tsdbCfg.maxRows);
|
||||
if (pReadHandle->pDataCols == NULL) {
|
||||
tsdbError("%p failed to malloc buf for pDataCols, %s", pReadHandle, pReadHandle->idStr);
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
|
@ -889,7 +889,7 @@ static bool moveToNextRowInMem(STableCheckInfo* pCheckInfo) {
|
|||
}
|
||||
|
||||
static bool hasMoreDataInCache(STsdbReadHandle* pHandle) {
|
||||
STsdbCfg* pCfg = &pHandle->pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pHandle->pTsdb);
|
||||
size_t size = taosArrayGetSize(pHandle->pTableCheckInfo);
|
||||
assert(pHandle->activeIndex < size && pHandle->activeIndex >= 0 && size >= 1);
|
||||
pHandle->cur.fid = INT32_MIN;
|
||||
|
@ -1169,7 +1169,7 @@ static void copyAllRemainRowsFromFileBlock(STsdbReadHandle* pTsdbReadHandle,
|
|||
|
||||
static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock* pBlock, STableCheckInfo* pCheckInfo) {
|
||||
SQueryFilePos* cur = &pTsdbReadHandle->cur;
|
||||
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
|
||||
SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
||||
TSKEY key;
|
||||
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) {
|
||||
SQueryFilePos* cur = &pTsdbReadHandle->cur;
|
||||
SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
||||
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
|
||||
|
||||
initTableMemIterator(pTsdbReadHandle, pCheckInfo);
|
||||
|
||||
|
@ -2200,7 +2200,7 @@ static int32_t getFirstFileDataBlock(STsdbReadHandle* pTsdbReadHandle, bool* exi
|
|||
int32_t numOfBlocks = 0;
|
||||
int32_t numOfTables = (int32_t)taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
|
||||
|
||||
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
|
||||
STimeWindow win = TSWINDOW_INITIALIZER;
|
||||
|
||||
while (true) {
|
||||
|
@ -2306,7 +2306,7 @@ int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT* queryHandle, STableBlockDistInfo*
|
|||
|
||||
// find the start data block in file
|
||||
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);
|
||||
|
||||
tsdbRLockFS(pFileHandle);
|
||||
|
@ -2407,7 +2407,7 @@ static int32_t getDataBlocksInFiles(STsdbReadHandle* pTsdbReadHandle, bool* exis
|
|||
// find the start data block in file
|
||||
if (!pTsdbReadHandle->locateStart) {
|
||||
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);
|
||||
|
||||
tsdbRLockFS(pFileHandle);
|
||||
|
@ -2498,7 +2498,7 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
|
|||
STsdbReadHandle* pTsdbReadHandle) {
|
||||
int numOfRows = 0;
|
||||
int32_t numOfCols = (int32_t)taosArrayGetSize(pTsdbReadHandle->pColumns);
|
||||
STsdbCfg* pCfg = &pTsdbReadHandle->pTsdb->config;
|
||||
STsdbCfg* pCfg = REPO_CFG(pTsdbReadHandle->pTsdb);
|
||||
win->skey = TSKEY_INITIAL_VAL;
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
|
|
@ -248,7 +248,8 @@ int tsdbLoadBlockInfo(SReadH *pReadh, void *pTarget) {
|
|||
|
||||
int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
||||
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;
|
||||
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,
|
||||
bool mergeBitmap) {
|
||||
ASSERT(pBlock->numOfSubBlocks > 0);
|
||||
int8_t update = pReadh->pRepo->config.update;
|
||||
int8_t update = pReadh->pRepo->pVnode->config.tsdbCfg.update;
|
||||
|
||||
SBlock *iBlock = pBlock;
|
||||
if (pBlock->numOfSubBlocks > 1) {
|
||||
|
|
|
@ -223,7 +223,7 @@ static FORCE_INLINE int32_t tsdbUnLockSma(SSmaEnv *pEnv) {
|
|||
}
|
||||
|
||||
static SPoolMem *openPool() {
|
||||
SPoolMem *pPool = (SPoolMem *)tdbOsMalloc(sizeof(*pPool));
|
||||
SPoolMem *pPool = (SPoolMem *)taosMemoryMalloc(sizeof(*pPool));
|
||||
|
||||
pPool->prev = pPool->next = pPool;
|
||||
pPool->size = 0;
|
||||
|
@ -245,7 +245,7 @@ static void clearPool(SPoolMem *pPool) {
|
|||
pMem->prev->next = pMem->next;
|
||||
pPool->size -= pMem->size;
|
||||
|
||||
tdbOsFree(pMem);
|
||||
taosMemoryFree(pMem);
|
||||
} while (1);
|
||||
|
||||
assert(pPool->size == 0);
|
||||
|
@ -254,7 +254,7 @@ static void clearPool(SPoolMem *pPool) {
|
|||
static void closePool(SPoolMem *pPool) {
|
||||
if (pPool) {
|
||||
clearPool(pPool);
|
||||
tdbOsFree(pPool);
|
||||
taosMemoryFree(pPool);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ static void *poolMalloc(void *arg, size_t size) {
|
|||
SPoolMem *pPool = (SPoolMem *)arg;
|
||||
SPoolMem *pMem;
|
||||
|
||||
pMem = (SPoolMem *)tdbOsMalloc(sizeof(*pMem) + size);
|
||||
pMem = (SPoolMem *)taosMemoryMalloc(sizeof(*pMem) + size);
|
||||
if (!pMem) {
|
||||
assert(0);
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ static void poolFree(void *arg, void *ptr) {
|
|||
pMem->prev->next = pMem->next;
|
||||
pPool->size -= pMem->size;
|
||||
|
||||
tdbOsFree(pMem);
|
||||
taosMemoryFree(pMem);
|
||||
}
|
||||
|
||||
int32_t tsdbInitSma(STsdb *pTsdb) {
|
||||
|
|
|
@ -55,12 +55,12 @@ static inline int tsdbSmaKeyCmpr(const void *arg1, int len1, const void *arg2, i
|
|||
}
|
||||
|
||||
static int32_t tsdbOpenDBDb(TDB **ppDB, TENV *pEnv, const char *pFName) {
|
||||
int ret;
|
||||
FKeyComparator compFunc;
|
||||
int ret;
|
||||
tdb_cmpr_fn_t compFunc;
|
||||
|
||||
// Create a database
|
||||
compFunc = tsdbSmaKeyCmpr;
|
||||
ret = tdbDbOpen(pFName, TDB_VARIANT_LEN, TDB_VARIANT_LEN, compFunc, pEnv, ppDB);
|
||||
ret = tdbDbOpen(pFName, -1, -1, compFunc, pEnv, ppDB);
|
||||
|
||||
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 ret;
|
||||
|
||||
ret = tdbDbInsert(pDBF->pDB, pKey, keyLen, pVal, valLen, txn);
|
||||
ret = tdbDbPut(pDBF->pDB, pKey, keyLen, pVal, valLen, txn);
|
||||
if (ret < 0) {
|
||||
tsdbError("Failed to create insert sma data into db, ret = %d", ret);
|
||||
return -1;
|
||||
|
|
|
@ -60,9 +60,10 @@ static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg) {
|
|||
SSubmitBlk *pBlock = NULL;
|
||||
SSubmitBlkIter blkIter = {0};
|
||||
STSRow *row = NULL;
|
||||
TSKEY now = taosGetTimestamp(pTsdb->config.precision);
|
||||
TSKEY minKey = now - tsTickPerDay[pTsdb->config.precision] * pTsdb->config.keep2;
|
||||
TSKEY maxKey = now + tsTickPerDay[pTsdb->config.precision] * pTsdb->config.days;
|
||||
STsdbCfg *pCfg = REPO_CFG(pTsdb);
|
||||
TSKEY now = taosGetTimestamp(pCfg->precision);
|
||||
TSKEY minKey = now - tsTickPerDay[pCfg->precision] * pCfg->keep2;
|
||||
TSKEY maxKey = now + tsTickPerDay[pCfg->precision] * pCfg->days;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
pMsg->length = htonl(pMsg->length);
|
||||
|
|
|
@ -42,13 +42,13 @@ int vnodeBegin(SVnode *pVnode) {
|
|||
|
||||
// begin meta
|
||||
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;
|
||||
}
|
||||
|
||||
// begin tsdb
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ int vnodeSaveInfo(const char *dir, const SVnodeInfo *pInfo) {
|
|||
// free info binary
|
||||
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;
|
||||
|
||||
|
@ -115,7 +115,7 @@ int vnodeCommitInfo(const char *dir, const SVnodeInfo *pInfo) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
vInfo("vgId: %d vnode info is committed", pInfo->config.vgId);
|
||||
vInfo("vgId:%d vnode info is committed", pInfo->config.vgId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@ int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
|||
|
||||
// check config
|
||||
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;
|
||||
}
|
||||
|
||||
// create vnode env
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
|||
info.state.applied = -1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
vInfo("vgId: %d vnode is created", pCfg->vgId);
|
||||
vInfo("vgId:%d vnode is created", pCfg->vgId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
pVnode = (SVnode *)taosMemoryCalloc(1, sizeof(*pVnode) + strlen(path) + 1);
|
||||
if (pVnode == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -85,13 +85,13 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
|
||||
// open buffer pool
|
||||
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;
|
||||
}
|
||||
|
||||
// open meta
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_WAL_DIR);
|
||||
pVnode->pWal = walOpen(tdir, &(pVnode->config.walCfg));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -130,25 +130,25 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
sprintf(tdir, "%s%s%s", dir, TD_DIRSEP, VNODE_TQ_DIR);
|
||||
pVnode->pTq = tqOpen(tdir, pVnode, pVnode->pWal);
|
||||
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;
|
||||
}
|
||||
|
||||
// open query
|
||||
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;
|
||||
}
|
||||
|
||||
// vnode begin
|
||||
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;
|
||||
}
|
||||
|
||||
// open sync
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
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 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 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);
|
||||
|
||||
int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) {
|
||||
|
@ -45,6 +45,47 @@ int vnodePreprocessWriteReqs(SVnode *pVnode, SArray *pMsgs, int64_t *version) {
|
|||
#endif
|
||||
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) {
|
||||
void *ptr = NULL;
|
||||
|
@ -52,7 +93,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
|
|||
int len;
|
||||
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);
|
||||
|
||||
pVnode->state.applied = version;
|
||||
|
@ -62,7 +103,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
|
|||
len = pMsg->contLen - sizeof(SMsgHead);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -75,7 +116,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
|
|||
if (vnodeProcessAlterStbReq(pVnode, pReq, len, pRsp) < 0) goto _err;
|
||||
break;
|
||||
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;
|
||||
case TDMT_VND_CREATE_TABLE:
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
case TDMT_VND_CREATE_SMA: { // timeRangeSMA
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
if (vnodeShouldCommit(pVnode)) {
|
||||
|
@ -134,7 +175,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
|
|||
return 0;
|
||||
|
||||
_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);
|
||||
return -1;
|
||||
}
|
||||
|
@ -409,9 +450,32 @@ static int vnodeProcessAlterStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpc
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vnodeProcessDropStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
// TODO
|
||||
// ASSERT(0);
|
||||
static int vnodeProcessDropStbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
SVDropStbReq req = {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;
|
||||
}
|
||||
|
||||
|
@ -421,9 +485,15 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcM
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vnodeProcessDropTbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
SVDropTbReq req = {0};
|
||||
SVDropTbReq rsp = {0};
|
||||
|
||||
// decode req
|
||||
|
||||
// process req
|
||||
|
||||
// return rsp
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,6 +375,7 @@ typedef struct SStreamBlockScanInfo {
|
|||
uint64_t numOfExec; // execution times
|
||||
void* readerHandle; // stream block reader handle
|
||||
SArray* pColMatchInfo; //
|
||||
SNode* pCondition;
|
||||
} SStreamBlockScanInfo;
|
||||
|
||||
typedef struct SSysTableScanInfo {
|
||||
|
@ -672,7 +673,7 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx
|
|||
const STableGroupInfo* pTableGroupInfo);
|
||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo);
|
||||
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,
|
||||
SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal,
|
||||
|
|
|
@ -6538,7 +6538,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
int32_t numOfCols = 0;
|
||||
SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
|
||||
SOperatorInfo* pOperator =
|
||||
createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo);
|
||||
createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo, pScanPhyNode->node.pConditions);
|
||||
taosArrayDestroy(tableIdList);
|
||||
return pOperator;
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
|
||||
|
|
|
@ -514,6 +514,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
|
|||
// NOTE: this operator does never check if current status is done or not
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
int32_t rows = 0;
|
||||
|
||||
pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
|
||||
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;
|
||||
return NULL;
|
||||
}
|
||||
rows = pBlockInfo->rows;
|
||||
doFilter(pInfo->pCondition, pInfo->pRes);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -588,16 +591,16 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
|
|||
pInfo->numOfExec++;
|
||||
pInfo->numOfRows += pBlockInfo->rows;
|
||||
|
||||
if (pBlockInfo->rows == 0) {
|
||||
if (rows == 0) {
|
||||
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,
|
||||
SArray* pTableIdList, SExecTaskInfo* pTaskInfo) {
|
||||
SArray* pTableIdList, SExecTaskInfo* pTaskInfo, SNode* pCondition) {
|
||||
SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -635,6 +638,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
|
|||
|
||||
pInfo->readerHandle = streamReadHandle;
|
||||
pInfo->pRes = pResBlock;
|
||||
pInfo->pCondition = pCondition;
|
||||
|
||||
pOperator->name = "StreamBlockScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;
|
||||
|
|
|
@ -588,6 +588,259 @@ static int32_t jsonToLogicSortNode(const SJson* pJson, void* pObj) {
|
|||
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* 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 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* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite";
|
||||
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 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* jkQueryNodeAddrInUse = "InUse";
|
||||
static const char* jkQueryNodeAddrNumOfEps = "NumOfEps";
|
||||
|
@ -1747,23 +1911,51 @@ static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
code = tjsonGetBoolValue(pJson, jkValueDatum, &pNode->datum.b);
|
||||
*(bool*)&pNode->typeData = pNode->datum.b;
|
||||
break;
|
||||
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:
|
||||
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
|
||||
*(int16_t*)&pNode->typeData = pNode->datum.i;
|
||||
break;
|
||||
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:
|
||||
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
|
||||
*(int64_t*)&pNode->typeData = pNode->datum.i;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
|
||||
*(int64_t*)&pNode->typeData = pNode->datum.i;
|
||||
break;
|
||||
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:
|
||||
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
|
||||
*(uint16_t*)&pNode->typeData = pNode->datum.u;
|
||||
break;
|
||||
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:
|
||||
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
|
||||
*(uint64_t*)&pNode->typeData = pNode->datum.u;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
|
||||
*(float*)&pNode->typeData = pNode->datum.d;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
|
||||
*(double*)&pNode->typeData = pNode->datum.d;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
|
@ -1964,78 +2156,6 @@ static int32_t jsonToTableNode(const SJson* pJson, void* pObj) {
|
|||
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* jkRealTableMeta = "Meta";
|
||||
static const char* jkRealTableVgroupsInfoSize = "VgroupsInfoSize";
|
||||
|
@ -2582,7 +2702,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
return logicSortNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||
return logicPartitionNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||
return logicSubplanToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN:
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
|
@ -2667,6 +2790,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
return jsonToLogicProjectNode(pJson, pObj);
|
||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||
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:
|
||||
return jsonToPhysiTagScanNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
|
|
|
@ -871,21 +871,18 @@ void nodesClearList(SNodeList* pList) {
|
|||
void* nodesGetValueFromNode(SValueNode* pNode) {
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
return (void*)&pNode->datum.b;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return (void*)&pNode->datum.i;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
return (void*)&pNode->datum.u;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
return (void*)&pNode->datum.d;
|
||||
return (void*)&pNode->typeData;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
|
@ -897,6 +894,68 @@ void* nodesGetValueFromNode(SValueNode* pNode) {
|
|||
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) {
|
||||
switch (pNode->node.resType.type) {
|
||||
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,
|
||||
SNodeList** pCols) {
|
||||
if (NULL == pSelect || NULL == pCols) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SCollectColumnsCxt cxt = {
|
||||
.errCode = TSDB_CODE_SUCCESS,
|
||||
.pTableAlias = pTableAlias,
|
||||
.collectType = type,
|
||||
.pCols = nodesMakeList(),
|
||||
.pCols = (NULL == *pCols ? nodesMakeList() : *pCols),
|
||||
.pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)};
|
||||
if (NULL == cxt.pCols || NULL == cxt.pColHash) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*pCols = NULL;
|
||||
nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
|
||||
taosHashCleanup(cxt.pColHash);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(cxt.pCols);
|
||||
return cxt.errCode;
|
||||
}
|
||||
if (0 == LIST_LENGTH(cxt.pCols)) {
|
||||
if (LIST_LENGTH(cxt.pCols) > 0) {
|
||||
*pCols = cxt.pCols;
|
||||
} else {
|
||||
nodesDestroyList(cxt.pCols);
|
||||
cxt.pCols = NULL;
|
||||
}
|
||||
*pCols = cxt.pCols;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1194,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
|||
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SCollectFuncsCxt cxt = {
|
||||
|
@ -1157,6 +1217,46 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNod
|
|||
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) {
|
||||
switch (mode) {
|
||||
case FILL_MODE_NONE:
|
||||
|
|
|
@ -30,9 +30,9 @@ typedef struct SAstCreateContext {
|
|||
SParseContext* pQueryCxt;
|
||||
SMsgBuf msgBuf;
|
||||
bool notSupport;
|
||||
bool valid;
|
||||
SNode* pRootNode;
|
||||
int16_t placeholderNo;
|
||||
int32_t errCode;
|
||||
} SAstCreateContext;
|
||||
|
||||
typedef enum EDatabaseOptionType {
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
}
|
||||
|
||||
%syntax_error {
|
||||
if (pCxt->valid) {
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
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 {
|
||||
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.
|
||||
|
||||
/************************************************ 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 ::= ALTER ACCOUNT NK_ID alter_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->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
|
||||
|
||||
%type account_options { int32_t }
|
||||
%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 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 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 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); }
|
||||
|
@ -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) ::= 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) ::= 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); }
|
||||
|
||||
%type literal_list { SNodeList* }
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define CHECK_OUT_OF_MEM(p) \
|
||||
do { \
|
||||
if (NULL == (p)) { \
|
||||
pCxt->valid = false; \
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "Out of memory"); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
@ -30,7 +30,7 @@
|
|||
#define CHECK_RAW_EXPR_NODE(node) \
|
||||
do { \
|
||||
if (NULL == (node) || QUERY_NODE_RAW_EXPR != nodeType(node)) { \
|
||||
pCxt->valid = false; \
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR; \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -42,9 +42,9 @@ void initAstCreateContext(SParseContext* pParseCxt, SAstCreateContext* pCxt) {
|
|||
pCxt->msgBuf.buf = pParseCxt->pMsg;
|
||||
pCxt->msgBuf.len = pParseCxt->msgLen;
|
||||
pCxt->notSupport = false;
|
||||
pCxt->valid = true;
|
||||
pCxt->pRootNode = NULL;
|
||||
pCxt->placeholderNo = 0;
|
||||
pCxt->errCode = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (NULL == pUserName) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
} else {
|
||||
if (pUserName->n >= TSDB_USER_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
}
|
||||
}
|
||||
if (pCxt->valid) {
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
trimEscape(pUserName);
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) {
|
||||
if (NULL == pPasswordToken) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
} else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
} else {
|
||||
strncpy(pPassword, pPasswordToken->z, pPasswordToken->n);
|
||||
strdequote(pPassword);
|
||||
if (strtrim(pPassword) <= 0) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY);
|
||||
}
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, char* pFqdn, int32_t* pPort) {
|
||||
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'
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
} else {
|
||||
char ep[TSDB_FQDN_LEN + 2 + 6];
|
||||
strncpy(ep, pEp->z, pEp->n);
|
||||
|
@ -106,66 +102,59 @@ static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, ch
|
|||
strtrim(ep);
|
||||
char* pColon = strchr(ep, ':');
|
||||
if (NULL == pColon) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT);
|
||||
} else {
|
||||
strncpy(pFqdn, ep, pColon - ep);
|
||||
*pPort = strtol(pColon + 1, NULL, 10);
|
||||
if (*pPort >= UINT16_MAX || *pPort <= 0) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkFqdn(SAstCreateContext* pCxt, const SToken* pFqdn) {
|
||||
if (NULL == pFqdn) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
} else {
|
||||
if (pFqdn->n >= TSDB_FQDN_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG);
|
||||
}
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkPort(SAstCreateContext* pCxt, const SToken* pPortToken, int32_t* pPort) {
|
||||
if (NULL == pPortToken) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
} else {
|
||||
*pPort = strtol(pPortToken->z, NULL, 10);
|
||||
if (*pPort >= UINT16_MAX || *pPort <= 0) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT);
|
||||
}
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkDbName(SAstCreateContext* pCxt, SToken* pDbName, bool query) {
|
||||
if (NULL == pDbName) {
|
||||
if (query && NULL == pCxt->pQueryCxt->db) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DB_NOT_SPECIFIED);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DB_NOT_SPECIFIED);
|
||||
}
|
||||
} else {
|
||||
trimEscape(pDbName);
|
||||
if (pDbName->n >= TSDB_DB_NAME_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pDbName->z);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pDbName->z);
|
||||
}
|
||||
}
|
||||
return pCxt->valid;
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode;
|
||||
}
|
||||
|
||||
static bool checkTableName(SAstCreateContext* pCxt, SToken* pTableName) {
|
||||
trimEscape(pTableName);
|
||||
if (NULL != pTableName && pTableName->n >= TSDB_TABLE_NAME_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pTableName->z);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pTableName->z);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -174,8 +163,7 @@ static bool checkTableName(SAstCreateContext* pCxt, SToken* pTableName) {
|
|||
static bool checkColumnName(SAstCreateContext* pCxt, SToken* pColumnName) {
|
||||
trimEscape(pColumnName);
|
||||
if (NULL != pColumnName && pColumnName->n >= TSDB_COL_NAME_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pColumnName->z);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pColumnName->z);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -184,8 +172,7 @@ static bool checkColumnName(SAstCreateContext* pCxt, SToken* pColumnName) {
|
|||
static bool checkIndexName(SAstCreateContext* pCxt, SToken* pIndexName) {
|
||||
trimEscape(pIndexName);
|
||||
if (NULL != pIndexName && pIndexName->n >= TSDB_INDEX_NAME_LEN) {
|
||||
generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pIndexName->z);
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, pIndexName->z);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -224,7 +211,7 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
|
|||
|
||||
SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
|
||||
if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
return nil_token;
|
||||
}
|
||||
SRawExprNode* target = (SRawExprNode*)pNode;
|
||||
|
@ -235,16 +222,12 @@ SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
|
|||
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode) {
|
||||
SNodeList* list = nodesMakeList();
|
||||
CHECK_OUT_OF_MEM(list);
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(list, pNode)) {
|
||||
pCxt->valid = false;
|
||||
}
|
||||
pCxt->errCode = nodesListAppend(list, pNode);
|
||||
return list;
|
||||
}
|
||||
|
||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode) {
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pList, pNode)) {
|
||||
pCxt->valid = false;
|
||||
}
|
||||
pCxt->errCode = nodesListAppend(pList, pNode);
|
||||
return pList;
|
||||
}
|
||||
|
||||
|
@ -381,10 +364,10 @@ SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType d
|
|||
strcpy(func->functionName, "cast");
|
||||
func->node.resType = dt;
|
||||
if (TSDB_DATA_TYPE_BINARY == dt.type) {
|
||||
func->node.resType.bytes += 2;
|
||||
func->node.resType.bytes += 2;
|
||||
} else if (TSDB_DATA_TYPE_NCHAR == dt.type) {
|
||||
func->node.resType.bytes = func->node.resType.bytes * TSDB_NCHAR_SIZE + 2;
|
||||
}
|
||||
}
|
||||
nodesListMakeAppend(&func->pParameterList, pExpr);
|
||||
return (SNode*)func;
|
||||
}
|
||||
|
@ -531,7 +514,7 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) {
|
|||
}
|
||||
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) {
|
||||
if (NULL == pNode || !pCxt->valid) {
|
||||
if (NULL == pNode || TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||
return pNode;
|
||||
}
|
||||
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) {
|
||||
if (needDbShowStmt(type) && NULL == pDbName && NULL == pCxt->pQueryCxt->db) {
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "db not specified");
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
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,
|
||||
const SToken* pLibPath, SDataType dataType, int32_t bufSize) {
|
||||
if (pLibPath->n <= 2) {
|
||||
pCxt->valid = false;
|
||||
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
SCreateFunctionStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_FUNCTION_STMT);
|
||||
|
|
|
@ -53,20 +53,20 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
|
|||
}
|
||||
case TK_NK_ILLEGAL: {
|
||||
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;
|
||||
}
|
||||
case TK_NK_HEX:
|
||||
case TK_NK_OCT:
|
||||
case TK_NK_BIN: {
|
||||
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;
|
||||
}
|
||||
default:
|
||||
Parse(pParser, t0.type, t0, &cxt);
|
||||
// ParseTrace(stdout, "");
|
||||
if (!cxt.valid) {
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
goto abort_parse;
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
|
|||
|
||||
abort_parse:
|
||||
ParseFree(pParser, (FFree)taosMemoryFree);
|
||||
if (cxt.valid) {
|
||||
if (TSDB_CODE_SUCCESS == cxt.errCode) {
|
||||
*pQuery = taosMemoryCalloc(1, sizeof(SQuery));
|
||||
if (NULL == *pQuery) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -82,5 +82,5 @@ abort_parse:
|
|||
(*pQuery)->pRoot = cxt.pRootNode;
|
||||
(*pQuery)->placeholderNum = cxt.placeholderNo;
|
||||
}
|
||||
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,23 @@ static int32_t calcConstProjections(SCalcConstContext* pCxt, SNodeList* pProject
|
|||
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) {
|
||||
int32_t code = calcConstProjections(pCxt, pSelect->pProjectionList, subquery);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
#include "functionMgt.h"
|
||||
#include "parUtil.h"
|
||||
#include "scalar.h"
|
||||
#include "systable.h"
|
||||
#include "tglobal.h"
|
||||
#include "ttime.h"
|
||||
#include "systable.h"
|
||||
|
||||
#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 {
|
||||
SParseContext* pParseCxt;
|
||||
|
@ -466,27 +466,66 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
|
||||
*(bool*)&pVal->typeData = pVal->datum.b;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_TINYINT:{
|
||||
char* endPtr = NULL;
|
||||
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: {
|
||||
char* endPtr = NULL;
|
||||
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;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
char* endPtr = NULL;
|
||||
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;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.d = strtold(pVal->literal, &endPtr);
|
||||
*(double*)&pVal->typeData = pVal->datum.d;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
|
@ -504,6 +543,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -1676,11 +1716,12 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions,
|
||||
bool alter) {
|
||||
static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
|
||||
int32_t daysPerFile = pOptions->daysPerFile;
|
||||
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;
|
||||
int32_t code = getDBCfg(pCxt, pDbName, &dbCfg);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
|
@ -1695,8 +1736,7 @@ static int32_t checkOptionsDependency(STranslateContext* pCxt, const char* pDbNa
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions,
|
||||
bool alter) {
|
||||
static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName, SDatabaseOptions* pOptions) {
|
||||
int32_t code =
|
||||
checkRangeOption(pCxt, "buffer", pOptions->buffer, TSDB_MIN_BUFFER_PER_VNODE, TSDB_MAX_BUFFER_PER_VNODE);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -1753,13 +1793,13 @@ static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName
|
|||
code = checkDbRetentionsOption(pCxt, pOptions->pRetentions);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkOptionsDependency(pCxt, pDbName, pOptions, alter);
|
||||
code = checkOptionsDependency(pCxt, pDbName, pOptions);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1826,7 +1866,7 @@ static void buildAlterDbReq(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) {
|
||||
return code;
|
||||
}
|
||||
|
@ -3136,11 +3176,11 @@ static int32_t rewriteShow(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
return code;
|
||||
}
|
||||
|
||||
typedef struct SVgroupTablesBatch {
|
||||
typedef struct SVgroupCreateTableBatch {
|
||||
SVCreateTbBatchReq req;
|
||||
SVgroupInfo info;
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
} SVgroupTablesBatch;
|
||||
} SVgroupCreateTableBatch;
|
||||
|
||||
static void destroyCreateTbReq(SVCreateTbReq* pReq) {
|
||||
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,
|
||||
SVgroupTablesBatch* pBatch) {
|
||||
SVgroupCreateTableBatch* pBatch) {
|
||||
char dbFName[TSDB_DB_FNAME_LEN] = {0};
|
||||
SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
|
||||
strcpy(name.dbname, pStmt->dbName);
|
||||
|
@ -3182,13 +3222,13 @@ static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t serializeVgroupTablesBatch(SVgroupTablesBatch* pTbBatch, SArray* pBufArray) {
|
||||
static int32_t serializeVgroupCreateTableBatch(SVgroupCreateTableBatch* pTbBatch, SArray* pBufArray) {
|
||||
int tlen;
|
||||
SCoder coder = {0};
|
||||
|
||||
int32_t ret = 0;
|
||||
tEncodeSize(tEncodeSVCreateTbBatchReq, &pTbBatch->req, tlen, ret);
|
||||
tlen += sizeof(SMsgHead); //+ tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
|
||||
tlen += sizeof(SMsgHead);
|
||||
void* buf = taosMemoryMalloc(tlen);
|
||||
if (NULL == buf) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -3214,7 +3254,7 @@ static int32_t serializeVgroupTablesBatch(SVgroupTablesBatch* pTbBatch, SArray*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) {
|
||||
static void destroyCreateTbReqBatch(SVgroupCreateTableBatch* pTbBatch) {
|
||||
size_t size = taosArrayGetSize(pTbBatch->req.pArray);
|
||||
for (int32_t i = 0; i < size; ++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;
|
||||
}
|
||||
|
||||
SVgroupTablesBatch tbatch = {0};
|
||||
int32_t code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch);
|
||||
SVgroupCreateTableBatch tbatch = {0};
|
||||
int32_t code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = serializeVgroupTablesBatch(&tbatch, *pBufArray);
|
||||
code = serializeVgroupCreateTableBatch(&tbatch, *pBufArray);
|
||||
}
|
||||
|
||||
destroyCreateTbReqBatch(&tbatch);
|
||||
|
@ -3307,9 +3347,9 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, c
|
|||
req.ctb.suid = suid;
|
||||
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) {
|
||||
SVgroupTablesBatch tBatch = {0};
|
||||
SVgroupCreateTableBatch tBatch = {0};
|
||||
tBatch.info = *pVgInfo;
|
||||
strcpy(tBatch.dbName, pDbName);
|
||||
|
||||
|
@ -3482,21 +3522,21 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla
|
|||
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*));
|
||||
if (NULL == pBufArray) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SVgroupTablesBatch* pTbBatch = NULL;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SVgroupCreateTableBatch* pTbBatch = NULL;
|
||||
do {
|
||||
pTbBatch = taosHashIterate(pVgroupHashmap, pTbBatch);
|
||||
if (pTbBatch == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
serializeVgroupTablesBatch(pTbBatch, pBufArray);
|
||||
serializeVgroupCreateTableBatch(pTbBatch, pBufArray);
|
||||
destroyCreateTbReqBatch(pTbBatch);
|
||||
} 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);
|
||||
if (NULL == pBufArray) {
|
||||
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:
|
||||
code = rewriteCreateMultiTable(pCxt, pQuery);
|
||||
break;
|
||||
case QUERY_NODE_DROP_TABLE_STMT:
|
||||
code = rewriteDropTable(pCxt, pQuery);
|
||||
break;
|
||||
case QUERY_NODE_ALTER_TABLE_STMT:
|
||||
if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == ((SAlterTableStmt*)pQuery->pRoot)->alterType) {
|
||||
code = rewriteAlterTable(pCxt, pQuery);
|
||||
|
|
|
@ -126,6 +126,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "slimit/soffset only available for PARTITION BY query";
|
||||
case TSDB_CODE_PAR_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:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
|
|
@ -3021,11 +3021,11 @@ static YYACTIONTYPE yy_reduce(
|
|||
/********** Begin reduce actions **********************************************/
|
||||
YYMINORTYPE yylhsminor;
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
case 2: /* account_options ::= */
|
||||
|
@ -3591,7 +3591,7 @@ static YYACTIONTYPE yy_reduce(
|
|||
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); }
|
||||
break;
|
||||
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;
|
||||
case 179: /* cmd ::= SHOW APPS */
|
||||
{ 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;
|
||||
break;
|
||||
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;
|
||||
case 291: /* expression ::= NK_LP expression NK_RP */
|
||||
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
|
||||
/************ Begin %syntax_error code ****************************************/
|
||||
|
||||
if (pCxt->valid) {
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
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 {
|
||||
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 ******************************************/
|
||||
ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
|
||||
|
|
|
@ -24,4 +24,9 @@ if(${BUILD_WINGETOPT})
|
|||
PUBLIC "${TD_SOURCE_DIR}/contrib/wingetopt/src"
|
||||
)
|
||||
target_link_libraries(parserTest PUBLIC wingetopt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME parserTest
|
||||
COMMAND parserTest
|
||||
)
|
||||
|
|
|
@ -155,16 +155,22 @@ int32_t __catalogGetDBVgInfo(SCatalog* pCtg, void* pRpc, const SEpSet* pMgmtEps,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t __catalogGetDBCfg(SCatalog* pCtg, void* pRpc, const SEpSet* pMgmtEps, const char* dbFName, SDbCfgInfo* pDbCfg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initMetaDataEnv() {
|
||||
mockCatalogService.reset(new MockCatalogService());
|
||||
|
||||
static Stub stub;
|
||||
stub.set(catalogGetHandle, __catalogGetHandle);
|
||||
stub.set(catalogGetTableMeta, __catalogGetTableMeta);
|
||||
stub.set(catalogGetSTableMeta, __catalogGetTableMeta);
|
||||
stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup);
|
||||
stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo);
|
||||
stub.set(catalogGetDBVgVersion, __catalogGetDBVgVersion);
|
||||
stub.set(catalogGetDBVgInfo, __catalogGetDBVgInfo);
|
||||
stub.set(catalogGetDBCfg, __catalogGetDBCfg);
|
||||
// {
|
||||
// AddrAny any("libcatalog.so");
|
||||
// std::map<std::string,void*> result;
|
||||
|
|
|
@ -111,9 +111,8 @@ class MockCatalogServiceImpl {
|
|||
}
|
||||
|
||||
int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const {
|
||||
char db[TSDB_DB_NAME_LEN] = {0};
|
||||
tNameGetDbName(pTableName, db);
|
||||
return copyTableVgroup(db, tNameGetTableName(pTableName), vgInfo);
|
||||
vgInfo->vgId = 1;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t catalogGetTableDistVgInfo(const SName* pTableName, SArray** vgList) const {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -111,6 +111,7 @@ class InsertTest : public Test {
|
|||
cxt_.pMsg = errMagBuf_;
|
||||
cxt_.msgLen = max_err_len;
|
||||
code_ = TSDB_CODE_SUCCESS;
|
||||
res_ = nullptr;
|
||||
}
|
||||
|
||||
SVnodeModifOpStmt* getVnodeModifStmt(SQuery* pQuery) { return (SVnodeModifOpStmt*)pQuery->pRoot; }
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -30,6 +30,8 @@
|
|||
#include "parTestUtil.h"
|
||||
#include "parToken.h"
|
||||
|
||||
namespace ParserTest {
|
||||
|
||||
class ParserEnv : public testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
|
@ -62,9 +64,11 @@ static void parseArg(int argc, char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace ParserTest
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
testing::AddGlobalTestEnvironment(new ParserEnv());
|
||||
testing::AddGlobalTestEnvironment(new ParserTest::ParserEnv());
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
parseArg(argc, argv);
|
||||
ParserTest::parseArg(argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
|
@ -23,17 +23,30 @@
|
|||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
#define DO_WITH_THROW(func, ...) \
|
||||
do { \
|
||||
int32_t code__ = func(__VA_ARGS__); \
|
||||
if (TSDB_CODE_SUCCESS != code__) { \
|
||||
throw runtime_error("sql:[" + stmtEnv_.sql_ + "] " #func " code:" + to_string(code__) + \
|
||||
", strerror:" + string(tstrerror(code__)) + ", msg:" + string(stmtEnv_.msgBuf_.data())); \
|
||||
} \
|
||||
namespace ParserTest {
|
||||
|
||||
#define DO_WITH_THROW(func, ...) \
|
||||
do { \
|
||||
int32_t code__ = func(__VA_ARGS__); \
|
||||
if (!checkResultCode(#func, code__)) { \
|
||||
if (TSDB_CODE_SUCCESS != code__) { \
|
||||
throw runtime_error("sql:[" + stmtEnv_.sql_ + "] " #func " code:" + to_string(code__) + \
|
||||
", 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);
|
||||
|
||||
bool g_isDump = false;
|
||||
|
||||
struct TerminateFlag : public exception {
|
||||
const char* what() const throw() { return "success and terminate"; }
|
||||
};
|
||||
|
||||
class ParserTestBaseImpl {
|
||||
public:
|
||||
void useDb(const string& acctId, const string& db) {
|
||||
|
@ -41,8 +54,8 @@ class ParserTestBaseImpl {
|
|||
caseEnv_.db_ = db;
|
||||
}
|
||||
|
||||
void run(const string& sql) {
|
||||
reset();
|
||||
void run(const string& sql, int32_t expect, ParserStage checkStage) {
|
||||
reset(expect, checkStage);
|
||||
try {
|
||||
SParseContext cxt = {0};
|
||||
setParseContext(sql, &cxt);
|
||||
|
@ -57,6 +70,9 @@ class ParserTestBaseImpl {
|
|||
if (g_isDump) {
|
||||
dump();
|
||||
}
|
||||
} catch (const TerminateFlag& e) {
|
||||
// success and terminate
|
||||
return;
|
||||
} catch (...) {
|
||||
dump();
|
||||
throw;
|
||||
|
@ -72,6 +88,8 @@ class ParserTestBaseImpl {
|
|||
struct stmtEnv {
|
||||
string sql_;
|
||||
array<char, 1024> msgBuf_;
|
||||
int32_t expect_;
|
||||
string checkFunc_;
|
||||
};
|
||||
|
||||
struct stmtRes {
|
||||
|
@ -80,9 +98,34 @@ class ParserTestBaseImpl {
|
|||
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_.msgBuf_.fill(0);
|
||||
stmtEnv_.expect_ = expect;
|
||||
stmtEnv_.checkFunc_ = stageFunc(checkStage);
|
||||
|
||||
res_.parsedAst_.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::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
|
||||
|
|
|
@ -18,15 +18,21 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "taoserror.h"
|
||||
|
||||
namespace ParserTest {
|
||||
|
||||
class ParserTestBaseImpl;
|
||||
|
||||
enum ParserStage { PARSER_STAGE_PARSE, PARSER_STAGE_TRANSLATE, PARSER_STAGE_CALC_CONST, PARSER_STAGE_ALL };
|
||||
|
||||
class ParserTestBase : public testing::Test {
|
||||
public:
|
||||
ParserTestBase();
|
||||
virtual ~ParserTestBase();
|
||||
|
||||
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:
|
||||
std::unique_ptr<ParserTestBaseImpl> impl_;
|
||||
|
@ -34,4 +40,6 @@ class ParserTestBase : public testing::Test {
|
|||
|
||||
extern bool g_isDump;
|
||||
|
||||
} // namespace ParserTest
|
||||
|
||||
#endif // PARSER_TEST_UTIL_H
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -748,10 +748,10 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
SLogicNode* pRoot = NULL;
|
||||
int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||
code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
|
||||
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
||||
|
@ -944,9 +944,16 @@ static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator*
|
|||
}
|
||||
|
||||
static int32_t getMsgType(ENodeType sqlType) {
|
||||
return (QUERY_NODE_CREATE_TABLE_STMT == sqlType || QUERY_NODE_CREATE_MULTI_TABLE_STMT == sqlType)
|
||||
? TDMT_VND_CREATE_TABLE
|
||||
: TDMT_VND_SUBMIT;
|
||||
switch (sqlType) {
|
||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||
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) {
|
||||
|
|
|
@ -206,6 +206,8 @@ static int32_t cpdMergeCond(SNode** pDst, SNode** pSrc) {
|
|||
if (NULL == pLogicCond) {
|
||||
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;
|
||||
int32_t code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -520,6 +522,7 @@ static int32_t cpdPushCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SN
|
|||
default:
|
||||
break;
|
||||
}
|
||||
planError("cpdPushCondToChild failed, invalid logic plan node %s", nodesNodeName(nodeType(pChild)));
|
||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,6 +272,7 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
|
|||
}
|
||||
// pIndex is definitely not NULL, otherwise it is a bug
|
||||
if (NULL == pIndex) {
|
||||
planError("doSetSlotId failed, invalid slot name %s", name);
|
||||
pCxt->errCode = TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
@ -435,12 +436,15 @@ static void vgroupInfoToNodeAddr(const SVgroupInfo* vg, SQueryNodeAddr* pNodeAdd
|
|||
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(
|
||||
pCxt, pScanLogicNode->pMeta->tableInfo.precision, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN);
|
||||
if (NULL == pTagScan) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
|
||||
taosArrayPush(pCxt->pExecNodeList, &pSubplan->execNode);
|
||||
return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pTagScan, pPhyNode);
|
||||
}
|
||||
|
||||
|
@ -514,7 +518,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
|
|||
SPhysiNode** pPhyNode) {
|
||||
switch (pScanLogicNode->scanType) {
|
||||
case SCAN_TYPE_TAG:
|
||||
return createTagScanPhysiNode(pCxt, pScanLogicNode, pPhyNode);
|
||||
return createTagScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode);
|
||||
case SCAN_TYPE_TABLE:
|
||||
return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode);
|
||||
case SCAN_TYPE_SYSTEM_TABLE:
|
||||
|
|
|
@ -104,8 +104,9 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
|
|||
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
|
||||
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.bytes = NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes;
|
||||
pVal->node.resType.bytes = inputSize;
|
||||
switch (pParam->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
pVal->datum.b = *((bool*)pParam->buffer);
|
||||
|
@ -130,7 +131,6 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
|
||||
if (NULL == pVal->datum.p) {
|
||||
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);
|
||||
strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes);
|
||||
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:
|
||||
pVal->datum.i = *((int64_t*)pParam->buffer);
|
||||
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 size = taosArrayGetSize(pPlan->pPlaceholderValues);
|
||||
|
||||
int32_t code = 0;
|
||||
|
||||
if (colIdx < 0) {
|
||||
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 {
|
||||
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)) {
|
||||
|
|
|
@ -30,4 +30,9 @@ if(${BUILD_WINGETOPT})
|
|||
PUBLIC "${TD_SOURCE_DIR}/contrib/wingetopt/src"
|
||||
)
|
||||
target_link_libraries(plannerTest PUBLIC wingetopt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME plannerTest
|
||||
COMMAND plannerTest
|
||||
)
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -13,25 +13,29 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#include "tsdb.h"
|
||||
#ifndef _TSDB_PLUGINS
|
||||
#include "planTestUtil.h"
|
||||
#include "planner.h"
|
||||
|
||||
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
|
||||
#endif
|
||||
run("select count(*), sum(c1) from t1 interval(10s) fill(value, 10, 20)");
|
||||
}
|
|
@ -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'");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -13,14 +13,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parTestUtil.h"
|
||||
#include "planTestUtil.h"
|
||||
#include "planner.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ParserAlterTest : public ParserTestBase {};
|
||||
class PlanSessionTest : public PlannerTestBase {};
|
||||
|
||||
TEST_F(ParserAlterTest, stmt) {
|
||||
TEST_F(PlanSessionTest, basic) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("create database db1");
|
||||
run("select count(*) from t1 session(ts, 10s)");
|
||||
}
|
|
@ -13,12 +13,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "vnd.h"
|
||||
// #include "vnodeInt.h"
|
||||
#include "planTestUtil.h"
|
||||
#include "planner.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)");
|
||||
}
|
|
@ -42,13 +42,13 @@ class PlanStmtTest : public PlannerTestBase {
|
|||
// todo
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
TAOS_MULTI_BIND* pBindParams_;
|
||||
int32_t paramNo_;
|
||||
int32_t paramNo_;
|
||||
};
|
||||
|
||||
TEST_F(PlanStmtTest, stmt) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT * FROM t1 where c1 = ?");
|
||||
run("select * from t1 where c1 = ?");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -13,19 +13,22 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TDB_TXN_H_
|
||||
#define _TDB_TXN_H_
|
||||
#include "planTestUtil.h"
|
||||
#include "planner.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
using namespace std;
|
||||
|
||||
int tdbTxnOpen(TXN *pTxn, int64_t txnid, void *(*xMalloc)(void *, size_t), void (*xFree)(void *, void *), void *xArg,
|
||||
int flags);
|
||||
int tdbTxnClose(TXN *pTxn);
|
||||
class PlanSysTableTest : public PlannerTestBase {};
|
||||
|
||||
#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");
|
||||
}
|
|
@ -106,6 +106,7 @@ class PlannerTestBaseImpl {
|
|||
res_.splitLogicPlan_.clear();
|
||||
res_.scaledLogicPlan_.clear();
|
||||
res_.physiPlan_.clear();
|
||||
res_.physiSubplans_.clear();
|
||||
}
|
||||
|
||||
void dump() {
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include "qworker.h"
|
||||
#include "tlockfree.h"
|
||||
#include "ttimer.h"
|
||||
#include "tref.h"
|
||||
|
||||
#define QW_DEFAULT_SCHEDULER_NUMBER 10000
|
||||
#define QW_DEFAULT_TASK_NUMBER 10000
|
||||
|
@ -85,6 +86,12 @@ typedef struct SQWMsg {
|
|||
SQWConnInfo connInfo;
|
||||
} SQWMsg;
|
||||
|
||||
typedef struct SQWHbParam {
|
||||
bool inUse;
|
||||
int32_t qwrId;
|
||||
int64_t refId;
|
||||
} SQWHbParam;
|
||||
|
||||
typedef struct SQWHbInfo {
|
||||
SSchedulerHbRsp rsp;
|
||||
SQWConnInfo connInfo;
|
||||
|
@ -137,7 +144,8 @@ typedef struct SQWSchStatus {
|
|||
} SQWSchStatus;
|
||||
|
||||
// Qnode/Vnode level task management
|
||||
typedef struct SQWorkerMgmt {
|
||||
typedef struct SQWorker {
|
||||
int64_t refId;
|
||||
SQWorkerCfg cfg;
|
||||
int8_t nodeType;
|
||||
int32_t nodeId;
|
||||
|
@ -148,9 +156,17 @@ typedef struct SQWorkerMgmt {
|
|||
SHashObj *schHash; // key: schedulerId, value: SQWSchStatus
|
||||
SHashObj *ctxHash; // key: queryId+taskId, value: SQWTaskCtx
|
||||
SMsgCb msgCb;
|
||||
} SQWorker;
|
||||
|
||||
typedef struct SQWorkerMgmt {
|
||||
SRWLatch lock;
|
||||
int32_t qwRef;
|
||||
int32_t qwNum;
|
||||
SQWHbParam param[1024];
|
||||
int32_t paramIdx;
|
||||
} 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_FPARAMS() mgmt, QW_IDS()
|
||||
|
||||
|
@ -209,13 +225,13 @@ typedef struct SQWorkerMgmt {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define QW_ELOG(param, ...) qError("QW:%p " param, mgmt, __VA_ARGS__)
|
||||
#define QW_DLOG(param, ...) qDebug("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_DUMP(param, ...) \
|
||||
#define QW_DUMP(_param, ...) \
|
||||
do { \
|
||||
if (gQWDebug.dumpEnable) { \
|
||||
qDebug("QW:%p " param, mgmt, __VA_ARGS__); \
|
||||
qDebug("QW:%p " _param, mgmt, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -282,6 +298,14 @@ typedef struct SQWorkerMgmt {
|
|||
} \
|
||||
} 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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,7 @@ int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
|||
int32_t qwProcessReady(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
int32_t qwProcessFetch(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 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);
|
||||
void qwFreeFetchRsp(void *msg);
|
||||
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 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
|
||||
}
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#include "tname.h"
|
||||
|
||||
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) {
|
||||
if (!gQWDebug.statusEnable) {
|
||||
|
@ -98,7 +103,7 @@ _return:
|
|||
|
||||
void qwDbgDumpSchInfo(SQWSchStatus *sch, int32_t i) {}
|
||||
|
||||
void qwDbgDumpMgmtInfo(SQWorkerMgmt *mgmt) {
|
||||
void qwDbgDumpMgmtInfo(SQWorker *mgmt) {
|
||||
if (!gQWDebug.dumpEnable) {
|
||||
return;
|
||||
}
|
||||
|
@ -186,7 +191,7 @@ int32_t qwSetTaskStatus(QW_FPARAMS_DEF, SQWTaskStatus *task, int8_t status) {
|
|||
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};
|
||||
newSch.tasksHash =
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
QW_LOCK(rwType, &mgmt->schLock);
|
||||
*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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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); }
|
||||
|
||||
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) {
|
||||
// Note: free/kill may in RC
|
||||
|
@ -606,7 +611,7 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryEnd) {
|
|||
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;
|
||||
|
||||
hbInfo->connInfo = sch->hbConnInfo;
|
||||
|
@ -1262,7 +1267,7 @@ _return:
|
|||
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;
|
||||
SSchedulerHbRsp rsp = {0};
|
||||
SQWSchStatus * sch = NULL;
|
||||
|
@ -1288,7 +1293,7 @@ int32_t qwProcessHbLinkBroken(SQWorkerMgmt *mgmt, SQWMsg *qwMsg, SSchedulerHbReq
|
|||
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;
|
||||
SSchedulerHbRsp rsp = {0};
|
||||
SQWSchStatus * sch = NULL;
|
||||
|
@ -1333,7 +1338,19 @@ _return:
|
|||
}
|
||||
|
||||
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;
|
||||
int32_t taskNum = 0;
|
||||
SQWHbInfo * rspList = NULL;
|
||||
|
@ -1347,6 +1364,7 @@ void qwProcessHbTimerEvent(void *param, void *tmrId) {
|
|||
if (schNum <= 0) {
|
||||
QW_UNLOCK(QW_READ, &mgmt->schLock);
|
||||
taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer);
|
||||
qwRelease(refId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1373,7 @@ void qwProcessHbTimerEvent(void *param, void *tmrId) {
|
|||
QW_UNLOCK(QW_READ, &mgmt->schLock);
|
||||
QW_ELOG("calloc %d SQWHbInfo failed", schNum);
|
||||
taosTmrReset(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, param, mgmt->timer, &mgmt->hbTimer);
|
||||
qwRelease(refId);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1396,6 +1415,74 @@ _return:
|
|||
taosMemoryFreeClear(rspList);
|
||||
|
||||
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) {
|
||||
|
@ -1404,10 +1491,21 @@ int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qW
|
|||
QW_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SQWorkerMgmt *mgmt = taosMemoryCalloc(1, sizeof(SQWorkerMgmt));
|
||||
int32_t qwNum = atomic_add_fetch_32(&gQwMgmt.qwNum, 1);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
mgmt->hbTimer = taosTmrStart(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, mgmt, mgmt->timer);
|
||||
if (NULL == mgmt->hbTimer) {
|
||||
qError("start hb timer failed");
|
||||
QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
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, ¶m);
|
||||
|
||||
mgmt->hbTimer = taosTmrStart(qwProcessHbTimerEvent, QW_DEFAULT_HEARTBEAT_MSEC, (void*)param, mgmt->timer);
|
||||
if (NULL == mgmt->hbTimer) {
|
||||
qError("start hb timer failed");
|
||||
QW_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
*qWorkerMgmt = 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:
|
||||
|
||||
taosHashCleanup(mgmt->schHash);
|
||||
taosHashCleanup(mgmt->ctxHash);
|
||||
|
||||
taosTmrCleanUp(mgmt->timer);
|
||||
|
||||
taosMemoryFreeClear(mgmt);
|
||||
if (mgmt->refId >= 0) {
|
||||
qwRelease(mgmt->refId);
|
||||
} else {
|
||||
taosHashCleanup(mgmt->schHash);
|
||||
taosHashCleanup(mgmt->ctxHash);
|
||||
taosTmrCleanUp(mgmt->timer);
|
||||
taosMemoryFreeClear(mgmt);
|
||||
|
||||
atomic_sub_fetch_32(&gQwMgmt.qwNum, 1);
|
||||
}
|
||||
|
||||
QW_RET(code);
|
||||
}
|
||||
|
||||
|
@ -1482,22 +1593,14 @@ void qWorkerDestroy(void **qWorkerMgmt) {
|
|||
return;
|
||||
}
|
||||
|
||||
SQWorkerMgmt *mgmt = *qWorkerMgmt;
|
||||
SQWorker *mgmt = *qWorkerMgmt;
|
||||
|
||||
taosTmrStopA(&mgmt->hbTimer);
|
||||
taosTmrCleanUp(mgmt->timer);
|
||||
|
||||
// TODO STOP ALL QUERY
|
||||
|
||||
// TODO FREE ALL
|
||||
|
||||
taosHashCleanup(mgmt->ctxHash);
|
||||
taosHashCleanup(mgmt->schHash);
|
||||
|
||||
taosMemoryFreeClear(*qWorkerMgmt);
|
||||
if (taosRemoveRef(gQwMgmt.qwRef, mgmt->refId)) {
|
||||
qError("remove qw from ref list failed, refId:%" PRIx64, mgmt->refId);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp) {
|
||||
int32_t qwGetSchTasksStatus(SQWorker *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp) {
|
||||
/*
|
||||
SQWSchStatus *sch = NULL;
|
||||
int32_t taskNum = 0;
|
||||
|
@ -1544,7 +1647,7 @@ int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRs
|
|||
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;
|
||||
|
||||
/*
|
||||
|
@ -1557,7 +1660,7 @@ int32_t qwUpdateSchLastAccess(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, ui
|
|||
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;
|
||||
SQWTaskStatus *task = NULL;
|
||||
int32_t code = 0;
|
||||
|
@ -1584,7 +1687,7 @@ int32_t qwGetTaskStatus(SQWorkerMgmt *mgmt, uint64_t sId, uint64_t qId, uint64_t
|
|||
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;
|
||||
SQWTaskStatus *task = NULL;
|
||||
int32_t code = 0;
|
||||
|
|
|
@ -320,7 +320,7 @@ int32_t qwRegisterQueryBrokenLinkArg(QW_FPARAMS_DEF, SQWConnInfo *pConn) {
|
|||
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};
|
||||
req.header.vgId = mgmt->nodeId;
|
||||
req.sId = sId;
|
||||
|
@ -363,7 +363,7 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
|||
|
||||
int32_t code = 0;
|
||||
SSubQueryMsg *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen <= sizeof(*msg)) {
|
||||
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;
|
||||
bool needStop = false;
|
||||
SQWTaskCtx *handles = NULL;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
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;
|
||||
}
|
||||
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
SResReadyReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
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);
|
||||
}
|
||||
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
msg->sId = htobe64(msg->sId);
|
||||
uint64_t sId = msg->sId;
|
||||
|
||||
|
@ -499,7 +499,7 @@ int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
SResFetchReq *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
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;
|
||||
}
|
||||
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
int32_t code = 0;
|
||||
STaskCancelReq *msg = pMsg->pCont;
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
|
@ -579,7 +579,7 @@ int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
|
|||
|
||||
int32_t code = 0;
|
||||
STaskDropReq *msg = pMsg->pCont;
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
if (NULL == msg || pMsg->contLen < sizeof(*msg)) {
|
||||
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;
|
||||
SSchedulerHbReq req = {0};
|
||||
SQWorkerMgmt *mgmt = (SQWorkerMgmt *)qWorkerMgmt;
|
||||
SQWorker *mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
if (NULL == pMsg->pCont) {
|
||||
QW_ELOG("invalid hb msg, msg:%p, msgLen:%d", pMsg->pCont, pMsg->contLen);
|
||||
|
|
|
@ -3765,6 +3765,7 @@ int32_t filterInitFromNode(SNode* pNode, SFilterInfo **pInfo, uint32_t options)
|
|||
FLT_ERR_JRET(fltReviseNodes(info, &pNode, &stat));
|
||||
|
||||
info->scalarMode = stat.scalarMode;
|
||||
fltDebug("scalar mode: %d", info->scalarMode);
|
||||
|
||||
if (!info->scalarMode) {
|
||||
FLT_ERR_JRET(fltInitFromNode(pNode, info, options));
|
||||
|
|
|
@ -75,7 +75,15 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
|||
|
||||
if (valueNode->node.resType.type != type) {
|
||||
out.columnData->info.type = type;
|
||||
out.columnData->info.bytes = tDataTypes[type].bytes;
|
||||
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;
|
||||
}
|
||||
|
||||
code = doConvertDataType(valueNode, &out);
|
||||
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);
|
||||
memcpy(res->datum.p, output.columnData->pData, varDataTLen(output.columnData->pData));
|
||||
} 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;
|
||||
output.columnData->pData = NULL;
|
||||
} else {
|
||||
memcpy(nodesGetValueFromNode(res), output.columnData->pData, tDataTypes[type].bytes);
|
||||
nodesSetValueNodeValue(res, output.columnData->pData);
|
||||
}
|
||||
|
||||
nodesDestroyNode(*pNode);
|
||||
|
@ -680,7 +688,7 @@ EDealRes sclRewriteOperator(SNode** pNode, SScalarCtx *ctx) {
|
|||
res->datum.p = output.columnData->pData;
|
||||
output.columnData->pData = NULL;
|
||||
} else {
|
||||
memcpy(nodesGetValueFromNode(res), output.columnData->pData, tDataTypes[type].bytes);
|
||||
nodesSetValueNodeValue(res, output.columnData->pData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,10 @@ typedef struct SSchedulerMgmt {
|
|||
uint64_t taskId; // sequential taksId
|
||||
uint64_t sId; // schedulerId
|
||||
SSchedulerCfg cfg;
|
||||
SRWLatch lock;
|
||||
bool exit;
|
||||
int32_t jobRef;
|
||||
int32_t jobNum;
|
||||
SSchedulerStat stat;
|
||||
SHashObj *hbConnections;
|
||||
} SSchedulerMgmt;
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
|
||||
SSchedulerMgmt schMgmt = {0};
|
||||
SSchedulerMgmt schMgmt = {
|
||||
.jobRef = -1,
|
||||
};
|
||||
|
||||
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,
|
||||
int64_t startTs, bool syncSchedule) {
|
||||
int32_t code = 0;
|
||||
int64_t refId = -1;
|
||||
SSchJob *pJob = taosMemoryCalloc(1, sizeof(SSchJob));
|
||||
if (NULL == pJob) {
|
||||
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);
|
||||
|
||||
int64_t refId = taosAddRef(schMgmt.jobRef, pJob);
|
||||
refId = taosAddRef(schMgmt.jobRef, pJob);
|
||||
if (refId < 0) {
|
||||
SCH_JOB_ELOG("taosAddRef job failed, error:%s", tstrerror(terrno));
|
||||
SCH_ERR_JRET(terrno);
|
||||
}
|
||||
|
||||
atomic_add_fetch_32(&schMgmt.jobNum, 1);
|
||||
|
||||
if (NULL == schAcquireJob(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;
|
||||
|
@ -137,7 +142,11 @@ int32_t schInitJob(SSchJob **pSchJob, SQueryPlan *pDag, void *transport, SArray
|
|||
|
||||
_return:
|
||||
|
||||
schFreeJobImpl(pJob);
|
||||
if (refId < 0) {
|
||||
schFreeJobImpl(pJob);
|
||||
} else {
|
||||
taosRemoveRef(schMgmt.jobRef, refId);
|
||||
}
|
||||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
@ -245,6 +254,7 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m
|
|||
SCH_SET_TASK_LASTMSG_TYPE(pTask, -1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
case TDMT_VND_CREATE_TABLE_RSP:
|
||||
case TDMT_VND_DROP_TABLE_RSP:
|
||||
case TDMT_VND_SUBMIT_RSP:
|
||||
break;
|
||||
default:
|
||||
|
@ -369,7 +379,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
|
|||
}
|
||||
|
||||
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);
|
||||
if (NULL == childTask || NULL == *childTask) {
|
||||
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) {
|
||||
SSubplan * parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n);
|
||||
SSubplan *parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n);
|
||||
SSchTask **parentTask = taosHashGet(planToTask, &parent, POINTER_BYTES);
|
||||
if (NULL == parentTask || NULL == *parentTask) {
|
||||
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};
|
||||
SNodeListNode *plans = NULL;
|
||||
int32_t taskNum = 0;
|
||||
SSchLevel * pLevel = NULL;
|
||||
SSchLevel *pLevel = NULL;
|
||||
|
||||
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));
|
||||
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: {
|
||||
if (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 code = 0;
|
||||
SSchTaskCallbackParam *pParam = (SSchTaskCallbackParam *)param;
|
||||
SSchTask * pTask = NULL;
|
||||
SSchTask *pTask = NULL;
|
||||
|
||||
SSchJob *pJob = schAcquireJob(pParam->refId);
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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:
|
||||
*fp = schHandleCreateTableCallback;
|
||||
break;
|
||||
case TDMT_VND_DROP_TABLE:
|
||||
*fp = schHandleDropTableCallback;
|
||||
break;
|
||||
case TDMT_VND_SUBMIT:
|
||||
*fp = schHandleSubmitCallback;
|
||||
break;
|
||||
|
@ -1617,8 +1658,8 @@ _return:
|
|||
int32_t schMakeHbRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) {
|
||||
int32_t code = 0;
|
||||
SSchHbCallbackParam *param = NULL;
|
||||
SMsgSendInfo * pMsgSendInfo = NULL;
|
||||
SQueryNodeAddr * addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
|
||||
SMsgSendInfo *pMsgSendInfo = NULL;
|
||||
SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
|
||||
SQueryNodeEpId epId = {0};
|
||||
|
||||
epId.nodeId = addr->nodeId;
|
||||
|
@ -1759,10 +1800,10 @@ int32_t schCloneHbRpcCtx(SRpcCtx *pSrc, SRpcCtx *pDst) {
|
|||
}
|
||||
|
||||
SRpcCtxVal dst = {0};
|
||||
void * pIter = taosHashIterate(pSrc->args, NULL);
|
||||
void *pIter = taosHashIterate(pSrc->args, NULL);
|
||||
while (pIter) {
|
||||
SRpcCtxVal *pVal = (SRpcCtxVal *)pIter;
|
||||
int32_t * msgType = taosHashGetKey(pIter, NULL);
|
||||
int32_t *msgType = taosHashGetKey(pIter, NULL);
|
||||
|
||||
dst = *pVal;
|
||||
dst.val = NULL;
|
||||
|
@ -1916,7 +1957,7 @@ _return:
|
|||
|
||||
int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType) {
|
||||
uint32_t msgSize = 0;
|
||||
void * msg = NULL;
|
||||
void *msg = NULL;
|
||||
int32_t code = 0;
|
||||
bool isCandidateAddr = false;
|
||||
bool persistHandle = false;
|
||||
|
@ -1931,6 +1972,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
|
|||
|
||||
switch (msgType) {
|
||||
case TDMT_VND_CREATE_TABLE:
|
||||
case TDMT_VND_DROP_TABLE:
|
||||
case TDMT_VND_SUBMIT: {
|
||||
msgSize = pTask->msgLen;
|
||||
msg = taosMemoryCalloc(1, msgSize);
|
||||
|
@ -2239,6 +2281,19 @@ int32_t schCancelJob(SSchJob *pJob) {
|
|||
// 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) {
|
||||
if (NULL == job) {
|
||||
return;
|
||||
|
@ -2284,6 +2339,10 @@ void schFreeJobImpl(void *job) {
|
|||
taosMemoryFreeClear(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,
|
||||
|
@ -2368,7 +2427,7 @@ _return:
|
|||
}
|
||||
|
||||
int32_t schedulerInit(SSchedulerCfg *cfg) {
|
||||
if (schMgmt.jobRef) {
|
||||
if (schMgmt.jobRef >= 0) {
|
||||
qError("scheduler already initialized");
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
@ -2673,7 +2732,7 @@ int32_t schedulerGetTasksStatus(int64_t job, SArray *pSub) {
|
|||
SSchLevel *pLevel = taosArrayGet(pJob->levels, i);
|
||||
|
||||
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};
|
||||
|
||||
taosArrayPush(pSub, &subDesc);
|
||||
|
@ -2732,7 +2791,9 @@ void schedulerFreeTaskList(SArray *taskList) {
|
|||
}
|
||||
|
||||
void schedulerDestroy(void) {
|
||||
if (schMgmt.jobRef) {
|
||||
atomic_store_8((int8_t*)&schMgmt.exit, 1);
|
||||
|
||||
if (schMgmt.jobRef >= 0) {
|
||||
SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0);
|
||||
int64_t refId = 0;
|
||||
|
||||
|
@ -2745,9 +2806,6 @@ void schedulerDestroy(void) {
|
|||
|
||||
pJob = taosIterateRef(schMgmt.jobRef, refId);
|
||||
}
|
||||
|
||||
taosCloseRef(schMgmt.jobRef);
|
||||
schMgmt.jobRef = 0;
|
||||
}
|
||||
|
||||
if (schMgmt.hbConnections) {
|
||||
|
|
|
@ -22,6 +22,65 @@
|
|||
extern "C" {
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -19,17 +19,17 @@
|
|||
#define TDB_BTREE_LEAF 0x2
|
||||
|
||||
struct SBTree {
|
||||
SPgno root;
|
||||
int keyLen;
|
||||
int valLen;
|
||||
SPager *pPager;
|
||||
FKeyComparator kcmpr;
|
||||
int pageSize;
|
||||
int maxLocal;
|
||||
int minLocal;
|
||||
int maxLeaf;
|
||||
int minLeaf;
|
||||
void *pBuf;
|
||||
SPgno root;
|
||||
int keyLen;
|
||||
int valLen;
|
||||
SPager *pPager;
|
||||
tdb_cmpr_fn_t kcmpr;
|
||||
int pageSize;
|
||||
int maxLocal;
|
||||
int minLocal;
|
||||
int maxLeaf;
|
||||
int minLeaf;
|
||||
void *pBuf;
|
||||
};
|
||||
|
||||
#define TDB_BTREE_PAGE_COMMON_HDR u8 flags;
|
||||
|
@ -58,16 +58,6 @@ typedef struct {
|
|||
SBTree *pBt;
|
||||
} 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 tdbBtreeOpenImpl(SBTree *pBt);
|
||||
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 tdbBtreeBalance(SBTC *pBtc);
|
||||
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell);
|
||||
static int tdbBtcMoveToNext(SBTC *pBtc);
|
||||
static int tdbBtcMoveDownward(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;
|
||||
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
|
||||
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) {
|
||||
tdbBtcClose(&btc);
|
||||
ASSERT(0);
|
||||
|
@ -243,7 +232,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
|
|||
tdbBtreeDecodeCell(btc.pPage, pCell, &cd);
|
||||
|
||||
if (ppKey) {
|
||||
pTKey = TDB_REALLOC(*ppKey, cd.kLen);
|
||||
pTKey = tdbRealloc(*ppKey, cd.kLen);
|
||||
if (pTKey == NULL) {
|
||||
tdbBtcClose(&btc);
|
||||
ASSERT(0);
|
||||
|
@ -255,7 +244,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
|
|||
}
|
||||
|
||||
if (ppVal) {
|
||||
pTVal = TDB_REALLOC(*ppVal, cd.vLen);
|
||||
pTVal = tdbRealloc(*ppVal, cd.vLen);
|
||||
if (pTVal == NULL) {
|
||||
tdbBtcClose(&btc);
|
||||
ASSERT(0);
|
||||
|
@ -1018,6 +1007,7 @@ int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn) {
|
|||
pBtc->iPage = -1;
|
||||
pBtc->pPage = NULL;
|
||||
pBtc->idx = -1;
|
||||
memset(&pBtc->coder, 0, sizeof(SCellDecoder));
|
||||
|
||||
if (pTxn == NULL) {
|
||||
pBtc->pTxn = &pBtc->txn;
|
||||
|
@ -1060,6 +1050,8 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
|
|||
return 0;
|
||||
}
|
||||
} else {
|
||||
ASSERT(0);
|
||||
#if 0
|
||||
// move from a position
|
||||
int iPage = 0;
|
||||
|
||||
|
@ -1077,6 +1069,7 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
|
|||
|
||||
tdbBtcMoveUpward(pBtc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// move downward
|
||||
|
@ -1125,6 +1118,8 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
|
|||
return 0;
|
||||
}
|
||||
} else {
|
||||
ASSERT(0);
|
||||
#if 0
|
||||
int iPage = 0;
|
||||
|
||||
// downward search
|
||||
|
@ -1147,6 +1142,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
|
|||
|
||||
tdbBtcMoveUpward(pBtc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// move downward
|
||||
|
@ -1185,7 +1181,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
|||
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd);
|
||||
|
||||
pKey = TDB_REALLOC(*ppKey, cd.kLen);
|
||||
pKey = tdbRealloc(*ppKey, cd.kLen);
|
||||
if (pKey == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1196,9 +1192,9 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
|||
|
||||
if (ppVal) {
|
||||
// TODO: vLen may be zero
|
||||
pVal = TDB_REALLOC(*ppVal, cd.vLen);
|
||||
pVal = tdbRealloc(*ppVal, cd.vLen);
|
||||
if (pVal == NULL) {
|
||||
TDB_FREE(pKey);
|
||||
tdbFree(pKey);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1216,7 +1212,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtcMoveToNext(SBTC *pBtc) {
|
||||
int tdbBtcMoveToNext(SBTC *pBtc) {
|
||||
int nCells;
|
||||
int ret;
|
||||
SCell *pCell;
|
||||
|
@ -1262,6 +1258,43 @@ static int tdbBtcMoveToNext(SBTC *pBtc) {
|
|||
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) {
|
||||
int ret;
|
||||
SPgno pgno;
|
||||
|
@ -1307,17 +1340,38 @@ static int tdbBtcMoveUpward(SBTC *pBtc) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
||||
int ret;
|
||||
int nCells;
|
||||
int c;
|
||||
SBTree *pBt;
|
||||
SCell *pCell;
|
||||
SPager *pPager;
|
||||
SCellDecoder cd = {0};
|
||||
int tdbBtcGet(SBTC *pBtc, const void **ppKey, int *kLen, const void **ppVal, int *vLen) {
|
||||
SCell *pCell;
|
||||
|
||||
pBt = pBtc->pBt;
|
||||
pPager = pBt->pPager;
|
||||
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 nCells;
|
||||
int c;
|
||||
SCell *pCell;
|
||||
SBTree *pBt = pBtc->pBt;
|
||||
SPager *pPager = pBt->pPager;
|
||||
const void *pTKey;
|
||||
int tkLen;
|
||||
|
||||
if (pBtc->iPage < 0) {
|
||||
// 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
|
||||
if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0) return 0;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
#if 0
|
||||
SPage *pPage;
|
||||
int idx;
|
||||
int iPage = 0;
|
||||
|
@ -1368,11 +1424,12 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
if (pBtc->iPage == iPage) break;
|
||||
tdbBtcMoveUpward(pBtc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// search downward to the leaf
|
||||
for (;;) {
|
||||
int lidx, ridx, midx;
|
||||
int lidx, ridx;
|
||||
SPage *pPage;
|
||||
|
||||
pPage = pBtc->pPage;
|
||||
|
@ -1381,13 +1438,11 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
ridx = nCells - 1;
|
||||
|
||||
ASSERT(nCells > 0);
|
||||
ASSERT(pBtc->idx == -1);
|
||||
|
||||
// compare first cell
|
||||
midx = lidx;
|
||||
pCell = tdbPageGetCell(pPage, midx);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd);
|
||||
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
|
||||
pBtc->idx = lidx;
|
||||
tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
|
||||
c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
|
||||
if (c <= 0) {
|
||||
ridx = lidx - 1;
|
||||
} else {
|
||||
|
@ -1396,10 +1451,9 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
|
||||
// compare last cell
|
||||
if (lidx <= ridx) {
|
||||
midx = ridx;
|
||||
pCell = tdbPageGetCell(pPage, midx);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd);
|
||||
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
|
||||
pBtc->idx = ridx;
|
||||
tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
|
||||
c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
|
||||
if (c >= 0) {
|
||||
lidx = ridx + 1;
|
||||
} else {
|
||||
|
@ -1411,24 +1465,15 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
for (;;) {
|
||||
if (lidx > ridx) break;
|
||||
|
||||
midx = (lidx + ridx) >> 1;
|
||||
|
||||
pCell = tdbPageGetCell(pPage, midx);
|
||||
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);
|
||||
pBtc->idx = (lidx + ridx) >> 1;
|
||||
tdbBtcGet(pBtc, &pTKey, &tkLen, NULL, NULL);
|
||||
c = pBt->kcmpr(pKey, kLen, pTKey, tkLen);
|
||||
if (c < 0) {
|
||||
// pKey < cd.pKey
|
||||
ridx = midx - 1;
|
||||
ridx = pBtc->idx - 1;
|
||||
} else if (c > 0) {
|
||||
// pKey > cd.pKey
|
||||
lidx = midx + 1;
|
||||
lidx = pBtc->idx + 1;
|
||||
} else {
|
||||
// pKey == cd.pKey
|
||||
break;
|
||||
|
@ -1437,14 +1482,11 @@ static int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
|
||||
// keep search downward or break
|
||||
if (TDB_BTREE_PAGE_IS_LEAF(pPage)) {
|
||||
pBtc->idx = midx;
|
||||
*pCRst = c;
|
||||
break;
|
||||
} else {
|
||||
if (c <= 0) {
|
||||
pBtc->idx = midx;
|
||||
} else {
|
||||
pBtc->idx = midx + 1;
|
||||
if (c > 0) {
|
||||
pBtc->idx += 1;
|
||||
}
|
||||
tdbBtcMoveDownward(pBtc);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ struct STDBC {
|
|||
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;
|
||||
SPager *pPager;
|
||||
int ret;
|
||||
|
@ -75,7 +75,7 @@ int tdbDbDrop(TDB *pDb) {
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
int tdbDbcOpen(TDB *pDb, TDBC **ppDbc) {
|
||||
int tdbDbcOpen(TDB *pDb, TDBC **ppDbc, TXN *pTxn) {
|
||||
int ret;
|
||||
TDBC *pDbc = NULL;
|
||||
|
||||
|
@ -97,34 +97,53 @@ int tdbDbcOpen(TDB *pDb, TDBC **ppDbc) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
tdbBtcOpen(&pDbc->btc, pDb->pBt, NULL);
|
||||
|
||||
// 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;
|
||||
}
|
||||
tdbBtcOpen(&pDbc->btc, pDb->pBt, pTxn);
|
||||
|
||||
*ppDbc = pDbc;
|
||||
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);
|
||||
}
|
||||
|
||||
int tdbDbcClose(TDBC *pDbc) {
|
||||
if (pDbc) {
|
||||
tdbBtcClose(&pDbc->btc);
|
||||
tdbOsFree(pDbc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tdbDbcInsert(TDBC *pDbc, const void *pKey, int keyLen, const void *pVal, int valLen) {
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#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;
|
||||
int dsize;
|
||||
int zsize;
|
||||
|
@ -49,14 +49,14 @@ int tdbEnvOpen(const char *rootDir, int pageSize, int cacheSize, TENV **ppEnv) {
|
|||
|
||||
pEnv->jfd = -1;
|
||||
|
||||
ret = tdbPCacheOpen(pageSize, cacheSize, &(pEnv->pCache));
|
||||
ret = tdbPCacheOpen(szPage, pages, &(pEnv->pCache));
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pEnv->nPgrHash = 8;
|
||||
tsize = sizeof(SPager *) * pEnv->nPgrHash;
|
||||
pEnv->pgrHash = TDB_REALLOC(pEnv->pgrHash, tsize);
|
||||
pEnv->pgrHash = tdbRealloc(pEnv->pgrHash, tsize);
|
||||
if (pEnv->pgrHash == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -103,11 +103,6 @@ int tdbCommit(TENV *pEnv, TXN *pTxn) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdbRollback(TENV *pEnv, TXN *pTxn) {
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SPager *tdbEnvGetPager(TENV *pEnv, const char *fname) {
|
||||
u32 hash;
|
||||
SPager **ppPager;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tdbInt.h"
|
||||
#include "tdbOs.h"
|
||||
|
||||
#ifndef TDB_FOR_TDENGINE
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue